概要

JEditorPaneに画像付きのHTMLを読み込み、描画が完了した段階で全体のスクリーンショットを撮る方法をテストします。

サンプルコード

class ImageLoadSynchronouslyHTMLEditorKit extends HTMLEditorKit {
  @Override public ViewFactory getViewFactory() {
    return new HTMLEditorKit.HTMLFactory() {
      @Override public View create(Element elem) {
        View view = super.create(elem);
        if (view instanceof ImageView) {
          ((ImageView) view).setLoadsSynchronously(true);
        }
        return view;
      }
    };
  }

  // @Override public Document createDefaultDocument() {
  //   Document doc = super.createDefaultDocument ();
  //   ((HTMLDocument) doc).setAsynchronousLoadPriority(-1);
  //   return doc;
  // }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、タブを切り替えた後にJEditorPane#setText(...)HTMLの読み込みを行い、全体のスクリーンショットを縮小してサムネイル画像を作成し右端のJLabelに表示しています。

  • defaultタブ
    • デフォルトのHTMLEditorKitを使用
    • <img>タグの画像が非同期で読み込まれるためスクリーンショットは文字のみ表示される
    • 文書の末尾までスクロールした後で画像のサイズが決まる
  • <img width='%d' ...タブ
    • デフォルトのHTMLEditorKitを使用
    • <img>タグに予めサイズを属性で指定しているのでスクリーンショット全体のサイズや、スクロールは正常だがスクリーンショットに画像は表示されない
  • LoadsSynchronouslyタブ
    • HTMLEditorKit#getViewFactory()ViewFactory#create(Element)をオーバーライドし、ImageViewsetLoadsSynchronously(true)を設定することで画像の読み込みを同期的に行う
    • スクリーンショットに画像がすべてロードされた状態で表示される

  • JDK 11.0.2JDK 8.0.202からImageViewsetLoadsSynchronously(true)を設定すると画像が表示されなくなってしまった
  • JDK 11.0.1では正常に画像が表示される
    openjdk version "11.0.1" 2018-10-16
    OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
    OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)

参考リンク

コメント