JEditorPaneHTMLEditorKitParserMonitor监控

wen java案例 2

本文目录导读:

JEditorPaneHTMLEditorKitParserMonitor监控

  1. JEditorPane 与 HTMLEditorKit 概述
  2. 解析器监控(Parser Monitor)
  3. 高级监控功能
  4. 注意事项

我来详细介绍 JEditorPaneHTMLEditorKit 和解析器监控(Parser Monitor)的相关内容。

JEditorPane 与 HTMLEditorKit 概述

JEditorPane

  • Swing 中的轻量级 HTML 渲染组件
  • 支持 HTML 3.2 和部分 CSS 功能
  • 使用 HTMLEditorKit 作为默认编辑器

HTMLEditorKit

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

解析器监控(Parser Monitor)

基本实现

import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
import javax.swing.text.*;
public class HTMLParserMonitor {
    public static void main(String[] args) {
        JEditorPane editorPane = new JEditorPane();
        // 创建自定义的 HTMLEditorKit
        HTMLEditorKit kit = new HTMLEditorKit() {
            @Override
            public Document createDefaultDocument() {
                HTMLDocument doc = (HTMLDocument) super.createDefaultDocument();
                // 设置解析器监控
                doc.setParser(new DocumentParser() {
                    @Override
                    public void parse(Reader r, HTMLDocument doc) throws IOException {
                        System.out.println("开始解析 HTML...");
                        super.parse(r, doc);
                        System.out.println("HTML 解析完成");
                    }
                });
                return doc;
            }
        };
        editorPane.setEditorKit(kit);
    }
}

完整的监控实现

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
import java.io.*;
public class ParserMonitorExample {
    public static class MonitoredHTMLEditorKit extends HTMLEditorKit {
        @Override
        public Document createDefaultDocument() {
            HTMLDocument doc = new HTMLDocument() {
                @Override
                public void parse(Reader r) throws IOException {
                    System.out.println("=== 开始解析 HTML 文档 ===");
                    long startTime = System.currentTimeMillis();
                    // 添加解析监听器
                    addDocumentListener(new DocumentListener() {
                        @Override
                        public void insertUpdate(DocumentEvent e) {
                            System.out.println("插入内容: " + e.getOffset() + ", 长度: " + e.getLength());
                        }
                        @Override
                        public void removeUpdate(DocumentEvent e) {
                            System.out.println("删除内容: " + e.getOffset() + ", 长度: " + e.getLength());
                        }
                        @Override
                        public void changedUpdate(DocumentEvent e) {
                            System.out.println("修改内容: " + e.getOffset() + ", 长度: " + e.getLength());
                        }
                    });
                    // 执行解析
                    try {
                        super.parse(r);
                    } catch (Exception e) {
                        System.err.println("解析错误: " + e.getMessage());
                        e.printStackTrace();
                    }
                    long endTime = System.currentTimeMillis();
                    System.out.println("=== 解析完成,耗时: " + (endTime - startTime) + "ms ===");
                }
            };
            return doc;
        }
        @Override
        public ViewFactory getViewFactory() {
            return new HTMLFactory() {
                @Override
                public View create(Element elem) {
                    View view = super.create(elem);
                    if (view != null) {
                        System.out.println("创建视图: " + view.getClass().getSimpleName() 
                            + " 元素: " + elem.getName());
                    }
                    return view;
                }
            };
        }
    }
    // 使用示例
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("HTML Parser Monitor");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(600, 400);
            JEditorPane editorPane = new JEditorPane();
            MonitoredHTMLEditorKit kit = new MonitoredHTMLEditorKit();
            editorPane.setEditorKit(kit);
            // 设置 HTML 内容
            String html = "<html><body><h1>标题</h1><p>段落内容</p></body></html>";
            editorPane.setText(html);
            JScrollPane scrollPane = new JScrollPane(editorPane);
            frame.add(scrollPane);
            frame.setVisible(true);
            // 监控解析过程
            monitorParsing(editorPane);
        });
    }
    private static void monitorParsing(JEditorPane editorPane) {
        HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
        doc.addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                printDocumentInfo(doc);
            }
            @Override
            public void removeUpdate(DocumentEvent e) {
                printDocumentInfo(doc);
            }
            @Override
            public void changedUpdate(DocumentEvent e) {
                printDocumentInfo(doc);
            }
        });
    }
    private static void printDocumentInfo(HTMLDocument doc) {
        System.out.println("\n文档信息:");
        System.out.println("元素数量: " + doc.getLength());
        System.out.println("段落数量: " + countElements(doc, HTML.Tag.P));
        System.out.println("标题数量: " + countElements(doc, HTML.Tag.H1));
        System.out.println("-------------------");
        // 列出所有元素
        Element root = doc.getDefaultRootElement();
        printElementTree(root, 0);
    }
    private static int countElements(HTMLDocument doc, HTML.Tag tag) {
        int count = 0;
        Element root = doc.getDefaultRootElement();
        count = countElementsRecursive(root, tag);
        return count;
    }
    private static int countElementsRecursive(Element element, HTML.Tag tag) {
        int count = 0;
        AttributeSet attrs = element.getAttributes();
        Object name = attrs.getAttribute(StyleConstants.NameAttribute);
        if (name == tag) {
            count++;
        }
        for (int i = 0; i < element.getElementCount(); i++) {
            count += countElementsRecursive(element.getElement(i), tag);
        }
        return count;
    }
    private static void printElementTree(Element element, int indent) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < indent; i++) {
            sb.append("  ");
        }
        AttributeSet attrs = element.getAttributes();
        Object name = attrs.getAttribute(StyleConstants.NameAttribute);
        sb.append("元素: ").append(name != null ? name.toString() : "unknown");
        if (element.isLeaf()) {
            sb.append(" [leaf]");
            try {
                int start = element.getStartOffset();
                int end = element.getEndOffset();
                Document doc = element.getDocument();
                String content = doc.getText(start, end - start);
                sb.append(" 内容: '").append(content.trim()).append("'");
            } catch (BadLocationException e) {
                // ignore
            }
        }
        System.out.println(sb.toString());
        for (int i = 0; i < element.getElementCount(); i++) {
            printElementTree(element.getElement(i), indent + 1);
        }
    }
}

高级监控功能

自定义标签处理器

public class CustomTagHandler extends HTMLDocument.HTMLReader.TagAction {
    @Override
    public void start(HTMLDocument.HTMLReader.TagAction t, HTML.Tag tag, MutableAttributeSet attrs) {
        System.out.println("开始标签: " + tag);
        if (attrs != null) {
            System.out.println("  属性: " + attrs);
        }
        super.start(t, tag, attrs);
    }
    @Override
    public void end(HTMLDocument.HTMLReader.TagAction t, HTML.Tag tag) {
        System.out.println("结束标签: " + tag);
        super.end(t, tag);
    }
}

性能监控

public class PerformanceMonitor {
    private long startTime;
    private int elementCount;
    public void startTracking() {
        startTime = System.currentTimeMillis();
        elementCount = 0;
    }
    public void trackElement(Element element) {
        elementCount++;
    }
    public void printReport() {
        long duration = System.currentTimeMillis() - startTime;
        System.out.println("解析性能报告:");
        System.out.println("  元素总数: " + elementCount);
        System.out.println("  解析耗时: " + duration + "ms");
        System.out.println("  平均速度: " + (elementCount / (duration / 1000.0)) + " 元素/秒");
    }
}

注意事项

  1. 线程安全:Swing 组件需要在事件调度线程(EDT)中操作
  2. 性能影响:监控功能会增加性能开销
  3. 内存使用:大量文档解析时注意内存管理
  4. 解析限制:Swing HTML 解析器支持有限,复杂 HTML 可能需要其他库

这个监控系统可以帮助开发人员了解 HTML 文档的解析过程,调试渲染问题,以及优化性能。

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