2013-02-26 49 views
0

我已經使用了一個TimerTask來添加一個定時器在我的一個類被paint組件類調用的循環上。基本上已經在頁面上繪製了白色圓圈,然後是一個for循環,它從數組中讀取一個值,根據值的範圍,圓圈將改變顏色。每個圓應表示數組中的下一個值。但它不起作用。我是一個基本的程序員,真的不明白髮生了什麼問題。如果有人能幫我一把,我會很感激。這裏是我到目前爲止的代碼:TImerTask on paintComponent

public DoThePaint() { 



    String fileName; 
    fileName = "/Users/Desktop/test2.txt"; 
    read = new Reader(fileName); 
    read.displayArrayList(); 

    panel = new JPanel(); 
    newImage = new ImageIcon(this.getClass().getResource("resource/background2T.png")).getImage(); 

    circlesT = new ArrayList<Shape>(); 
    circlesT.add(new Ellipse2D.Float(197.0f, 352.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(247.0f, 307.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(152.0f, 303.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(172.0f, 372.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(223.0f, 378.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(273.0f, 285.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(130.0f, 281.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(148.0f, 393.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(246.0f, 403.0f, 10.0f, 10.0f)); 
    circlesT.add(new Ellipse2D.Float(297.0f, 264.0f, 10.0f, 10.0f)); 
} 
public void paintComponent(Graphics g) { 

    drawShapes(g, circlesT); 

} 

public void drawShapes(Graphics g, final ArrayList<Shape> circlesT) { 
    final Graphics2D ga = (Graphics2D) g; 
    ga.drawImage(newImage, 0, 0, null); 



    for (int i = 0; i < circlesT.size(); i++) { 
     ga.draw(circlesT.get(i)); 
     ga.setPaint(Color.white); 
     ga.fill(circlesT.get(i)); 
    } 



    Timer timer = new Timer(); 
    TimerTask t; 
    t = new TimerTask() { 
     @Override 
     public void run() { 

      for (int i = 0; i < 10; i++) { 


       if (read.temp.get(i) < 31 && read.temp.get(i) > 30) { 
        ga.draw(circlesT.get(i)); 
        ga.setPaint(Color.green); 
        ga.fill(circlesT.get(i)); 
       } else if (read.temp.get(i) < 32 && read.temp.get(i) > 31) { 
        ga.draw(circlesT.get(i)); 
        ga.setPaint(Color.red); 
        ga.fill(circlesT.get(i)); 
       } else if (read.temp.get(i) < 33 && read.temp.get(i) > 32) { 
        ga.draw(circlesT.get(i)); 
        ga.setPaint(Color.yellow); 
        ga.fill(circlesT.get(i)); 
       } 

      } 
     } 
    }; 
    repaint(); 
    timer.schedule(t, 0, 5000); 

} 
+0

對不起,但沒有人會爲你調試你的代碼。你知道如何調試嗎?我建議你嘗試一下,然後發佈更多信息,如果你仍然堅持。 – Mick 2013-02-26 12:33:33

+0

它不是它不工作。塗漆的物品似乎閃爍,然後在一段時間後全部消失。所以什麼都不會畫......真的很困惑,因爲我在做什麼錯誤 – user1961019 2013-02-26 13:32:03

+0

a)不要把任何邏輯放入繪畫方法b)永遠不要在繪畫循環中添加調用重繪 – kleopatra 2013-02-26 13:35:09

回答

4

抱歉,但是這是你做恐怖大廳:內paintComponent()你正在創建一個new Timer,一個new TimerTask,並最終調用repaint()

  1. paintComponent():你應該做的是噴漆作業(繪製圖像,填充圓,畫線,畫文本,...在Graphics)。這就是你應該做的。
  2. 調用repaint()最終會觸發paintComponent()被再次調用 - >重新創建計時器,計時器任務和調用repaint() - > paintComponent() - > repaint() - > ...你得到了點,你剛剛創建了一個無限循環吃掉你的資源
  3. 我不知道你的Reader類做了什麼,它保存了什麼數據。我可以看到兩件事我會改變:temp應該是private,並且可以用getter或其他訪問方法正確訪問。你的循環中的條件是非常嚴格的,你確定所有的值都符合三個條件之一(順便說一下,如果read.temp.get(i)返回intInteger,你的條件都是false)。
  4. 要解決所有這些問題,請放下Timer,放下TimerTask並在第一個for-loop直接查找圓圈的顏色並立即正確繪製它們。如果在某一時刻,你想更新顯示器,那麼你可以撥打repaint()
  5. 順便說一句,你的TimerTask沒有運行在EDT(事件調度線程)上,但你仍然可以訪問其中的UI相關的東西。這違反了所有的用戶界面相關的任務應在EDT(採用搖擺TimerSwingUtilities.invokeLater()
  6. 在你TimerTask訪問Graphics2D ga這是同由paintComponent()提供的Graphics g執行的事實:你不能訪問Graphics對象之外paintComponent方法的範圍。 Graphics是創建和處置的,因此不應在其範圍之外使用。一般來說,你絕對不應該保留對Graphics對象的引用(也不要使用可能誘惑的方法getGraphics(),但它可能是所有類型頭痛的源頭)。
1

您對於Swing中繪畫的工作原理有一個根本性的誤解。沒有什麼大不了的,每個人都必須從某個地方開始。

它看起來像你想做動畫。在那導致你的paintComponent方法應該在特定的時間點繪製你的對象的狀態。任何控制油漆時間的定時器都應該在另一個類中。

對於簡單的動畫TimerTask就好了。如果您想要爲遊戲製作動畫或需要良好性能,我建議您使用Andrew Davison編寫的Java Killer Game Programming Java書中的第2章中的動畫類。實際上,您可以在Look Inside功能中閱讀Amazon的第2章。

+0

感謝您的回覆。我的繪畫對象已經繪製在某個位置。如果我沒有計時器,所有的圓圈根據進來的數值同時改變顏色。所有我想要做的就是逐個改變圓圈的顏色。所以用戶可以直觀地看到發生的變化。 – user1961019 2013-02-26 20:55:37

+0

你介意,如果你告訴我代碼明智的把計時器task.for例如顯示它應該看起來相比,我的代碼給予above.im真的很困惑的一些反饋,雖然我很欣賞它..這是星期五到期,我真的陷入了困境。 – user1961019 2013-02-27 16:26:12