JEditorPaneHTMLEditorKitParserInsert插入操作

wen java案例 2

本文目录导读:

JEditorPaneHTMLEditorKitParserInsert插入操作

  1. 核心组件关系
  2. 插入操作的实现方式
  3. HTML解析器在插入过程中的作用
  4. 完整的插入操作示例
  5. 重要注意事项

我来详细解释一下JEditorPane、HTMLEditorKit和HTML解析器在插入操作中的关系和工作原理。

核心组件关系

JEditorPane editorPane = new JEditorPane();
HTMLEditorKit kit = new HTMLEditorKit();
editorPane.setEditorKit(kit);
editorPane.setContentType("text/html");

插入操作的实现方式

基本插入方法

// 方法1:使用replaceSelection
editorPane.replaceSelection("要插入的文本");
// 方法2:使用Document的insertString
HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
try {
    doc.insertString(caretPosition, "插入内容", null);
} catch (BadLocationException e) {
    e.printStackTrace();
}

插入HTML元素

// 插入HTML片段
HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
HTMLEditorKit kit = (HTMLEditorKit) editorPane.getEditorKit();
try {
    // 获取当前位置
    int pos = editorPane.getCaretPosition();
    // 创建HTML片段
    String htmlContent = "<b>粗体文本</b><br>";
    // 方法1:直接插入HTML
    kit.insertHTML(doc, pos, htmlContent, 0, 0, null);
} catch (BadLocationException | IOException e) {
    e.printStackTrace();
}

高级插入操作

public class HTMLInsertExample {
    public static void insertStyledText(JEditorPane editor, String text, 
                                      String tagName, Map<String, String> attributes) {
        HTMLDocument doc = (HTMLDocument) editor.getDocument();
        HTMLEditorKit kit = (HTMLEditorKit) editor.getEditorKit();
        try {
            int pos = editor.getCaretPosition();
            StringBuilder htmlBuilder = new StringBuilder();
            // 构建HTML标签
            htmlBuilder.append("<").append(tagName);
            if (attributes != null) {
                for (Map.Entry<String, String> entry : attributes.entrySet()) {
                    htmlBuilder.append(" ").append(entry.getKey())
                              .append("=\"").append(entry.getValue()).append("\"");
                }
            }
            htmlBuilder.append(">").append(text)
                      .append("</").append(tagName).append(">");
            // 插入HTML
            kit.insertHTML(doc, pos, htmlBuilder.toString(), 0, 0, 
                          HTML.Tag.valueOf(tagName.toUpperCase()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 使用示例
    public static void main(String[] args) {
        JEditorPane editorPane = new JEditorPane();
        editorPane.setContentType("text/html");
        // 插入段落
        Map<String, String> attrs = new HashMap<>();
        attrs.put("style", "color: blue; font-size: 14px;");
        insertStyledText(editorPane, "蓝色文本示例", "p", attrs);
        // 插入链接
        Map<String, String> linkAttrs = new HashMap<>();
        linkAttrs.put("href", "https://example.com");
        linkAttrs.put("target", "_blank");
        insertStyledText(editorPane, "点击访问", "a", linkAttrs);
    }
}

HTML解析器在插入过程中的作用

解析工作流程

// 自定义HTML解析器
public class CustomHTMLParser extends HTMLEditorKit.Parser {
    @Override
    public void parse(Reader r, ParserCallback cb, boolean ignoreCharSet) 
            throws IOException {
        // 自定义解析逻辑
        // 1. 读取HTML内容
        // 2. 解析标签和属性
        // 3. 调用回调方法
        // 4. 生成文档结构
    }
}
// 使用自定义解析器
HTMLEditorKit kit = new HTMLEditorKit() {
    @Override
    public ViewFactory getViewFactory() {
        return super.getViewFactory();
    }
    @Override
    public Parser getParser() {
        return new CustomHTMLParser();
    }
};

解析回调机制

// ParserCallback用于处理解析事件
HTMLEditorKit.ParserCallback callback = new HTMLEditorKit.ParserCallback() {
    @Override
    public void handleText(char[] data, int pos) {
        // 处理文本内容
        System.out.println("文本: " + new String(data));
    }
    @Override
    public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
        // 处理开始标签
        System.out.println("开始标签: " + t.toString());
    }
    @Override
    public void handleEndTag(HTML.Tag t, int pos) {
        // 处理结束标签
        System.out.println("结束标签: " + t.toString());
    }
    @Override
    public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
        // 处理自闭合标签(如 <br>, <img>)
        System.out.println("自闭合标签: " + t.toString());
    }
    @Override
    public void handleComment(char[] data, int pos) {
        // 处理注释
        System.out.println("注释: " + new String(data));
    }
};

完整的插入操作示例

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import java.io.*;
public class HTMLInsertDemo extends JFrame {
    private JEditorPane editorPane;
    private JTextField textField;
    private JComboBox<String> tagSelector;
    public HTMLInsertDemo() {
        setTitle("HTML插入操作示例");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 创建编辑器
        editorPane = new JEditorPane();
        editorPane.setContentType("text/html");
        editorPane.setEditable(true);
        // 设置初始内容
        editorPane.setText("<html><body><p>初始内容</p></body></html>");
        // 创建控制面板
        JPanel controlPanel = new JPanel();
        textField = new JTextField(20);
        textField.setText("插入的文本");
        String[] tags = {"p", "b", "i", "u", "h1", "h2", "a"};
        tagSelector = new JComboBox<>(tags);
        JButton insertButton = new JButton("插入");
        insertButton.addActionListener(e -> insertHTML());
        JButton insertAtCursorButton = new JButton("在光标处插入");
        insertAtCursorButton.addActionListener(e -> insertAtCaret());
        controlPanel.add(new JLabel("标签:"));
        controlPanel.add(tagSelector);
        controlPanel.add(new JLabel("文本:"));
        controlPanel.add(textField);
        controlPanel.add(insertButton);
        controlPanel.add(insertAtCursorButton);
        // 布局
        setLayout(new BorderLayout());
        add(new JScrollPane(editorPane), BorderLayout.CENTER);
        add(controlPanel, BorderLayout.SOUTH);
    }
    private void insertHTML() {
        HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
        HTMLEditorKit kit = (HTMLEditorKit) editorPane.getEditorKit();
        try {
            String tag = (String) tagSelector.getSelectedItem();
            String text = textField.getText();
            // 构建HTML
            String html = "<" + tag + ">" + text + "</" + tag + ">";
            // 在文档末尾插入(示例)
            kit.insertHTML(doc, doc.getLength(), html, 0, 0, 
                          HTML.Tag.valueOf(tag.toUpperCase()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    private void insertAtCaret() {
        HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
        HTMLEditorKit kit = (HTMLEditorKit) editorPane.getEditorKit();
        try {
            String tag = (String) tagSelector.getSelectedItem();
            String text = textField.getText();
            int caretPos = editorPane.getCaretPosition();
            // 在光标位置插入
            String html = "<" + tag + ">" + text + "</" + tag + ">";
            kit.insertHTML(doc, caretPos, html, 0, 0, 
                          HTML.Tag.valueOf(tag.toUpperCase()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new HTMLInsertDemo().setVisible(true);
        });
    }
}

重要注意事项

解析限制

// JEditorPane的HTML解析器是Swing自带的简单解析器
// 不支持完整的HTML规范
// 不支持CSS样式表
// 不支持JavaScript

性能优化

// 批量插入时使用DocumentListener
doc.addDocumentListener(new DocumentListener() {
    @Override
    public void insertUpdate(DocumentEvent e) {
        // 插入更新后的处理
    }
    @Override
    public void removeUpdate(DocumentEvent e) {
        // 删除更新后的处理
    }
    @Override
    public void changedUpdate(DocumentEvent e) {
        // 属性更改后的处理
    }
});

线程安全

// 所有文档操作应在事件调度线程中执行
SwingUtilities.invokeLater(() -> {
    // 执行插入操作
});

这个实现展示了JEditorPane如何使用HTMLEditorKit和HTML解析器来处理插入操作,包括基本的文本插入、HTML元素插入以及自定义解析器的使用。

抱歉,评论功能暂时关闭!