我用Netbeans的可視化編輯器構建了一個表單。當我按下一個按鈕,應該做到以下幾點:它擺動按鈕不會立即反應!我該如何改變它?
- 設置爲禁用
- 當任務完成後該按鈕將再次啓用
然而,發生以下情況:
- 按鈕仍處於按下狀態,直到任務完成
- 當任務完成後,按鈕的啓用/禁用會非常快(它們會發生,但你不會注意到他們)
這種行爲是不是我想要的。我嘗試在JButton上,JFrame上,甚至在包含按鈕的JPanel上使用重繪,但我似乎無法讓它做我想做的事。一些提示?
我用Netbeans的可視化編輯器構建了一個表單。當我按下一個按鈕,應該做到以下幾點:它擺動按鈕不會立即反應!我該如何改變它?
然而,發生以下情況:
這種行爲是不是我想要的。我嘗試在JButton上,JFrame上,甚至在包含按鈕的JPanel上使用重繪,但我似乎無法讓它做我想做的事。一些提示?
當你在按鈕回調中工作時,你正在拖延GUI繪製線程直到它完成。
你需要做的是產生一個線程來執行長時間運行的任務,然後讓該線程使用SwingUtilities.invokeLater()
在完成時更新UI。不使用invokeLater
不是線程安全的,並且通常是不好的mojo。
一個基本的例子是:
button.setEnabled(false);
new Thread(new Runnable() {
public void run() {
// Do heavy lifting here
SwingUtilies.invokeLater(new Runnable() {
public void run() {
button.setEnabled(true);
}
});
}
}).start();
當你在按鈕回調中做事情時,你基本上停止了gui繪畫線程 - 不僅僅是按鈕,而是任何gui繪畫。 (嘗試覆蓋另一個窗口的界面,然後再次暴露它 - 它不會重畫,直到任務完成!)
你需要做的是產生一個線程做長時間運行的任務,然後讓線程使用SwingUtilities.invokeLater()來啓用按鈕。 invokeLater強制按鈕啓用發生在gui繪畫線程中。
在長時間運行的線程運行時,您可能需要設置佔線遊標或以其他方式鎖定接口。
您需要完成在不同線程中需要一些時間的任務。
按鈕被阻塞的原因是因爲工作是在繪製按鈕的同一個線程中完成的。一旦工作完成,該按鈕可以完成您告訴它的其餘部分。
如果使用不同的線程,線程將執行該任務,而繪圖代碼可以繼續繪製表單。
Sun的Concurrency in Swing tutorial是非常值得一讀。優秀的解釋和背景閱讀,包括事件調度線程,使用工作線程等
太糟糕了,我們無法合併答案。 – 2009-01-07 21:51:39
@Allain,重要的是確保接受的答案和我們能做到的一樣好。 – 2009-01-08 01:00:41