【问题标题】:Using sleep in JPanel在 JPanel 中使用睡眠
【发布时间】:2017-05-05 23:38:35
【问题描述】:

我写了一个简单的java程序在屏幕上放置一些矩形(在彼此之间有一些延迟之后)

package guitest2;
import java.awt.Graphics;
import javax.swing.JPanel;

public class DrawPanel extends JPanel {
    public void paintComponent( Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < 10; i++ ) {
           g.drawRect(10+5*i, 10+5*i, 20, 20);
           try{
              Thread.sleep( 2000 );
           }
           catch (InterruptedException ex) { }
        }
    }
}

我用过那个类

package guitest2;
import javax.swing.JFrame;
public class Guitest2 {
    public static void main(String[] args) {
        DrawPanel panel = new DrawPanel();
        JFrame app = new JFrame();
        app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
        app.add(panel);
        app.setSize(450, 250);
        app.setVisible(true);
    }    
}

运行上述代码的问题是,正方形没有显示出来。 10*2S = 20 秒后,最终面板显示为包含所有方块。我想要的是:

1- 用g.drawRect画一个正方形。

2- 等待 2 秒

3- 删除之前的正方形并绘制新的。

【问题讨论】:

    标签: java jpanel sleep


    【解决方案1】:

    也许你可以使用下面的代码,我用 cmets 稍微修改了你的代码。

        import java.awt.Color;
        import java.awt.Graphics;
        import javax.swing.JPanel;
        import javax.swing.JFrame;
    
        public class RectTest {
         DrawPanel panel;
         int x;
         int y;
         public static void main(String[] args) {
          new RectTest().startApp();
         } 
    
         public void startApp() {
          panel = new DrawPanel();
          JFrame app = new JFrame();
          app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
          //modify this line
          app.getContentPane().add(panel);
          app.setSize(450, 250);
          app.setVisible(true);
          //added for loop here
          for (int i = 0; i < 10; i++ ) {
           // x,y here
           x = 10+5*i;
           y = 10+5*i;
           // repaint the panel
           panel.repaint();
           // wait 2sec
           try{
              Thread.sleep( 2000 );
           }
           catch (InterruptedException ex) { }
        }
       }
    
       class DrawPanel extends JPanel {
        public void paintComponent( Graphics g) {
           //super.paintComponent(g);
           // repaint the backround to see the single reactangles
           g.setColor(Color.white);
           g.fillRect(0, 0, this.getWidth(), this.getHeight());
    
           g.setColor(Color.green);
           g.drawRect(x, y, 20, 20);
        }
       }
      }
    

    【讨论】:

    • 它应该可以按照你的要求工作,我改变了颜色。
    【解决方案2】:

    您正在Event Dispatch Thread (EDT) 上睡觉,从而阻止了所有与 GUI 相关的事件。 GUI 在 EDT 这个线程上运行,因此您不能像那样阻止它(即循环休眠)。

    来自 EDT 链接的相关引用:

    将在事件调度线程上运行的代码视为一系列短任务很有用。 [...]

    事件调度线程上的任务必须快速完成;如果他们不这样做,未处理的事件会备份并且用户界面变得无响应。

    在您的情况下,您正在绘制 10 个矩形,其中一些处于休眠状态。然后处理事件队列的其余部分。这会导致 GUI 卡住 10 x 2000 毫秒,然后绘制完成。

    改为使用Swing Timer 来计时 GUI 相关事件:

    Swing 计时器(javax.swing.Timer 的一个实例)在指定的延迟后触发一个或多个动作事件。 [...]

    [...] 我们建议将 Swing 计时器 [...] 用于与 GUI 相关的任务,因为 Swing 计时器都共享相同的、预先存在的计时器线程,并且与 GUI 相关的任务会在事件调度线程上自动执行.

    【讨论】:

      猜你喜欢
      • 2012-03-01
      • 2012-04-07
      • 2014-12-06
      • 1970-01-01
      • 2010-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多