6

私はそのようなコードを持っています:

// In MyPanel.java
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    // Draw something
    mypanel_count++;
}

// In Test.java
public void testLargeData()
{
    while (notDone)
    {
        panel.repaint();
        // do huge work
        test_count++;
        System.out.println("Test_count: " + test_count + ", MyPanel_count: " + mypanel_count);
    }
}

// Output !!!
Test_count: 752, MyPanel_count: 23
Test_count: 753, MyPanel_count: 23
Test_count: 754, MyPanel_count: 23
Test_count: 755, MyPanel_count: 24

しかし、に変更panel.repaint()するpanel.paintComponent(panel.getGraphics())と、アウトは正しいです:

Test_count: 752, MyPanel_count: 752
Test_count: 753, MyPanel_count: 753
Test_count: 754, MyPanel_count: 754
Test_count: 755, MyPanel_count: 755

なんで?paintComponentメソッドは機能しますが、盲目的な場合があるため、使用したくありません。誰でも私にいくつかの提案をすることができますか? ありがとう!

4

3 に答える 3

13

のドキュメントをrepaint注意深く読むと、次のように記載されていることに気付くでしょう (強調は私のものです):

このコンポーネントが軽量コンポーネントの場合、このメソッドはできるだけ早くこのコンポーネントのペイント メソッドを呼び出します。それ以外の場合、このメソッドはできるだけ早くこのコンポーネントの update メソッドを呼び出します。

これは、AWT/Swing が、立て続けに要求された再描画をマージすることにより、再描画を最適化できることを意味します。repaint(long time)AWT/Swing が再描画要求を満たすまで待機できる時間を制御できるメソッドもあります。ただし、特にループでリクエストを実行する場合は、リクエストをマージする可能性があります。

関連するさまざまな概念を説明している記事「Painting in AWT and Swing」を読むと役立つ場合があります。

反復ごとにパネルを再描画するには、描画が行われるのを待ってからループを続行する必要があります。これは、処理スレッド (ループ) と AWT/Swing スレッドの間で何らかの同期が必要であることを意味します。大まかなアイデアとして、たとえばwait()、最後の呼び出し以降に再描画されていない場合、ループの最後にあるパネルオブジェクトで、パネルのメソッドの最後にrepaint()呼び出すことができます。ただし、これを正しく実装するのは難しい場合があるため、コンポーネントの「リアルタイム」再描画が本当に必要な場合にのみこれを行う必要があります。代わりにを使用することもできますが、次のように、イベント ディスパッチ スレッドですべての処理を行う必要があります。notifyAll()paintComponent()paintImmediately(...)

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        while(notDone) {
            // Do your processing
            panel.paintImmediately(...);
        }
    }
});

これにより、ループの実行中にマウスやキーボード入力を含むイベント処理が停止することに注意してください。Swing と Threading の詳細については、「Swing の同時実行」を参照してください。

于 2012-11-19T12:21:42.293 に答える
0

paint(...) get が呼び出されるかどうか、またはいつ呼び出されるかを完全に制御することはできず、repaint() 呼び出しは、JVM がペイントすることを提案するだけであることを理解してください。あまりにも多くの repaint() リクエストが来て、それらがあなたのように積み重なった場合、それらは結合されます

参照: https://stackoverflow.com/a/13256847/1423083

于 2012-11-19T12:18:26.180 に答える