ページが解析されたら、コンポーネントをレイアウトする前に、すべての画像が読み込まれるまで待つ必要があります。
コンポーネントをレイアウトする前に、すべての画像の読み込みをインターセプトして、すべての画像が完全に読み込まれていることを確認します。これは、HtmlDocumentImpl.loadImageをオーバーライドすることで行いました。(DocumentBuilderImplをサブクラス化し、createDocumentをオーバーライドして機能させる必要がありました。)セマフォを使用して、image.getWItdhの結果が利用可能になるまで待機しました。
一部のスクリプトはループして戻らない可能性があるため、解析の前後にタイマーを設定する必要がありました。これを解決するより良い方法があるかどうかはわかりません。
レイアウトに関しては、カーゴカルトや実験がたくさんあり、下の切り抜きにつながるので、いくつかのものを削除してみることができます。
htmlPanel.setVisible(true);
htmlPanel.setPreferredWidth(DEFAULT_PAGE_WIDTH);
logger.info("Calculating preferred size");
// Get the preferred heigth for the current width.
Dimension psvz = htmlPanel.getPreferredSize();
Dimension min = htmlPanel.getMinimumSize();
logger.info("prf :" + psvz);
logger.info("min :" + min);
// Enlarge to the minimum width (with a limit)
int width = Math.min(MAX_PAGE_WIDTH, Math.max(DEFAULT_PAGE_WIDTH,
psvz.width));
int height = psvz.height;
logger.info("width :" + width);
logger.info("heigth :" + height);
htmlPanel.setSize(width, height);
// actually, htmlPanel is a subclass, and this method exposes validateTree. It may work without it.
htmlPanel.forceValidateTree();
htmlPanel.doLayout();
setImageSize(width);
logger.info("actual size:" + htmlPanel.getSize());
JFrameがHtmlPanelを使用して、子を適切にペイントするために何をするのか理解できませんでした。子コンポーネントを使用してペイントする必要がありました。つまり、htmlPanel.getBlockRenderable()またはフレームセットのいずれかです。
画像は非同期でペイントされるため(ペイントが中止される可能性があります)、BufferedImageを使用する前に、すべての画像ペイントを完了する必要があります。
委任するgraphics2dオブジェクトを使用して、すべての画像ペイントメソッドをオーバーライドし、ペイントが完了するまで待機しました。
その後、すべての画像サイズがわかっているので、htmlが再レイアウトの恩恵を受ける可能性があることがわかりました。そのため、コンポーネントを無効にして、レイアウトとペイントを再度実行します(または、実際には、コードを2回呼び出すだけです...)
その後、BufferedImageを使用できます。たぶんもっと簡単な方法があります。