本文目录导读:

- 核心概念说明
- 常见场景:提取纯文本(从 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(如表格、嵌套标签),欢迎提供更多细节,我可以给出更精准的示例。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播