Java Swing revalidate()とrepaint()


211

JPanelのコンテンツを頻繁に置き換えたいSwingアプリケーションを作成しています。これを行うには、を呼び出しremoveAll()、次に新しいコンテンツを追加して、を呼び出しrevalidate()ます。

ただし、古いコンテンツが実際に表示されていることがわかります(ただし、新しいコンテンツによって隠されています)。私はへの呼び出しを追加する場合repaint()に加えてrevalidate()、予想通り、それは動作します。

私が経験した他の機会では、電話をかけるだけrevalidate()で十分だと確信しています。

だから基本的に私の質問は-両方の関数を呼び出す必要がありますか?


6
Oracleのこのチュートリアルでは、「再検証後に必ず再ペイントを呼び出す」と述べています。説明はありませんが。

回答:


154

とを呼び出す必要がrepaint()ありrevalidate()ます。前者は、ウィンドウの領域が汚れていることをSwingに通知します(これは、によって削除された古い子のイメージを消去するために必要removeAll()です)。後者は、レイアウトマネージャーにレイアウトを再計算するように指示します(コンポーネントを追加するときに必要です)。これにより、パネルのが再描画されますが、パネル自体は再描画されない場合があります(再描画トリガーのリストについては、こちらを参照してください)。

より一般的な注意:元のパネルを再利用するのではなく、新しいパネルを作成して親でそれらを交換することをお勧めします。


1
新しいパネルを作成することが古いパネルを使用するよりも優れたソリューションである理由を合理化できますか :)
Arttu 2016年

3
@Arttu-作業が少ないため、エラーが発生しにくくなります。
kdgregory 2016年

86

remove()またはremoveAll()を実行するときはいつでも、

  validate();
  repaint();

新しいコンポーネントのadd()を完了した後。

remove()を実行する場合、validate()またはrevalidate()の呼び出しは必須です-関連するjavadocsを参照してください。

私自身のテストでは、repaint()も必要であることを示しています。正確な理由はわかりません。


59

revalidate新しいコンポーネントが追加されるか、古いコンポーネントが削除されると、コンテナで呼び出されます。この呼び出しは、レイアウトマネージャーに新しいコンポーネントリストに基づいてリセットするように指示する命令です。 revalidateコンポーネントが「ダーティリージョン」であると考えるものを再描画する呼び出しをトリガーします。明らかに、上のすべての領域JPanelがによってダーティと見なされるわけではありませんRepaintManager

repaintコンポーネントに自身を再描画するように指示するために使用されます。あなたのような状態をクリーンアップするためにこれを呼び出す必要がある場合がよくあります。


5

revalidate()コンテナのレイアウトを要求するだけで、revalidate()作品を呼び出すだけの場合、子コンポーネントの境界の更新がrepaint()再レイアウト中に境界が変更されたときにトリガーされることが原因である可能性があります。あなたが言及した場合、コンポーネントのみが削除され、コンポーネントの境界は変更されません。この場合、「誤って」トリガーされることrepaint()はありません。


-4

はい、repaint()を呼び出す必要があります。revalidate(); removeAll()を呼び出すときは、repaint()とrevalidate()を呼び出す必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.