本文目录导读:

这个异常通常与 JEditorPane 结合 HTMLEditorKit 解析 HTML 时的线程中断有关,以下是详细分析和解决方案:
异常原因
ParserMethodInterruptedException 是 Swing HTML 解析器内部的中断异常,通常在以下情况发生:
- 线程中断:解析 HTML 的线程被意外中断(如线程池关闭)
- 超时机制:HTMLEditorKit 的内置超时检测触发
- 资源竞争:在事件调度线程(EDT)外部操作组件
典型场景
// 问题代码示例
JEditorPane editor = new JEditorPane();
editor.setEditorKit(new HTMLEditorKit());
// 在非 EDT 线程中设置内容(可能导致中断)
new Thread(() -> {
editor.setText("<html><body>...</body></html>");
}).start();
// 或者频繁快速更新内容
for (int i = 0; i < 100; i++) {
editor.setText(htmlContent); // 可能触发中断
}
解决方案
使用 SwingUtilities.invokeLater
SwingUtilities.invokeLater(() -> {
editor.setText(htmlContent);
});
处理中断异常
try {
editor.setText(htmlContent);
} catch (RuntimeException e) {
if (e.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt(); // 恢复中断状态
// 重新尝试或记录日志
System.err.println("HTML 解析被中断,无需重试");
} else {
throw e; // 其他异常重新抛出
}
}
使用 Document 替换内容(更安全)
import javax.swing.text.Document;
// 使用 Document 操作(避免解析器中断)
SwingUtilities.invokeLater(() -> {
try {
HTMLEditorKit kit = (HTMLEditorKit) editor.getEditorKit();
Document doc = kit.createDefaultDocument();
editor.setDocument(doc);
kit.read(new StringReader(htmlContent), doc, 0);
} catch (Exception ex) {
ex.printStackTrace();
}
});
完整的安全设置方法
public class SafeHtmlEditor {
private final JEditorPane editor;
public void setHtmlContentSafe(String html) {
SwingUtilities.invokeLater(() -> {
try {
// 暂停当前解析
editor.getDocument().render(() -> {
// 设置内容时保持线程安全
editor.setText(html);
});
} catch (Exception e) {
// 捕获并处理中断异常
handleInterruptException(e);
}
});
}
private void handleInterruptException(Exception e) {
if (e instanceof RuntimeException &&
e.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt();
// 可以选择延迟后重试
scheduleRetry();
}
}
private void scheduleRetry() {
Timer timer = new Timer(100, e -> {
setHtmlContentSafe(currentHtml);
});
timer.setRepeats(false);
timer.start();
}
}
预防措施
// 禁止在解析器工作时更改内容
private boolean isParsing = false;
public void setContentSafely(String html) {
if (isParsing) {
queueContent(html); // 放入队列,稍后处理
return;
}
isParsing = true;
SwingUtilities.invokeLater(() -> {
try {
editor.setText(html);
} finally {
isParsing = false;
processQueue(); // 处理队列中的内容
}
});
}
- 始终在 EDT 线程中操作 JEditorPane
- 使用 Document 对象替代直接 setText()
- 捕获并正确处理中断异常
- 避免频繁快速更新 HTML 内容
- 考虑使用更现代的 WebView(JavaFX)作为替代
如果问题持续存在,建议代码审计,检查是否有线程安全问题或不当的线程中断操作。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播