在Swing中进行实时/动态更改

时间:2011-12-29 16:20:59

标签: java swing concurrency windowbuilder

我正在制作一个有正方形的游戏(面板网格),当游戏结束时,会有一种算法,以“实时”方式逐个改变面板的颜色,用户观看正方形变化颜色慢慢。我试着像:

Thread.sleep(1000);      

grid.getComponent(boxNumber).setBackground(Color.YELLOW);

Thread.sleep(1000); 

grid.getComponent(boxNumber).setBackground(Color.ORANGE);

虽然方框的颜色变为黄色,但之后不会变为橙色。有人有主意吗?希望我能够清楚。

3 个答案:

答案 0 :(得分:2)

阅读Concurrency上的Swing教程中的部分,了解为什么不应该使用sleep()方法。

一种解决方案是使用SwingWorker,然后您可以“发布”组件的颜色,以便在EDT上正确更新它,您也可以在worker中调用sleep()方法。

答案 1 :(得分:1)

这些需要在Swing事件线程上发生。通过以下方式调用集背景:

SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    grid.getComponent(boxNumber).setBackground(Color.ORANGE);
  }
});

请注意,您的Thread.sleep() 应位于事件线程中(或直接来自Swing事件侦听器(ActionListener,WindowListener等)。

Swing Timing Framework专门用于此类事情也是明智的。

答案 2 :(得分:1)

- 一般来说,在EDT中做Thread.sleep(1000);并不是一个好主意。您应该尝试使用Timers - 之后你还需要致电revalidate()/validate() and 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();