Java 在Swing中进行实时/动态更改
我正在制作一个有方块的游戏(一个格子的面板),当游戏结束时,会有一个算法以“实时”的方式一个接一个地改变面板的颜色,用户会看到方块慢慢地改变颜色。我试着做如下事情:Java 在Swing中进行实时/动态更改,java,swing,concurrency,windowbuilder,Java,Swing,Concurrency,Windowbuilder,我正在制作一个有方块的游戏(一个格子的面板),当游戏结束时,会有一个算法以“实时”的方式一个接一个地改变面板的颜色,用户会看到方块慢慢地改变颜色。我试着做如下事情: Thread.sleep(1000); grid.getComponent(boxNumber).setBackground(Color.YELLOW); Thread.sleep(1000); grid.getComponent(boxNumber).setBackground(Color.ORANGE);
Thread.sleep(1000);
grid.getComponent(boxNumber).setBackground(Color.YELLOW);
Thread.sleep(1000);
grid.getComponent(boxNumber).setBackground(Color.ORANGE);
虽然长方体的颜色会变为黄色,但之后不会变为橙色。有人有什么想法吗?希望我能说清楚。这些需要在Swing事件线程上发生。呼叫设置后台通过:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
grid.getComponent(boxNumber).setBackground(Color.ORANGE);
}
});
注意,您的Thread.sleep()
不应位于事件线程中(或直接位于Swing事件侦听器(ActionListener、WindowListener等)中)
谨慎的做法是查看特定于此类事件的。这些事件需要在Swing事件线程上发生。通过以下方式调用set background:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
grid.getComponent(boxNumber).setBackground(Color.ORANGE);
}
});
注意,您的Thread.sleep()
不应位于事件线程中(或直接位于Swing事件侦听器(ActionListener、WindowListener等)中)
另外,请谨慎地查看专门用于此类操作的方法。阅读Swing教程中关于的部分,了解不应使用sleep()方法的原因
一种解决方案是使用SwingWorker,然后您可以“发布”组件的颜色,以便在EDT上正确更新,还可以在worker中调用sleep()方法。阅读Swing教程中关于的部分,了解为什么不应该使用sleep()方法
一种解决方案是使用SwingWorker,然后您可以“发布”组件的颜色,以便在EDT上正确更新组件,还可以在worker中调用sleep()方法。-通常在EDT中执行
Thread.sleep(1000);
。您应该尝试使用。-之后还需要调用
revalidate()/validate()和repaint()
所以可能是这样的:
Timer yellowTimer = new Timer(1000,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jtp.setBackground(Color.YELLOW);
//call revalidate()/validate() and repaint() afterward
jtp.revalidate();
jtp.repaint();
}
});
yellowTimer.setRepeats(false);
Timer orangeTimer = new Timer(2000,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jtp.setBackground(Color.ORANGE);
//call revalidate()/validate() and repaint() afterward
jtp.revalidate();
jtp.repaint();
}
});
orangeTimer.setRepeats(false);
yellowTimer.start();
orangeTimer.start();
-通常在EDT中执行
线程睡眠(1000);
不是一个好主意。您应该尝试使用。-之后还需要调用
revalidate()/validate()和repaint()
所以可能是这样的:
Timer yellowTimer = new Timer(1000,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jtp.setBackground(Color.YELLOW);
//call revalidate()/validate() and repaint() afterward
jtp.revalidate();
jtp.repaint();
}
});
yellowTimer.setRepeats(false);
Timer orangeTimer = new Timer(2000,new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jtp.setBackground(Color.ORANGE);
//call revalidate()/validate() and repaint() afterward
jtp.revalidate();
jtp.repaint();
}
});
orangeTimer.setRepeats(false);
yellowTimer.start();
orangeTimer.start();
你试过调用
invalidate
?不,不太了解它。我是Swing的新手。我会尝试一下。谢谢。编辑:我只是看了一下,我不确定这对我有什么帮助=/没有必要调用invalidate().Swing组件将自动重新绘制。您是否尝试调用invalidate
.Swing组件将自动重新绘制自己。+1定时器是一个潜在的解决方案(但不是最好的,因为现在逻辑分布在两个类中)。-1,不需要重新验证(),因为组件的大小不会更改,并且重新绘制()不需要,因为Swing组件足够聪明,可以自己重新绘制。+1定时器是一个潜在的解决方案(但不是最好的,因为现在逻辑分布在两个类中)。-1,不需要重新验证(),因为组件的大小不会改变,也不需要重新绘制(),因为Swing组件足够聪明,可以自己重新绘制。