2016-11-26 75 views
0

我做了一个简单的Java程序,它使用一个Thread对象在JPanel周围移动一个正方形。正方形移动到一个随机位置,改变它的颜色,并且JPanel改变它的背景颜色。然后线程睡了1000毫秒。但后来我又添加了一行代码,它为JLabel添加了+1,并且广场停止移动(同时分数正在工作并添加+1)。线程运行不正常

下面是代码:

@Override 
public void run() { 

    Random random = new Random(); 

    int width = 0; 
    int height = 0; 

    while(true) { 

     width = random.nextInt(area.getSize().width) + 1; 
     height = random.nextInt(area.getSize().height) + 1; 

     width -= ((width - 45) > 0) ? 45 : 0; 
     height -= ((height - 45) > 0) ? 45 : 0; 

     this.square.setLocation(width, height); 
     this.square.setIcon(new ImageIcon(getClass().getResource("/img/square" + (random.nextInt(4) + 1) + ".png"))); 
     this.area.setBackground(new Color(random.nextInt(255) + 1, random.nextInt(255) + 1, random.nextInt(255) + 1)); 

     //The following line works, but the setLocation method stops working. 

     this.score.setText(Integer.toString(Integer.parseInt(this.score.getText()) + 1)); 

     try { 

      sleep(1000); 

     } catch (InterruptedException ex) { 

      Logger.getLogger(RunThread.class.getName()).log(Level.SEVERE, null, ex); 

     } 

    } 

} 

任何想法?

谢谢。

编辑:这是我如何创建一个线程...

public Click() { 

    initComponents(); 
    pack(); 
    setLocationRelativeTo(null); 
    setVisible(true); 

    RunThread run = new RunThread(jLabel1, jLabel2, jPanel1); 
    run.run(); 

} 
+0

也许线程挤破头? –

+1

从哪里开始线程?那是你真的启动一个Thread还是只调用run()方法?发布一个证明问题的适当的[mcve]。 – camickr

+0

最初如何设定'this.score'的文字?除非将其设置为包含整数的字符串,否则'Integer.parseInt'将失败。 –

回答

5

调用run()方法中

哪项是错误的。那不是如何使用Thread。如果您调用run()方法,那么它就像其他任何方法一样对待,并且您没有使用Thread。因此,无论何时使用Thread.Sleep(...),都会导致Event Dispatch Thread(EDT)进入睡眠状态,这意味着GUI无法重新绘制自身。要使用Thread。你需要调用start()方法上Thead,所以代码应该是:

run.start(); 
+0

您还应该注意,修改事件派发线程之外的Swing组件是一种非常糟糕的做法。这样你会得到绘画错误和其他可怕的东西。如果您需要进行繁重的计算或处理,则可以使用单独的线程,但在修改摆动组件时,您必须使用SwingUtilities.invokeLater() –

+0

谢谢您对camickr的解释。现在工作得很好! –