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

时间:2014-04-18 18:23:49

标签: java multithreading swing netbeans

我正在编写一个程序来绘制一条在屏幕上移动的火车。我正在使用带有fillRect,drawOval和draw lines方法的图形类。我有一个按钮,可以在屏幕的右侧启动火车。在屏幕消失后,它应该随机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());
 }

3 个答案:

答案 0 :(得分:3)

您正在事件调度线程上执行Thread.sleep(),使GUI在整个调用期间冻结。

延迟在GUI上执行操作的正确方法是使用Swing Timer安排它。

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

不幸的是,当您使用 Swing (以及几乎每个UI框架)时,您无法像在UI线程中那样进行睡眠(也称为事件调度线程),因为,它真的是这个管理整个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();
}