本文目录导读:

- 核心概念说明
- 常见场景:提取纯文本(从 HTML 中剥离标签)
- 常见场景:在 JEditorPane 中显示 HTML 并获取选中文本
- 常见问题与注意事项
- 进阶:使用 Jsoup 替代(推荐用于复杂文本提取)
针对你提到的关键词组合 JEditorPane、HTMLEditorKit、Parser 和 Text文本处理,这通常涉及在 Java Swing 中使用 JEditorPane 搭配 HTMLEditorKit 来解析和显示 HTML 内容,或者提取其中的纯文本。
下面整理了关于这三个核心组件的场景说明、常见问题及代码示例。
核心概念说明
JEditorPane:Swing 中的一个文本组件,可以显示纯文本、HTML 和 RTF 格式。HTMLEditorKit:负责解析和编辑 HTML 内容的编辑器工具包,它是JEditorPane显示 HTML 的核心。Parser/ParserCallback:HTMLEditorKit内部使用javax.swing.text.html.parser.ParserDelegator来解析 HTML,你可以通过自定义HTMLEditorKit.ParserCallback来拦截解析过程中的各种 HTML 标签和文本,从而提取纯文本或进行自定义处理。
常见场景:提取纯文本(从 HTML 中剥离标签)
这是最常见的需求,使用 HTMLEditorKit 的 ParserDelegator 配合 ParserCallback 实现。
代码示例:从 HTML 字符串中提取纯文本
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;
import java.io.IOException;
import java.io.StringReader;
public class HtmlToPlainTextExtractor {
public static String extractText(String html) throws IOException {
if (html == null || html.isEmpty()) {
return "";
}
final StringBuilder text = new StringBuilder();
// 1. 创建 ParserCallback
HTMLEditorKit.ParserCallback callback = new HTMLEditorKit.ParserCallback() {
@Override
public void handleText(char[] data, int pos) {
// 每当解析到文本节点时,追加到 StringBuilder
text.append(data);
}
@Override
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
// 处理开始标签,例如遇到 <br> 或 <p> 时添加换行
if (t == HTML.Tag.BR || t == HTML.Tag.P || t == HTML.Tag.DIV || t == HTML.Tag.LI) {
text.append('\n');
}
}
@Override
public void handleEndTag(HTML.Tag t, int pos) {
// 处理结束标签,如 </p>、</div> 后加换行
if (t == HTML.Tag.P || t == HTML.Tag.DIV || t == HTML.Tag.H1 || t == HTML.Tag.H2
|| t == HTML.Tag.H3 || t == HTML.Tag.H4 || t == HTML.Tag.H5 || t == HTML.Tag.H6
|| t == HTML.Tag.LI) {
text.append('\n');
}
}
@Override
public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
// 处理自闭合标签,如 <br/>、<hr/>
if (t == HTML.Tag.BR) {
text.append('\n');
} else if (t == HTML.Tag.HR) {
text.append("\n---\n");
}
}
@Override
public void handleComment(char[] data, int pos) {
// 忽略注释,不处理
}
@Override
public void handleError(String errorMsg, int pos) {
// 可以记录日志,但通常忽略解析错误
System.err.println("HTML Parse error at " + pos + ": " + errorMsg);
}
};
// 2. 创建解析器并解析
ParserDelegator parser = new ParserDelegator();
// 注意:StringReader 需要包装
try (StringReader reader = new StringReader(html)) {
// 第三个参数用于 Strict/Transitional 模式,通常设为 true
parser.parse(reader, callback, true);
}
return text.toString().trim();
}
public static void main(String[] args) throws IOException {
String html = "<html><body><h1>Title</h1><p>This is <b>bold</b> and <i>italic</i> text.</p><br/>Line 2<br>Line 3<ul><li>Item 1</li><li>Item 2</li></ul></body></html>";
String plainText = extractText(html);
System.out.println("=== Plain Text ===");
System.out.println(plainText);
// 期望输出:
// Title
// This is bold and italic text.
// Line 2
// Line 3
// Item 1
// Item 2
}
}
常见场景:在 JEditorPane 中显示 HTML 并获取选中文本
如果你已经在界面上使用 JEditorPane 显示 HTML,并希望获取用户选中的纯文本。
代码示例:从 JEditorPane 获取选中文本(纯文本)
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
public class JEditorPaneDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("JEditorPane HTML Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
// 1. 创建 JEditorPane 并设置 HTMLEditorKit
JEditorPane editorPane = new JEditorPane();
editorPane.setEditorKit(new HTMLEditorKit());
editorPane.setText("<html><body><b>Bold</b> and <i>Italic</i> text.<br/><a href='#'>Click me</a></body></html>");
editorPane.setEditable(false); // 通常作为显示组件
// 2. 获取选中文本 (纯文本,无标签)
JButton getSelectedButton = new JButton("Get Selected Text");
getSelectedButton.addActionListener(e -> {
String selectedText = editorPane.getSelectedText();
// 注意:getSelectedText() 默认返回的是去掉 HTML 标签的纯文本
// 但如果需要更干净的文本,可能需要手动解析
JOptionPane.showMessageDialog(frame, "Selected: '" + selectedText + "'");
});
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(editorPane), BorderLayout.CENTER);
frame.add(getSelectedButton, BorderLayout.SOUTH);
frame.setVisible(true);
});
}
}
注意:
editorPane.getSelectedText()返回的是视图渲染后的文本(即去掉了标签,保留了格式后的视觉效果)。- 如果你需要提取整个文档的纯文本(类似上面的
extractText方法),JEditorPane本身没有直接提供一个方法,你需要用Document配合EditorKit来实现,或者直接使用上面的解析器方法。
常见问题与注意事项
- 解析器线程安全:
ParserDelegator不是线程安全的,不要在多个线程中同时解析。 - 性能问题:解析大段 HTML 可能会消耗较多 CPU,建议在后台线程中执行解析操作。
- 不完整的 HTML:
HTMLEditorKit的解析器比较宽容,能处理一些不规范的 HTML,但复杂的现代页面(如包含 JavaScript、CSS 复杂布局)效果有限。 - 编码问题:确保输入字符串的编码正确,防止中文乱码。
- 依赖:
HTMLEditorKit是 Java SE 自带的,无需额外引入第三方库,如果需要更强大的 HTML 处理(如 XHTML、严格语法、CSS 选择器),建议使用第三方库如 Jsoup(功能更强、更简单)。
进阶:使用 Jsoup 替代(推荐用于复杂文本提取)
如果你不局限于 Swing 组件,只是想从 HTML 中提取纯文本,Jsoup 是最优雅的选择。
// 需要添加依赖:org.jsoup:jsoup:1.17.2
import org.jsoup.Jsoup;
public class JsoupExtractor {
public static String extractText(String html) {
if (html == null || html.isEmpty()) return "";
// Jsoup.parse 自动处理标签剥离,jsoup 的 text() 方法自动加空格分隔
return Jsoup.parse(html).text();
}
public static void main(String[] args) {
String html = "<div>Hello <b>World</b>! <ul><li>Item 1</li><li>Item 2</li></ul></div>";
System.out.println(JsoupExtractor.extractText(html));
// 输出: "Hello World! Item 1 Item 2"
}
}
- 在 Swing 中显示 HTML -> 使用
JEditorPane+HTMLEditorKit。 - 从 HTML 中提取纯文本(自定义) -> 使用
ParserDelegator+ParserCallback。 - 从 HTML 中提取纯文本(推荐第三方) -> 使用 Jsoup,代码更简洁,解析更健壮。
- 获取 JEditorPane 中选中的纯文本 ->
editorPane.getSelectedText()。
如果你有具体的代码报错或需要处理某种特定格式的 HTML(如表格、嵌套标签),欢迎提供更多细节,我可以给出更精准的示例。