[英]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()請求進入並且它們正在進行堆疊,那么它們將被合並
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.