2012-12-28 57 views
4

我不知道我怎麼會線程下面的代碼,或只是一個方法一般:線程油漆方法

public void run(){ 

    public void paint(Graphics g) { 
     g.fillRect(20, 20, 20, 20); 
     for (int i = 20; i < 1000; i++) { 
      g.fillRect(20, i, 20, 20); 
      Thread.sleep(10); 
     } 
    } 
} 

我發現,我不能讓這個代碼的線程,因爲我得到一個非法表達錯誤的開始,這是公平的,但我沒有看到它的方式。

+0

不允許您做GUI線程的畫外。您不能將繪圖重定向到輔助線程。 – MTilsted

回答

13

它很難告訴你在做什麼,

,但好像你正試圖從它的run()方法內重寫Runnablepaint()

這肯定無法做到的。

的邏輯是

  • 以一個組件
  • 覆蓋其paint方法繪製我們需要的
  • 調用方法來更新矩形的座標(或在這種情況下,計時器會做到這一點)
  • 比在組件上調用repaint()可以再次調用paint方法,並用它的新座標重新繪製矩形(在更改矩形座標後,Timer還會照顧重新繪製)
  • 重複過去的2個步驟,根據需要多次/想

(當我說組件其實我的意思是JPanelpaint方法是指覆蓋的JPanelpaintComponent(..),因爲這是最好的做法。)

幾點建議:

1)不要覆蓋paint而使用JPanel並覆蓋paintComponent

2)不要忘記兌現油漆鏈和呼叫super.XXX執行重寫paintComponent(Graphics g)(或爲任何事實重寫的方法),除非故意留出來。即

class MyPanel extends JPanel { 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     //do drawings here 
    } 
} 

3)如果在paintComponent繪製它通常需要覆蓋getPreferredSize()並返回Dimension S的適應內容的JPanel /附圖中,即:

class MyPanel extends JPanel { 
    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(300,300); 
    } 
} 

3)看Swing Timer代替Thread.sleep(..)作爲sleep將阻止GUI線程,並使其似乎被凍結。即

Timer t = new Timer(10, new AbstractAction() { 
    int count = 20; 
    @Override 
    public void actionPerformed(ActionEvent ae) { 
     if (count < 1000) { 
      //increment rectangles y position 
      //now repaint container so we can see changes in co-ordinates (unless you have a timer which repaints for you too) 
      count++; 
     } else {//counter is at 1000 stop the timer 
      ((Timer) ae.getSource()).stop(); 
     } 
    } 
}); 
t.start(); 

4)的替代(因爲我看到現在你只移動一個Rectangle這不是一個Swing組件),以搖擺定時器TimerTask,並且這可以使用,只要沒有Swing組件將從run()方法中創建/操作(因爲TimerTask不像EDT Swing Timer那樣在EDT上運行)。注意revalidate()repaint()線程安全所以它可以在TimerTask內使用。

上面是不必要的代碼的優點被保持EDT的(即通過改變共ORDS移動AWT矩形)即

final TimerTask tt = new TimerTask() { 
     @Override 
     public void run() { 
      if (count < 1000) { 
       //increment rectangles y position 
       //now repaint container so we can see changes in co-ordinates (unless you have a timer which repaints for you too) 
      count++; 
      } else {//counter is at 1000 stop the timer 
       cancel(); 
      } 
     } 
    }; 

    new Timer().scheduleAtFixedRate(tt, 0, 10);//start in 0milis and call run every 10 milis 
+0

@NickHaughton也看到這個類似的答案,它使用一個單一的擺動計時器,以移動一個球,然後重新繪製其容器重新考慮更改:http://stackoverflow.com/questions/14068472/java-mouselistener-action-event-in-的paintComponent/14070147#14070147 –