JEditorPaneHTMLEditorKitParserHandler处理器

wen java案例 1

本文目录导读:

JEditorPaneHTMLEditorKitParserHandler处理器

  1. 核心组件关系
  2. 详细说明
  3. 自定义 Parser Handler 高级示例

我来详细解释 JEditorPane、HTMLEditorKit、Parser 和 Handler 这几个核心组件及其关系。

这是 Java Swing 中用于显示和编辑 HTML 内容的组件体系,它们共同构成了一个完整的内容处理管道。

核心组件关系

graph TB
    A[JEditorPane] --> B[HTMLEditorKit]
    B --> C[ViewFactory]
    B --> D[Parser]
    D --> E[ParserCallback/Handler]
    E --> F[Document]
    F --> G[Views]

详细说明

JEditorPane

// 基础用法
JEditorPane editorPane = new JEditorPane();
editorPane.setContentType("text/html");  // 设置内容类型
editorPane.setText("<html><body><h1>Hello World</h1></body></html>");
// 设置编辑器
editorPane.setEditorKit(new HTMLEditorKit());

HTMLEditorKit

public class CustomHTMLEditorKit extends HTMLEditorKit {
    @Override
    public Document createDefaultDocument() {
        HTMLDocument doc = (HTMLDocument) super.createDefaultDocument();
        // 自定义文档设置
        return doc;
    }
    @Override
    public ViewFactory getViewFactory() {
        return new HTMLFactory() {
            @Override
            public View create(Element elem) {
                // 自定义视图创建
                return super.create(elem);
            }
        };
    }
}

Parser 和 Handler

基础 Parser 使用

public class CustomHTMLParser {
    public static void main(String[] args) throws Exception {
        String html = "<html><body><p>Hello <b>World</b></p></body></html>";
        // 创建解析器
        ParserDelegator parser = new ParserDelegator();
        // 创建回调处理器
        HTMLEditorKit.ParserCallback callback = new HTMLEditorKit.ParserCallback() {
            @Override
            public void handleText(char[] data, int pos) {
                System.out.println("Text: " + new String(data) + " at position " + pos);
            }
            @Override
            public void handleStartTag(HTML.Tag t, 
                                      MutableAttributeSet a, 
                                      int pos) {
                System.out.println("Start tag: " + t + " at " + pos);
            }
            @Override
            public void handleEndTag(HTML.Tag t, int pos) {
                System.out.println("End tag: " + t + " at " + pos);
            }
            @Override
            public void handleSimpleTag(HTML.Tag t, 
                                       MutableAttributeSet a, 
                                       int pos) {
                System.out.println("Simple tag: " + t + " at " + pos);
            }
            @Override
            public void handleComment(char[] data, int pos) {
                System.out.println("Comment: " + new String(data));
            }
            @Override
            public void handleEndOfLineString(String eol) {
                // 处理行结束
            }
        };
        // 执行解析
        Reader reader = new StringReader(html);
        parser.parse(reader, callback, true);
    }
}

自定义 Document 解析器

public class CustomDocumentParser {
    public static class CustomParserCallback extends HTMLEditorKit.ParserCallback {
        private StringBuilder sb = new StringBuilder();
        private int depth = 0;
        @Override
        public void handleStartTag(HTML.Tag t, 
                                  MutableAttributeSet a, 
                                  int pos) {
            // 缩进显示
            String indent = "  ".repeat(depth);
            sb.append(indent).append("<").append(t);
            // 处理属性
            Enumeration<?> names = a.getAttributeNames();
            while (names.hasMoreElements()) {
                Object name = names.nextElement();
                sb.append(" ").append(name).append("='")
                  .append(a.getAttribute(name)).append("'");
            }
            sb.append(">\n");
            depth++;
        }
        @Override
        public void handleEndTag(HTML.Tag t, int pos) {
            depth--;
            String indent = "  ".repeat(depth);
            sb.append(indent).append("</").append(t).append(">\n");
        }
        @Override
        public void handleText(char[] data, int pos) {
            String indent = "  ".repeat(depth);
            sb.append(indent).append(new String(data)).append("\n");
        }
        public String getResult() {
            return sb.toString();
        }
    }
    public static void main(String[] args) throws Exception {
        String html = "<html><body><div class='content'><p>Hello <b>World</b></p></div></body></html>";
        ParserDelegator parser = new ParserDelegator();
        CustomParserCallback callback = new CustomParserCallback();
        parser.parse(new StringReader(html), callback, true);
        System.out.println("Parsed HTML structure:");
        System.out.println(callback.getResult());
    }
}

完整的 HTML 编辑器示例

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import java.awt.*;
public class CompleteHTMLEditorExample {
    private JFrame frame;
    private JEditorPane editorPane;
    private HTMLDocument document;
    public void createAndShowGUI() {
        frame = new JFrame("HTML Editor Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        // 创建编辑器
        editorPane = new JEditorPane();
        editorPane.setContentType("text/html");
        editorPane.setEditable(true);
        // 设置自定义编辑器
        HTMLEditorKit kit = new HTMLEditorKit();
        editorPane.setEditorKit(kit);
        // 创建文档
        document = (HTMLDocument) kit.createDefaultDocument();
        editorPane.setDocument(document);
        // 设置初始内容
        String initialContent = "<html><body>" +
            "<h1>HTML Editor</h1>" +
            "<p>This is a <b>demo</b> of HTML editing.</p>" +
            "<ul><li>Item 1</li><li>Item 2</li></ul>" +
            "</body></html>";
        editorPane.setText(initialContent);
        // 添加滚动面板
        JScrollPane scrollPane = new JScrollPane(editorPane);
        frame.add(scrollPane, BorderLayout.CENTER);
        // 添加工具栏
        JToolBar toolbar = createToolBar();
        frame.add(toolbar, BorderLayout.NORTH);
        // 添加解析信息显示
        JTextArea parseInfo = new JTextArea(10, 40);
        parseInfo.setEditable(false);
        frame.add(new JScrollPane(parseInfo), BorderLayout.SOUTH);
        // 解析并显示结构
        parseAndDisplayStructure();
        frame.setVisible(true);
    }
    private JToolBar createToolBar() {
        JToolBar toolbar = new JToolBar();
        JButton boldBtn = new JButton("Bold");
        boldBtn.addActionListener(e -> toggleBold());
        toolbar.add(boldBtn);
        JButton italicBtn = new JButton("Italic");
        italicBtn.addActionListener(e -> toggleItalic());
        toolbar.add(italicBtn);
        JButton underlineBtn = new JButton("Underline");
        underlineBtn.addActionListener(e -> toggleUnderline());
        toolbar.add(underlineBtn);
        toolbar.addSeparator();
        JButton parseBtn = new JButton("Parse Structure");
        parseBtn.addActionListener(e -> parseAndDisplayStructure());
        toolbar.add(parseBtn);
        return toolbar;
    }
    private void toggleBold() {
        // 实现粗体切换
        Action action = new StyledEditorKit.BoldAction();
        action.actionPerformed(new java.awt.event.ActionEvent(
            editorPane, 
            java.awt.event.ActionEvent.ACTION_PERFORMED, 
            ""
        ));
    }
    private void toggleItalic() {
        Action action = new StyledEditorKit.ItalicAction();
        action.actionPerformed(new java.awt.event.ActionEvent(
            editorPane, 
            java.awt.event.ActionEvent.ACTION_PERFORMED, 
            ""
        ));
    }
    private void toggleUnderline() {
        Action action = new StyledEditorKit.UnderlineAction();
        action.actionPerformed(new java.awt.event.ActionEvent(
            editorPane, 
            java.awt.event.ActionEvent.ACTION_PERFORMED, 
            ""
        ));
    }
    private void parseAndDisplayStructure() {
        try {
            String html = editorPane.getText();
            ParserDelegator parser = new ParserDelegator();
            StringBuilder structure = new StringBuilder();
            structure.append("HTML Structure:\n");
            structure.append("===============\n");
            parser.parse(new StringReader(html), 
                new HTMLEditorKit.ParserCallback() {
                    private int depth = 0;
                    @Override
                    public void handleStartTag(HTML.Tag t, 
                                              MutableAttributeSet a, 
                                              int pos) {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < depth; i++) sb.append("  ");
                        sb.append("<").append(t);
                        Enumeration<?> names = a.getAttributeNames();
                        while (names.hasMoreElements()) {
                            Object name = names.nextElement();
                            sb.append(" ").append(name).append("='")
                              .append(a.getAttribute(name)).append("'");
                        }
                        sb.append(">\n");
                        structure.append(sb.toString());
                        depth++;
                    }
                    @Override
                    public void handleEndTag(HTML.Tag t, int pos) {
                        depth--;
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < depth; i++) sb.append("  ");
                        sb.append("</").append(t).append(">\n");
                        structure.append(sb.toString());
                    }
                    @Override
                    public void handleText(char[] data, int pos) {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < depth; i++) sb.append("  ");
                        sb.append(new String(data)).append("\n");
                        structure.append(sb.toString());
                    }
                }, true);
            // 获取底部的文本区域并更新
            JScrollPane bottomPane = (JScrollPane) frame.getContentPane()
                .getComponent(2);
            JTextArea infoArea = (JTextArea) bottomPane.getViewport().getView();
            infoArea.setText(structure.toString());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new CompleteHTMLEditorExample().createAndShowGUI();
        });
    }
}

自定义 Parser Handler 高级示例

public class AdvancedHTMLParserHandler {
    // 自定义 Tag 处理器接口
    public interface TagHandler {
        void handle(HTML.Tag tag, MutableAttributeSet attrs);
    }
    // 可配置的解析器回调
    public static class ConfigurableParserCallback 
            extends HTMLEditorKit.ParserCallback {
        private Map<HTML.Tag, TagHandler> tagHandlers = new HashMap<>();
        private Map<HTML.Tag, TagHandler> endTagHandlers = new HashMap<>();
        private Consumer<String> textHandler;
        private StringBuffer buffer = new StringBuffer();
        public void registerTagHandler(HTML.Tag tag, TagHandler handler) {
            tagHandlers.put(tag, handler);
        }
        public void registerEndTagHandler(HTML.Tag tag, TagHandler handler) {
            endTagHandlers.put(tag, handler);
        }
        public void setTextHandler(Consumer<String> handler) {
            this.textHandler = handler;
        }
        @Override
        public void handleStartTag(HTML.Tag t, 
                                  MutableAttributeSet a, 
                                  int pos) {
            TagHandler handler = tagHandlers.get(t);
            if (handler != null) {
                handler.handle(t, a);
            }
        }
        @Override
        public void handleEndTag(HTML.Tag t, int pos) {
            TagHandler handler = endTagHandlers.get(t);
            if (handler != null) {
                handler.handle(t, null);
            }
        }
        @Override
        public void handleText(char[] data, int pos) {
            if (textHandler != null) {
                textHandler.accept(new String(data));
            }
        }
    }
    // 使用示例
    public static void main(String[] args) throws Exception {
        String html = "<html><body>" +
            "<h1>Title</h1>" +
            "<p class='content'>Paragraph text</p>" +
            "<a href='http://example.com'>Link</a>" +
            "</body></html>";
        ConfigurableParserCallback callback = new ConfigurableParserCallback();
        // 注册处理器
        callback.registerTagHandler(HTML.Tag.A, (tag, attrs) -> {
            String href = (String) attrs.getAttribute(HTML.Attribute.HREF);
            System.out.println("Link found: " + href);
        });
        callback.registerTagHandler(HTML.Tag.H1, (tag, attrs) -> {
            System.out.println("Heading 1 found");
        });
        callback.registerTagHandler(HTML.Tag.P, (tag, attrs) -> {
            String cls = (String) attrs.getAttribute(HTML.Attribute.CLASS);
            System.out.println("Paragraph with class: " + cls);
        });
        callback.setTextHandler(text -> {
            System.out.println("Text content: " + text.trim());
        });
        // 执行解析
        ParserDelegator parser = new ParserDelegator();
        parser.parse(new StringReader(html), callback, false);
    }
}
  1. JEditorPane: 显示和编辑 HTML 的组件
  2. HTMLEditorKit: 提供 HTML 编辑功能的编辑器套件
  3. Parser: 解析 HTML 内容的解析器
  4. Handler/Callback: 处理解析过程中的各种事件

这些组件共同提供了完整的 HTML 处理能力,可以用于:

  • HTML 内容展示
  • 富文本编辑
  • HTML 结构分析
  • 自定义 HTML 渲染

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