本文目录导读:

这是一个关于 Java Swing 中 JEditorPane 和 HTMLEditorKit 的特定错误或警告信息,通常出现在解析 HTML 内容时。
这个错误信息("no connection pending" 或 "NoConnectionPending")最常见的原因是 网络连接问题,或者 解析器在非预期状态下找到了数据,以下是详细的原因分析和解决方案:
核心原因分析
JEditorPane 默认使用 HTMLEditorKit 解析 HTML,在解析过程中,尤其是在处理包含图片(<img>)、样式表或框架的复杂 HTML 时,它可能会尝试异步加载资源(文件或网络资源)。
-
网络连接中断或未建立:你的代码尝试加载一个 URL(
http://...),但网络不可用、URL 不可达或连接被阻止,解析器内部的状态机在等待连接完成时,发现没有挂起的连接,于是抛出此错误。 -
setPage()与setText()混用:setPage(URL):是直接加载远程资源,容易出现此类网络错误。setText(htmlString):是设置纯文本内容,如果你先用setText()设置了大量 HTML,然后立即调用setPage()去加载另一个 URL,或者反之,可能会导致状态管理混乱,出现此错误。
-
解析器的内部状态机错误:Swing 的
HTMLEditorKit解析器(ParserDelegator)是一个事件驱动、有状态的解析器,HTML 内容格式严重错误(例如标签未闭合、属性值带引号异常),或者解析器在解析过程中遇到了它不期望的状态(例如在字符数据中间突然遇到 EOF),可能会触发此断言或异常。
常见的触发场景
- 加载一个包含损坏图片链接的 HTML 页面。
- 在
EDT(事件调度线程)之外修改 HTML 内容。 - 程序启动时网络环境尚未就绪。
- 使用
editorPane.setPage()指向一个不存在的本地文件路径。
解决方法(从简单到复杂)
请按顺序尝试以下解决方案:
确保资源可访问性和网络连接
-
本地文件:确保你传入
setPage()的文件路径是绝对路径且文件存在。new File("C:/myfile.html").toURI().toURL()。 -
远程 URL:在调用
setPage()之前,先用URLConnection测试一下 URL 是否能连接。// 简单的连接测试 try { URL url = new URL("http://example.com/page.html"); HttpURLConnection huc = (HttpURLConnection) url.openConnection(); huc.setRequestMethod("HEAD"); huc.connect(); int code = huc.getResponseCode(); if (code == 200) { editorPane.setPage(url); } else { System.err.println("URL 返回状态码: " + code); } } catch (Exception ex) { ex.printStackTrace(); }
使用 setText() 代替 setPage()(推荐用于本地/生成的内容)
如果你只是要显示动态生成的 HTML,不要用 setPage()。最稳定、最不容易出错的方式是:
String myHtmlContent = "<html><body><h1>Hello</h1></body></html>"; editorPane.setText(myHtmlContent);
是网络资源,你可以先下载内容为字符串,再 setText(),这彻底绕过了 setPage() 的网络异步加载机制。
// 安全的方式:下载 HTML 为字符串,setText()
try (InputStream is = new URL("http://example.com").openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
editorPane.setText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
在 EDT 上执行操作
始终确保对 JEditorPane 的任何修改都在 事件调度线程 上完成。
SwingUtilities.invokeLater(() -> {
editorPane.setPage(yourURL); // 或者 setText(...)
});
捕获异常并处理
在调用 setPage() 或清除内容时,放置一个 try-catch 块。
try {
editorPane.setPage(new URL("http://valid.url"));
} catch (IOException e) {
// 处理错误,例如显示错误页面或设置备用文本
editorPane.setText("<html><body>无法加载页面: " + e.getMessage() + "</body></html>");
e.printStackTrace();
}
手动重置解析器状态(终极方案)
如果上面的方法都无效,可以尝试“强制重置”:
// 先设置为纯文本,再设置回 HTML,以重置内部状态
editorPane.setContentType("text/plain");
editorPane.setText(""); // 清空
editorPane.setContentType("text/html"); // 恢复为 HTML
// 现在再尝试加载或设置 HTML
editorPane.setText("<html>...new content...</html>");
- 首选方案:如果你不需要加载外部资源(图片、CSS 文件),避免使用
setPage(),直接用setText()传入完整的 HTML 字符串,这是最稳定、最可控的方式。 - 网络资源:手动下载内容后再用
setText()填充,而不是依赖JEditorPane的内置网络加载。 - 调试:在出现错误的地方打印
e.printStackTrace(),查看完整的堆栈跟踪,以确定是哪个标签或哪行 HTML 触发的这个问题。
这个错误通常不是你的代码逻辑有语法问题,而是 Swing 的 HTML 渲染引擎在网络或状态管理上的脆弱性导致的,遵循上述方法,可以最大程度地避免它。