JEditorPaneHTMLEditorKitParserSubscribe订阅

wen java案例 1

本文目录导读:

JEditorPaneHTMLEditorKitParserSubscribe订阅

  1. 场景一:订阅/监听 HTML 解析完成事件
  2. 场景二:替换默认解析器以订阅底层解析事件
  3. 总结:应对“订阅”需求的方案

基于您提供的关键词 JEditorPane HTMLEditorKit Parser Subscribe,您可能是在 Java Swing 开发中遇到了以下两种常见情况之一:

  1. 如何监听/订阅 JEditorPane 的 HTML 解析完成事件?
  2. 如何自定义 HTML 解析器 (ParserCallback) 来拦截或处理特定的 HTML 标签?

下面针对这两个场景提供详细解答。

订阅/监听 HTML 解析完成事件

JEditorPane 在使用 HTMLEditorKit 加载 HTML 内容时,解析和渲染是异步进行的,Java Swing 本身并没有直接提供一个“解析完成”的事件监听器(如 addParseListener),但可以通过以下几种曲线救国的方式实现“订阅”效果。

方法 1:使用 PropertyChangeListener(推荐)

这是最标准的方法,当编辑器内容加载完毕后,page 属性会发生变化。

import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class HtmlParseListener {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JEditorPane editorPane = new JEditorPane();
        editorPane.setEditorKit(new HTMLEditorKit());
        editorPane.setEditable(false);
        // ★ 订阅页面加载完成事件
        editorPane.addPropertyChangeListener("page", new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                System.out.println("HTML 解析完成,页面已加载!");
                // 在这里执行你需要在解析完成后做的事情
                // 设置光标位置、修改文档、添加链接监听器等
            }
        });
        // 加载 HTML
        editorPane.setText("<html><body><h1>Hello, World!</h1></body></html>");
        frame.add(new JScrollPane(editorPane));
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

方法 2:继承 HTMLEditorKit 并重写 createParser

如果你需要在解析过程中进行拦截(而不仅仅是完成时),可以自定义 ParserCallback

import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.html.parser.DTD;
import javax.swing.text.html.HTML;
import javax.swing.text.MutableAttributeSet;
import java.io.*;
public class CustomHtmlEditorKit extends HTMLEditorKit {
    @Override
    public Parser getParser() {
        // 返回一个自定义的解析器,或者像下面这样返回默认解析器
        // 但为了拦截回调,通常需要自定义 Callback
        return super.getParser();
    }
    // 另一种方法:如果你想要完全控制解析,可以这样
    public static void parseWithCustomCallback(String html, final HTMLEditorKit.ParserCallback customCallback) {
        ParserDelegator parser = new ParserDelegator();
        try {
            Reader reader = new StringReader(html);
            // 使用你的自定义 Callback
            parser.parse(reader, customCallback, true);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 使用示例
    public static void main(String[] args) {
        String htmlContent = "<html><body><p>Test</p></body></html>";
        parseWithCustomCallback(htmlContent, new HTMLEditorKit.ParserCallback() {
            @Override
            public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
                System.out.println("开始标签: " + t + " 位置: " + pos);
                // ★ 这里就是订阅点:每当解析器遇到开始标签就会调用
            }
            @Override
            public void handleText(char[] data, int pos) {
                System.out.println("文本: " + new String(data));
            }
            @Override
            public void handleEndTag(HTML.Tag t, int pos) {
                System.out.println("结束标签: " + t);
            }
            @Override
            public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
                System.out.println("单标签: " + t);
            }
            @Override
            public void handleError(String errorMsg, int pos) {
                System.err.println("解析错误: " + errorMsg);
            }
        });
    }
}

替换默认解析器以订阅底层解析事件

如果你需要全局替换 JEditorPane 使用的解析器(ParserDelegator),可以通过覆盖 HTMLEditorKitgetParser() 方法来实现,不过通常情况下,直接使用 PropertyChangeListener 或自定义 ParserCallback 就足够了。

应对“订阅”需求的方案

需求 解决方案 关键代码/类
解析完成后执行动作 addPropertyChangeListener("page", ...) JEditorPane
在解析过程中拦截标签 自定义 ParserCallback HTMLEditorKit.ParserCallback
完全自定义解析器 继承 HTMLEditorKit 并重写 getParser() HTMLEditorKit, ParserDelegator

如果您能提供更多上下文(“我在做一个富文本编辑器,想在解析某个特定标签时触发一个动作”),我可以给出更精确的代码示例。

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