它很難告訴你在做什麼,
,但好像你正試圖從它的run()
方法內重寫Runnable
的paint()
。
這肯定無法做到的。
的邏輯是
- 以一個組件
- 覆蓋其paint方法繪製我們需要的
- 調用方法來更新矩形的座標(或在這種情況下,計時器會做到這一點)
- 比在組件上調用
repaint()
可以再次調用paint方法,並用它的新座標重新繪製矩形(在更改矩形座標後,Timer還會照顧重新繪製) 個
- 重複過去的2個步驟,根據需要多次/想
(當我說組件其實我的意思是JPanel
,paint方法是指覆蓋的JPanel
paintComponent(..)
,因爲這是最好的做法。)
幾點建議:
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
不允許您做GUI線程的畫外。您不能將繪圖重定向到輔助線程。 – MTilsted