簡體   English   中英

Java中的repaint()不會立即“重新繪制”?

[英]repaint() in Java doesn't “re-paint” immediately?

我有這樣的代碼:

// 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()) ,out是正確的:

 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方法有效,但有時它是盲目的,所以我不想使用它。 有人可以給我一些建議嗎? 謝謝!

如果您仔細閱讀repaint的文檔,您會注意到它(強調我的):

如果此組件是輕量級組件,則此方法會盡快調用此組件的paint方法。 否則,此方法會盡快調用此組件的更新方法。

這意味着允許AWT / Swing通過合並快速連續請求的重繪來優化重新繪制。 還有一個repaint(long time)方法,它允許您控制AWT / Swing在完全填充重繪請求時等待的時間。 它可能仍會合並請求,特別是如果你在循環中執行它們。

閱讀文章“在AWT和Swing中繪畫”可能會有所幫助,該文章試圖解釋所涉及的各種概念。

要讓每次迭代都重新繪制面板,您必須等待繪制,然后繼續循環。 這意味着您需要在處理線程(循環)和AWT / Swing線程之間進行一些同步。 作為一個粗略的想法,你可以在循環結束時的面板對象上wait() ,如果它自上次調用repaint()以來沒有重新repaint()並在面板的paintComponent()結束時調用notifyAll() paintComponent()方法。 但是,實現這一點可能很棘手,所以只有在真正需要“實時”重新繪制組件時才應該這樣做。 作為替代方案,可以使用paintImmediately(...) ,但您必須在事件調度線程中執行所有處理,如下所示:

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

請注意,這將停止任何事件處理,包括在循環運行時處理鼠標和鍵盤輸入。 您可以在“Swing中的並發”中閱讀有關Swing和Threading的更多信息

正如其他答案所說:這是AWT何時調用paint()

如果你做一些需要繪制/布局組件信息的工作,那么將這項工作放到一個等待繪畫完成的工作線程中也有幫助。

在你的情況下,這將是:

panel.repaint();

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        // do huge work
        test_count++;
        System.out.println("Test_count: " + test_count 
             + ", MyPanel_count: " + mypanel_count);
    }
});

雖然我不確定它在你的while循環中的表現如何。

了解到你無法完全控制是否或何時調用paint(...),而且repaint()調用只是建議JVM繪制的。 如果有太多repaint()請求進入並且它們正在進行堆疊,那么它們將被合並

參考: https//stackoverflow.com/a/13256847/1423083

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM