java - JEdi​​torPane 的奇怪行为

标签 java swing url jeditorpane

我创建了一个扩展 JEditorPane 的自定义类并使用它的 setPage() 方法。然而,我在使用它时遇到了一个非常奇怪的问题。这就是我的实现方式;

class WebReader extends JEditorPane {

  WebReader(String addressIn) {
    setEditable(false);
    showPage(addressIn)
  }

  void showPage(String address) {    
    try {
      setPage(address);
    } catch (Exception e) {
      e.printStackTrace();
  }
}

调用可能看起来像这样;

WebReader fooReader = new WebReader("https://www.google.com");
fooReader.showPage("https://www.google.comxxxx");

这本不应该起作用,但神秘地却起作用了。

非常奇怪的是,如果我已经输入了正确的 URL,它就不会捕获错误的 URL。例如,如果我输入“https://www.google.com ”,它工作正常(应该如此),然后输入 https://www.google.comxxxxx ,它仍然在我的 JEditorPane 上显示 google.com 并且不会引发异常(我希望它这样做)。

值得注意的是,如果我输入https://www.google.comxxxxx作为我的“起始 URL”,它确实会引发异常。

编辑:添加了更多代码。

最佳答案

如果页面是异步加载的(在后台),您将不会收到 IOException。是否异步加载 URL 取决于 EditorKit 针对您正在加载的内容类型安装的文档。来自 documentation for JEditorPane.setPage :

This may load either synchronously or asynchronously depending upon the document returned by the EditorKit. If the Document is of type AbstractDocument and has a value returned by AbstractDocument.getAsynchronousLoadPriority that is greater than or equal to zero, the page will be loaded on a separate thread using that priority.

If the document is loaded synchronously, it will be filled in with the stream prior to being installed into the editor with a call to setDocument, which is bound and will fire a property change event. If an IOException is thrown the partially loaded document will be discarded and neither the document or page property change events will be fired. If the document is successfully loaded and installed, a view will be built for it by the UI which will then be scrolled if necessary, and then the page property change event will be fired.

If the document is loaded asynchronously, the document will be installed into the editor immediately using a call to setDocument which will fire a document property change event, then a thread will be created which will begin doing the actual loading. In this case, the page property change event will not be fired by the call to this method directly, but rather will be fired when the thread doing the loading has finished. It will also be fired on the event-dispatch thread. Since the calling thread can not throw an IOException in the event of failure on the other thread, the page property change event will be fired when the other thread is done whether the load was successful or not.

显然,在这种情况下,网页的 EditorKit 是 HTMLEditorKit。来自 documentation of HTMLEditorKit :

Larger documents involve a lot of parsing and take some time to load. By default, this kit produces documents that will be loaded asynchronously if loaded using JEditorPane.setPage.

解决方法是自己同步加载文档,而不是使用 JEditorPane.setPage:

Document doc;

URLConnection connection = new URL(url).openConnection();
try (InputStream stream = connection.getInputStream()) {
    String contentType = connection.getContentType();
    EditorKit editorKit =
        JEditorPane.createEditorKitForContentType(contentType);
    doc = editorKit.createDefaultDocument();
    editorKit.read(stream, doc, 0);
}

pane.setDocument(doc);

关于java - JEdi​​torPane 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43870900/

相关文章:

java - 我怎样才能在这个循环中传递所有整数并在最后一行之前停止

java - 为什么这段java代码无法将图像保存到mysql数据库中?

java - 如何在 JPanel 上绘制 SimpleWeightedGraph?

java - 多个按钮的ActionListener-Swing

javascript - 有没有办法在 url 中传递 javascript 变量?

java - 实例化 newRequestQueue Volley

java - ServletRequest 获取实际页面的名称

java - 监听组件何时首次显示

url - 有 #!网址中的组合有特殊含义吗?

c# - 托管者通过其 IP 地址访问页面主机