2016-11-26 96 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的解釋。現在工作得很好! –