我已经创建了一个自定义类,它扩展了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作为我的'起始网址',它确实会引发异常。
编辑:添加了更多代码。
答案 0 :(得分:2)
如果页面异步加载(在后台),则不会出现IOException。是否异步加载URL取决于EditorKit为要加载的内容类型安装的文档。来自documentation for JEditorPane.setPage:
这可以同步或异步加载,具体取决于
EditorKit
返回的文档。如果Document
的类型为AbstractDocument
并且AbstractDocument.getAsynchronousLoadPriority
返回的值大于或等于零,则该页面将使用该优先级加载到单独的线程上。如果文档是同步加载的,那么在通过调用
setDocument
安装到编辑器之前,它将被流填充,该IOException
被绑定并将触发属性更改事件。如果抛出setDocument
,则将丢弃部分加载的文档,并且不会触发文档或页面属性更改事件。如果文档已成功加载并安装,UI将为其构建一个视图,然后在必要时滚动它,然后将触发页面属性更改事件。如果文档是异步加载的,文档将立即通过调用
IOException
安装到编辑器中,这将调用文档属性更改事件,然后将创建一个将开始执行实际加载的线程。在这种情况下,直接调用此方法不会触发页面属性更改事件,而是在执行加载的线程完成时触发。它也将在事件派发线程上触发。由于调用线程在另一个线程发生故障时无法抛出JEditorPane.setPage
,因此当另一个线程完成时,无论加载是否成功,都会触发页面属性更改事件。
显然,在这种情况下,网页的EditorKit是一个HTMLEditorKit。来自documentation of HTMLEditorKit:
较大的文档涉及大量解析并需要一些时间来加载。默认情况下,如果使用
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);
加载,此工具包将生成将异步加载的文档。
解决方法是自己同步加载文档,而不是使用JEditorPane.setPage:
componentWillReceiveProps() {
realms = this.state.realm;
if(realms == ""){
src = [];
}
else{
src = this.state.realm.objects('Bills');
}
this.setState({
dataSource: this.state.dataSource.cloneWithRows(src)
})
}
答案 1 :(得分:1)
我设法解决了!
我在showPage()中添加了以下内容:
setEditorKit(createDefaultEditorKit());
因此,每次更改网页时,它都会创建一个新的EditorKit。