【问题标题】:Doing Live/Dynamic changes in Swing在 Swing 中进行实时/动态更改
【发布时间】:2011-12-29 16:20:59
【问题描述】:

我正在制作一个游戏,其中包含正方形(面板网格),当游戏结束时,有一种算法会以“实时”方式逐个更改面板的颜色,用户可以看到正方形的变化慢慢上色。我尝试类似:

Thread.sleep(1000);      

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

Thread.sleep(1000); 

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

虽然盒子的颜色变成了黄色,但之后它并没有变成橙色。有人有想法么?希望我能说清楚。

【问题讨论】:

  • 你试过打电话给invalidate吗?
  • 不,不太了解。我对 Swing 有点陌生。会试一试。谢谢。编辑:我只是看了看,我不确定这对我有什么帮助=/
  • 无需调用 invalidate()。 Swing 组件会自动重绘自己。

标签: java swing concurrency windowbuilder


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    这些需要发生在 Swing 事件线程上。调用设置背景通过:

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

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

    查看专门用于此类事情的Swing Timing Framework 也是谨慎的做法。

    【讨论】:

      【解决方案3】:

      -通常在 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();
      

      【讨论】:

      • +1 Timer 是一个潜在的解决方案(但不是最好的,因为现在逻辑分布在两个类中)。 -1,不需要 revalidate(),因为组件的大小不会改变,并且不需要 repaint(),因为 Swing 组件足够聪明,可以重新绘制自己。
      猜你喜欢
      • 1970-01-01
      • 2018-05-28
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 2012-03-21
      相关资源
      最近更新 更多