Boo*_*ley 5 java swing repaint paintcomponent
我有这样的代码:
// 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
Run Code Online (Sandbox Code Playgroud)
但是当我改变panel.repaint()时panel.paintComponent(panel.getGraphics()),出局是正确的:
Run Code Online (Sandbox Code Playgroud)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方法有效,但有时它是盲目的,所以我不想使用它.有人可以给我一些建议吗?谢谢!
Sim*_*ann 11
如果您repaint仔细阅读文档,您会注意到它(强调我的):
如果此组件是轻量级组件,则此方法会尽快调用此组件的paint方法.否则,此方法会尽快调用此组件的更新方法.
这意味着允许AWT/Swing通过合并快速连续请求的重绘来优化重新绘制.还有一种repaint(long time)方法,允许您控制AWT/Swing在完全填充重绘请求时等待的时间.它可能仍会合并请求,特别是如果你在循环中执行它们.
阅读文章"在AWT和Swing中绘画"可能会有所帮助,该文章试图解释所涉及的各种概念.
要让每次迭代都重新绘制面板,您必须等待绘制,然后继续循环.这意味着您需要在处理线程(循环)和AWT/Swing线程之间进行一些同步.作为一个粗略的想法,你可以wait()在循环结束时的面板对象上,如果它自上次调用后没有重新绘制,repaint()并notifyAll()在面板paintComponent()方法结束时调用.但是,实现这一点可能很棘手,所以只有在真正需要"实时"重新绘制组件时才应该这样做.作为替代方案,paintImmediately(...)可以使用,但您必须在事件调度线程中执行所有处理,如下所示:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
while(notDone) {
// Do your processing
panel.paintImmediately(...);
}
}
});
Run Code Online (Sandbox Code Playgroud)
请注意,这将停止任何事件处理,包括在循环运行时处理鼠标和键盘输入.您可以在"Swing中的并发"中阅读有关Swing和Threading的更多信息
| 归档时间: |
|
| 查看次数: |
15809 次 |
| 最近记录: |