2012-01-09 30 views
1

我修改張貼甲骨文/ Sun AWT教程頁上的Activator示例代碼here爲什麼在AWT組件中運行線程循環會阻止WindowHandler執行?

的修改如下

f.add(new MyCanvas(f.getGraphicsConfiguration()), 
      BorderLayout.CENTER); 

在MyCanvas的塗料方法如下

MyCustomRunnable mcr = new MyCustomRunnable(); 
Thread th = new Thread(mcr); 

th.start(); 

while(Thread.currentThread().isAlive()){ 
    mcr.getData(); 
    //do UI stuff 
    Thread.yield(); 
} 
被覆蓋

類似地MyCustomRunnablerun()

具有相應的循環
public void run(){ 
    while(Thread.currentThread().isAlive){ 
     //do Stuff 
     Thread.yield(); 
    } 
} 

Runnable和Canvas paint(都)運行循環。運行這段代碼時,不會調用UI窗口上的系統菜單關閉。爲什麼?

+2

爲什麼在這個千年中使用AWT組件編碼?大多數使用過它的人已經忘記了方法,因此答案也不那麼有價值。 – 2012-01-09 19:58:29

+0

沒有冒犯,但是...因爲它在那裏(+: 這是當我在00年開始學習java時發生的事情,所以當我必須做一些需要UI的東西時,我選擇了相對熟悉的東西開始。 – Everyone 2012-01-09 20:19:55

回答

3

簡短的回答是,paint()在事件線程上調用,它也是處理所有UI事件的線程,並且您正在接管該線程並將其置於無限循環中。

當你在paint方法做這...

while(Thread.currentThread().isAlive()){ 
    ... 
} 

...「當前線程」您正在上相同的線程您輸入了上方法,這就是「事件調度線程「。我猜想你真正想要的是運行後臺線程,定期重新繪製視圖。你可以在你的AWT組件的構造函數做到這一點:

new Thread() { 
    public void run() { 
     while(runBackgroundThread) { 
     mcr.getData(); 
     repaint(); 
     } 
    } 
}.start(); 

請注意,我還創建了一個布爾變量runBackgroundThread這將是在組件類揮發性場。將其設置爲false將停止加載線程。相反,Thread.currentThread().isAlive()總是爲真 - 當前運行的線程必須定義爲活動。

3

0幾乎肯定是因爲你的線程保持了控制權並且不讓窗口事件線程運行。

1

如果您要做的只是等待它完成,那麼啓動後臺線程沒有任何意義。相反,你可以讓後臺線程完成你想要發生的事情。

相關問題