本文目录导读:

我来详细介绍 JEditorPane、HTMLEditorKit 和 HTML parser/writer 的处理机制。
基本架构
// 核心组件关系
JEditorPane (显示组件)
→ HTMLEditorKit (编辑器工具包)
→ Parser (HTML解析器)
→ Writer (HTML写入器)
HTMLEditorKit 使用示例
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
import java.io.*;
public class HTMLEditorExample {
// 设置HTMLEditorKit
public static void setupHTMLEditor(JEditorPane editorPane) {
HTMLEditorKit kit = new HTMLEditorKit();
editorPane.setEditorKit(kit);
// 设置文档
HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
editorPane.setDocument(doc);
}
// 读取HTML
public static void readHTML(JEditorPane editor, String htmlContent) {
try {
HTMLEditorKit kit = (HTMLEditorKit) editor.getEditorKit();
HTMLDocument doc = (HTMLDocument) editor.getDocument();
// 使用StringReader读取
StringReader reader = new StringReader(htmlContent);
kit.read(reader, doc, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
// 写入HTML
public static String writeHTML(JEditorPane editor) {
try {
HTMLEditorKit kit = (HTMLEditorKit) editor.getEditorKit();
HTMLDocument doc = (HTMLDocument) editor.getDocument();
StringWriter writer = new StringWriter();
kit.write(writer, doc, 0, doc.getLength());
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
自定义HTML解析器
import javax.swing.text.html.parser.*;
import javax.swing.text.html.*;
public class CustomHTMLParser {
// 创建自定义解析器
public static HTMLEditorKit.Parser createCustomParser() {
return new ParserDelegator() {
@Override
public void parse(Reader r, HTMLEditorKit.ParserCallback cb, boolean ignoreCharSet)
throws IOException {
// 自定义解析逻辑
super.parse(r, cb, ignoreCharSet);
}
};
}
// 自定义回调处理器
public static class CustomCallback extends HTMLEditorKit.ParserCallback {
@Override
public void handleText(char[] data, int pos) {
String text = new String(data);
System.out.println("处理文本: " + text + " 位置: " + pos);
}
@Override
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
System.out.println("开始标签: " + t + " 位置: " + pos);
// 处理属性
if (a != null) {
Enumeration<?> names = a.getAttributeNames();
while (names.hasMoreElements()) {
Object name = names.nextElement();
System.out.println(" 属性: " + name + " = " + a.getAttribute(name));
}
}
}
@Override
public void handleEndTag(HTML.Tag t, int pos) {
System.out.println("结束标签: " + t + " 位置: " + pos);
}
@Override
public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
System.out.println("简单标签: " + t + " 位置: " + pos);
}
@Override
public void handleComment(char[] data, int pos) {
System.out.println("注释: " + new String(data) + " 位置: " + pos);
}
@Override
public void handleError(String errorMsg, int pos) {
System.err.println("解析错误: " + errorMsg + " 位置: " + pos);
}
}
}
HTML写入器处理
import javax.swing.text.*;
import javax.swing.text.html.*;
import java.io.*;
public class HTMLWriterCustomizer {
// 自定义HTML写入器
public static class CustomHTMLWriter extends HTMLWriter {
public CustomHTMLWriter(Writer w, HTMLDocument doc, int pos, int len) {
super(w, doc, pos, len);
}
@Override
protected void write(BigDecimal d) throws IOException {
// 自定义数字输出格式
super.write(d);
}
@Override
protected void writeContent(Element elem, boolean needsIndenting)
throws IOException, BadLocationException {
// 自定义内容输出
super.writeContent(elem, needsIndenting);
}
}
// 获取格式化的HTML
public static String getFormattedHTML(JEditorPane editor) {
try {
HTMLEditorKit kit = (HTMLEditorKit) editor.getEditorKit();
HTMLDocument doc = (HTMLDocument) editor.getDocument();
// 使用自定义写入器
StringWriter writer = new StringWriter();
CustomHTMLWriter htmlWriter = new CustomHTMLWriter(writer, doc, 0, doc.getLength());
htmlWriter.write();
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
完整示例:编辑器应用
import javax.swing.*;
import javax.swing.text.html.*;
import java.awt.*;
public class HTMLEditorApp extends JFrame {
private JEditorPane editorPane;
private HTMLEditorKit editorKit;
public HTMLEditorApp() {
setupUI();
setupEditor();
}
private void setupUI() {
setTitle("HTML编辑器");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 创建编辑器面板
editorPane = new JEditorPane();
JScrollPane scrollPane = new JScrollPane(editorPane);
add(scrollPane, BorderLayout.CENTER);
// 创建工具栏
JToolBar toolbar = new JToolBar();
toolbar.add(new JButton("打开HTML"));
toolbar.add(new JButton("保存HTML"));
toolbar.add(new JButton("预览"));
add(toolbar, BorderLayout.NORTH);
}
private void setupEditor() {
// 设置HTMLEditorKit
editorKit = new HTMLEditorKit();
editorPane.setEditorKit(editorKit);
// 创建HTML文档
HTMLDocument doc = (HTMLDocument) editorKit.createDefaultDocument();
editorPane.setDocument(doc);
// 设置初始内容
String initialHTML = "<html><body><h1>Hello, World!</h1></body></html>";
readHTMLContent(initialHTML);
}
public void readHTMLContent(String html) {
try {
StringReader reader = new StringReader(html);
editorKit.read(reader, editorPane.getDocument(), 0);
} catch (Exception e) {
e.printStackTrace();
}
}
public String writeHTMLContent() {
try {
StringWriter writer = new StringWriter();
editorKit.write(writer, editorPane.getDocument(),
0, editorPane.getDocument().getLength());
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new HTMLEditorApp().setVisible(true);
});
}
}
高级用法:自定义标签处理
import javax.swing.text.html.*;
import javax.swing.text.*;
import java.util.*;
public class CustomTagHandler {
// 自定义标签处理器
public static class MyHTMLDocument extends HTMLDocument {
public MyHTMLDocument() {
super();
}
@Override
public void setInnerHTML(Element elem, String htmlText) throws IOException, BadLocationException {
// 自定义内部HTML设置
super.setInnerHTML(elem, htmlText);
}
@Override
public void setOuterHTML(Element elem, String htmlText) throws IOException, BadLocationException {
// 自定义外部HTML设置
super.setOuterHTML(elem, htmlText);
}
}
// 自定义属性处理
public static class CustomAttributeSet extends SimpleAttributeSet {
public CustomAttributeSet() {
super();
}
public void addCustomAttribute(Object name, Object value) {
addAttribute(name, value);
}
public Map<Object, Object> getAllAttributes() {
Map<Object, Object> attrs = new HashMap<>();
Enumeration<?> names = getAttributeNames();
while (names.hasMoreElements()) {
Object name = names.nextElement();
attrs.put(name, getAttribute(name));
}
return attrs;
}
}
}
注意事项
- 性能优化:处理大量HTML时,考虑使用流式处理
- 编码处理:注意字符编码设置,避免乱码
- 线程安全:Swing组件操作需要在EDT线程中进行
- 内存管理:大型文档注意内存使用,考虑分页或懒加载
- 错误处理:解析错误时提供友好的错误信息
这个架构提供了完整的HTML编辑功能,可以根据需求进行扩展和定制。