Java,thread.sleep()阻止按钮的使用(无法识别按钮点击)



我正在编写一个程序,绘制一列在屏幕上移动的火车。我将图形类与fillRect、drawOval和draw line方法一起使用。我在屏幕的右手边有一个启动火车的按钮。在从屏幕上消失后,它应该以随机的y位置重新出现并再次运行。这应该循环,直到单击停止按钮。问题是我使用thread.sleep()方法在程序更新列车位置之前暂停程序。由于某种原因,我无法在程序运行时单击任何按钮。关于如何让我的停止按钮工作,有什么想法吗?谢谢

这是我正在使用的代码。它还有JFrame表单在netbeans中的普通代码。

private void btnStartTrainActionPerformed(java.awt.event.ActionEvent evt) {                                              
    run = true;
    while (run) {
    Graphics g = jPanel1.getGraphics(); 
    int x =0;
    int y = (int)(Math.random() *500) + 20;
    int smoke =1;
    for( x = 900; x > -600; x--)
    {
        drawTrain(g, x, y, smoke);        
    try {
          Thread.sleep(17);
        } 
catch (InterruptedException e) 
    {
             e.printStackTrace();
    }
    clearJFrame(g);
    smoke++;
    x = x-4; 
    }
    if (x == -599)
    {
        x = 900;
        y = (int)(Math.random() *500) + 20;
    }
    }
    }                                             
    private void btnStopTrainActionPerformed(java.awt.event.ActionEvent evt) {                                             
    run = false;
    } 
public void drawTrain(Graphics g, int x, int y, int smoke)
{
         // draw locomotive
    g.setColor(Color.RED);
    g.fillRect(x, y, 100, 30); 
    g.fillRect(x +100, y-30, 40, 60); 
    g.setColor(Color.BLACK);
    g.fillRect(x +110, y-20, 20, 10);
    g.drawLine(x +10, y, x, y-20); 
    g.drawLine(x +11, y, x, y-20);
    g.drawLine(x, y-20, x +30, y-20);
    g.drawLine(x +30, y-20, x +20, y);
    g.drawLine(x +31, y-20, x +20, y);
    g.drawLine(x, y+30, x-20, y+25);
    g.drawLine(x-20, y+25, x-20, y+20); 
    g.drawLine(x-20, y+20, x, y+15); 
    g.drawOval(x +10, y+20, 25, 25); //draw wheels
    g.drawOval(x +35, y+20, 25, 25);
    g.drawOval(x +60, y+20, 25, 25);
    g.drawOval(x +85, y+20, 25, 25);
    g.drawOval(x +110, y+20, 25, 25);
    if (smoke >20) 
        g.drawOval(x +8, y-33, 12, 12); // draw smoke
    if (smoke >40) 
        g.drawOval(x +12, y-53, 12, 12);
    if (smoke >60)
        g.drawOval(x +18, y-73, 13, 13);
    if (smoke >80)
        g.drawOval(x +25, y-100, 14, 14);
    if(smoke >100)
        g.drawOval(x+31, y-120, 15, 15);
    if (smoke > 120)
        g.drawOval(x+37, y - 140, 16, 16);
    if (smoke > 140)
        g.drawOval(x+44, y-160, 17, 17);
    g.setColor(Color.RED);
    g.fillRect(x +160, y, 80, 30);      // draw additional cars
    g.fillRect(x +260, y, 80, 30);
    g.fillRect(x +360, y, 80, 30);
    g.setColor(Color.BLACK);
    g.drawOval(x +160, y+20, 25, 25); 
    g.drawOval(x +215, y+20, 25, 25);
    g.drawOval(x +260, y+20, 25, 25);
    g.drawOval(x +315, y+20, 25, 25);
    g.drawOval(x +360, y+20, 25, 25);
    g.drawOval(x +415, y+20, 25, 25);

 }
 public void clearJFrame(Graphics g)
 {
     g.setColor(jPanel1.getBackground());
     g.fillRect(0, 0, jPanel1.getWidth(), jPanel1.getHeight());
 }

您正在事件调度线程上执行Thread.sleep(),使GUI在该调用的整个持续时间内冻结。

延迟在GUI上执行操作的正确方法是使用Swing Timer对其进行调度。

当Swing程序需要执行长时间运行的任务时,您需要使用SwingWorker。事件调度线程上的阻塞将冻结您的GUI。

阅读oracle的这两个教程,你就会知道你应该做什么:

  • http://docs.oracle.com/javase/tutorial/uiswing/concurrency/simple.html
  • http://docs.oracle.com/javase/tutorial/uiswing/concurrency/interim.html

不幸的是,当您使用Swing(以及几乎所有的UI框架)时,您无法在UI线程(也称为Event Dispatch线程)中进行睡眠,因为实际上是这个线程管理整个UI。因此,通过睡眠,它在整个睡眠时间内变得没有反应是正常的。

您应该做的是从btnStartTrainActionPerformed启动另一个线程,并在该线程中进行睡眠。

类似于:

private void btnStartTrainActionPerformed(java.awt.event.ActionEvent evt) {
    Thread thread = new Thread() {
      public void run()
      {
        run = true;
        while (run)
        {
            Graphics g = jPanel1.getGraphics(); 
            int x =0;
            int y = (int)(Math.random() *500) + 20;
            int smoke =1;
            for( x = 900; x > -600; x--)
            {
            // Needed to make this change back on the UI Thread
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        drawTrain(g, x, y, smoke);        
                }
            });
            try
            {
                Thread.sleep(17);
            } 
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
            clearJFrame(g);
            smoke++;
            x = x-4; 
        }
        if (x == -599)
        {
            x = 900;
            y = (int)(Math.random() *500) + 20;
        }
      }
     }
    };
    thread.start();
}

相关内容

  • 没有找到相关文章

最新更新