我有这样的代码:
// 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
该方法有效,但有时它是盲目的,所以我不想使用它。有人可以给我一些建议吗?谢谢!
如果您repaint
仔细阅读的文档,您会注意到它指出(强调我的意思):
如果此组件是轻量级组件,则此方法将导致尽快调用此组件的paint方法。否则,此方法将导致 尽快 调用此组件的update方法。
这意味着允许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(...);
}
}
});
请注意,这将在循环运行时停止任何事件处理(包括鼠标和键盘输入)的处理。您可以在“
Swing的并发性”中阅读有关Swing和线程的更多信息。
我想问一下,为什么在执行事件时,我的状态没有改变。我已经搜索到需要在构造函数中绑定函数,但是状态仍然没有更新。 下面是我的代码:
问题内容: 我想问为什么在执行onclick事件时状态没有变化。我已经搜索了一段时间,我需要在构造函数中绑定onclick函数,但状态仍未更新。这是我的代码: 问题答案: 这个回调真的很混乱。只需使用async await代替:
问题内容: 我想问一下为什么在执行onclick事件时状态没有变化。我已经搜索了一段时间,我需要在构造函数中绑定onclick函数,但状态仍未更新。这是我的代码: 问题答案: 幸运的是, setState进行了回调。这是我们获取更新状态的地方。考虑这个例子。 因此,当回调触发时,this.state是更新后的状态。你可以在回调中获取突变/更新的数据。
问题内容: 在一个简短的方法中,我使用setVisible(false)隐藏了一个JFrame。然后,截屏并使用setVisible(true)还原JFrame。 在再次显示之后,窗口应该显示与以前不同的图片(可以说是截图的一部分)。 问题是,在调用setVisible(true)之后,将窗口与旧内容一起闪烁一秒钟,然后再调用paintComponent并绘制更新的状态。 我可能会以丑陋的方式解决
在试图制作一个非常简单的子弹地狱游戏来学习java时,我遇到了一个障碍: repaint()没有调用油漆组件()。 这是整个程序,目前只需将我每秒创建50次的图像绘制到JFrame上的JPanel上。 在使用断点和println方法进行了一些调试之后,我可以确认正在读取正确的图像,gameTimerAction中的计时器每秒被调用50次,并且repaint()根本没有调用paintComponen
我有一些动画,我试图转换为约束。它背后的想法是当出现错误时登录提示会反弹。 我的方法是,视图控制器上的所有内容都在bounceView中,而bounceView本身也在主视图中。 BounceView使用居中约束和前导空间约束绑定到主视图。为了使布局在设计时明确无误,还有一个前导空间和顶部空间约束。不过,这些只是占位符,在运行时被等高/宽约束替换。 没有其他约束与主视图相关联。 现在,一些细节…