我有一个以十几秒为单位显示时间的Java程序。每个数字都是一个单独的组件,组件被分组在一个JPanel中,该JPanel位于占据大部分屏幕的JFrame的角落附近。数字由专用线程更新,该线程以100ms wait()循环。当数字改变时,它被重新绘制。
调度似乎正在起作用:以100ms的间隔适当调用repaint()和paint(),但显示只每500ms更新一次。
但是,如果我将鼠标移到JFrame上,或者反复按一个键(控制并移动两个工作),则显示更新更快。
如果我每100毫秒重新绘制JFrame的内容窗格,那么显示会正确更新,但JFrame中的其他所有内容都会被不必要地重新绘制。重新绘制包含时间显示的JFrame部分没有明显效果,但重新绘制JFrame 的大部分区域(不包括时间显示)会更新时间。
我已尝试将数字基于JComponent并调用paintImmediately()(来自事件调度线程),没有明显差异。
解释可能是EDT等待500毫秒超时并且没有被paint()通知。有没有办法可以明确通知EDT测试这个?
我可以通过在一个单独的重量级容器中显示时间来解决这个问题,但我想了解导致这种行为的原因。
这是一个产生此行为的简短程序。 1.7版本的线条始终平稳旋转。使用1.8版本时,它首先会平稳移动,但在两秒钟内它会开始跳跃。请注意,角度在绘制过程中会增加,因此如果要合并涂料,线条仍然会平滑旋转但速度会更慢。
我不相信有必要从美国东部时间调用重画,但我已经尝试了它并没有任何区别。 for 循环不在EDT中运行,因此睡眠不会阻止显示更新。
package bugs;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class DisplayRefresh {
private class Cmpt extends Component {
private static final int POINTS = 16;
int m_ix;
public Cmpt()
{
m_ix = 0;
}
public void paint(Graphics g)
{
Dimension sz = getSize();
int rx = (sz.width - 1) / 2;
int ry = (sz.height - 1) / 2;
Double w = Math.PI * m_ix / POINTS;
int x = (int)Math.floor(Math.sin(w) * rx);
int y = (int)Math.floor(Math.cos(w) * ry);
g.drawLine(rx - x, ry - y, rx + x, ry + y);
m_ix = (m_ix + 1) % POINTS;
}
}
JFrame m_frame;
Cmpt m_cmpt;
public static void main(String[] args) {
(new DisplayRefresh()).exec();
}
private void exec()
{
m_frame = new JFrame();
m_frame.setLayout(null);
m_frame.setSize(600, 600);
m_frame.setVisible(true);
m_cmpt = new Cmpt();
m_cmpt.setSize(64, 64);
m_frame.add(m_cmpt);
m_cmpt.setLocation(500, 100);
if (SwingUtilities.isEventDispatchThread()) {
System.out.println("This is the event dispatch thread");
} else {
System.out.println("This is NOT the event dispatch thread");
}
for (int i = 0; i < 100; i++) {
m_cmpt.repaint(10);
try {
Thread.sleep(100);
} catch(InterruptedException exc) {
System.out.println(exc.toString());
}
}
m_frame.dispose();
System.exit(0);
}
}
答案 0 :(得分:-1)
我刚刚使用Java 1.7.0_80而不是1.8.0_92进行了重新编译,显示现在已经及时更新,问题的答案是&#34;是什么导致了这种行为?&#34;是这个版本的java的特性。
我现在尝试了1.8.0_111版本。这与1.8.0_92具有相同的刷新延迟。