1

開発中の Swing アプリで再描画を行うと、奇妙な問題が発生します。特定のコンポーネントのテキスト (ウィンドウの一番下にあるステータス バーのテキスト ラベル) を設定すると、画面の非常に異なる領域にあるテーブル全体が再描画されるように指示されていることがわかりました。基本的にステータスバーのテキストを設定するたびにウィンドウ全体を再描画するように求められているように見えるため、パフォーマンスの問題が発生しています。

何が起こっているのかを把握しようとして RepaintManager をさまよい、このテキストのラベルを設定しようとすると、メインの JPanel 全体がダーティ コンポーネントとしてマークされていることがわかりました。ただし、どの時点でそれが発生しているのか、正確にはなぜそれが発生しているのかをデバッグするのに問題があります。再描画システムについて調べてみましたが、他のテキスト ラベルが設定されているときに重複しないテーブルを再描画する必要がある理由がわかりません。

Swing Explorer を使用して、レイアウトの境界線を視覚化して、異常な方法でオーバーラップしていないことを確認しました。すべて問題ないように見えます。

JTable に再描画を要求している一連の呼び出しを特定する方法を探しています。paintComponent() にブレークポイントを追加してスタックをたどると、RepaintManager の paintDirtyRegions() 呼び出しの内部に行き着き、メインの JPanel 全体 (ウィンドウ内のすべてを含む) が tmpDirtyComponents 変数内に置かれます。

最初に単一のステータステキストラベルを設定しただけで、JPanel全体がダーティとしてマークされる方法を誰か説明できますか? そうでない場合は、エラーを見つけるためにどこにフックするかについて、いくつかのガイダンスを提供していただけますか?

ご協力いただきありがとうございます。

4

3 に答える 3

1

Just to add to camickr's comment, overriding isValidateRoot() for the troublesome component is the correct solution to this problem, and is usually the correct solution to solving unnecessary repaint problems.

The drawback is that if a change to your isValidateRoot component does actually require the component to change size, you will need to force a revalidation manually (myValidateRoot.getParent().invalidate() should do it).

于 2016-07-17T09:33:31.597 に答える
1

どういうわけか、レイアウト マネージャーを変更することで、この問題を回避することができました。メイン パネルは GroupLayout を使用していました。全体的な GroupLayout は非常にシンプルだったので、BorderLayout.CENTER に追加された JPanel のメイン ウィンドウのコンテンツと、BorderLayout.PAGE_END にステータス バー ラベルを追加して、代わりに BorderLayout を試すことにしました。ステータス ラベル テキストを設定すると、ウィンドウ全体が無効化され、再描画されるという問題が修正されました。すばらしい提案をしてくれたみんなに感謝します!

于 2011-03-21T02:11:41.763 に答える