JEditorPane同步加载网页

2014-02-19 8:56 by Elliot

最近在做的一个项目中, 需要在Java桌面控件上显示一个本地的html, 功能很简单, 显示一个网页, 把网页转换成图片, 然后打印.
由于功能极其简单, 也不想引用过多外部文件, 所以选择了Swing自带的JEditorPane来显示网页.
可是由于JEditorPane加载网页是异步的, 所以我并不知道网页什么时候会加载完成, 也就不知道要在什么时间把网页转换为图片.

JEditorPane pane = new JEditorPane();
pane.setContentType("text/html");
pane.addPropertyChangeListener("page", new PropertyChangeListener() {
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        // TODO Auto-generated method stub
    }
});

上面代码的addPropertyChangeListener方法可以为JEditorPane添加一个listener, 该listener会在html文档load完成的时候触发, 但是如果html中包含了外部文件,
如样式表文件, 脚本文件, 或者图片的时候, 它不会判断这些外部文件是否已经加载完成, 只要html文档加载完成就会触发该listener.
很遗憾, 我的html中可能会包含图片,所以依旧是无法知道该在什么时候把网页转换为图片.

分析一下问题, 发现造成这种情况的原因完全是因为JEditorPane加载html的时候是异步的, 如果能够使其同步加载html, 那问题也就解决了.
可是如何让JEditorPane同步加载html呢?
查看HTMLEditorKit类的Javadoc中有这样一段话:

Asynchronous Loading

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. This is controlled by a property on the document. The method createDefaultDocument can be overriden to change this. The batching of work is done by the HTMLDocument.HTMLReader class. The actual work is done by the DefaultStyledDocument and AbstractDocument classes in the text package.

OK, 看来只要重写一下createDefaultDocument方法就可以了.

class SynchronousHTMLEditorKit extends HTMLEditorKit {
 
    @Override
    public Document createDefaultDocument() {
        HTMLDocument doc = (HTMLDocument) super.createDefaultDocument();
        // Set to synchronous
        doc.setAsynchronousLoadPriority(-1);
        return doc;
    }
}

然后修改一下JEditorPane的EditorKit:

JEditorPane pane = new JEditorPane();
pane.setEditorKitForContentType("text/html", new SynchronousHTMLEditorKit());
pane.setContentType("text/html");

这样JEditorPane就可以同步加载html网页了.

PS: JEditorPane之所以异步加载html是因为加载一个稍大一点的html文档可能就会耗费比较明显的时间, 我这里改成同步有着自己独特的应用场景.

本文基于 署名 2.5 中国大陆 许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 Elliot 并包含 原文链接
发表评论

本文有 2 条评论

  1. lidaddy
    2014-04-25 12:06

    你好,请问上面代码页面的浮动层怎么弄的,小白一枚,谢谢!

  2. Elliot
    2014-04-25 14:01

    插件啊~ 叫WP-GeSHi-Highlight。

发表评论