2010-11-22 33 views
4

我試了很多,但似乎無法讓它工作。如何更新線程內的JFrame標籤? - Java

我被告知使用EDT與下面的例子。

SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      // Modify the GUI here 
     } 
}); 

我已閱讀了這個話題很多,仍然不明白。我得到了一個線程,但.invokeLater對我仍然沒有任何意義。老實說,如果你可以詳細解釋這將是一個很大的幫助!

程序目標:獲取每秒不斷創建的隨機生成的密鑰,以便在GUI中隨後進行更新。

+1

除了@John V.的回答下面,你可能想要閱讀這篇文章:[Threads and Swing](http://java.sun.com/products/jfc/tsc/articles/threads/threads1 .html) – casablanca 2010-11-22 21:37:50

回答

3

所以有一個EDT(事件調度線程)。出現在屏幕上的所有操作都由EDT執行。每個鞦韆應用只有一個EDT。

你在一些任意線程,你想通過該線程更新QUI?就像我說的那樣,每個搖擺應用程序只有一個EDT,所以你必須告訴EDT顯示標籤(或任何你想要的上下文)。

這裏的想法是,你把這個Runnable推到一個美國東部時間從一個隊列中拉出來。最終,您的可運行應用程序將在EDT執行之前執行所有其他操作。

0

如果你所要做的是按照已知的時間表更新UI,請嘗試如下所示。這假定JFrame是您希望每隔1秒更新一次的組件。

private static final int WAIT_LENGTH = 1000; // 1 second 
private JFrame frame = new JFrame(); 

// Thread will update the UI (via updateUI() call) about every 1 second 
class UIUpdater extends Thread { 
    @Override 
    void run() { 
    while (true) { 
     try { 
     // Update variables here 
     } 
     catch (Exception e) { 
     System.out.println("Error: " + e); 
     } 
     finally { 
     frame.repaint(); 
     Thread.sleep(WAIT_LENGTH); 
     } 
    } 
    } 
} 

要啓動這個線程:

UIUpdater t = new UIUpdater(); 
t.start(); 
+0

.updateUI();不斷出現一個錯誤,當我嘗試用.setText()更改標籤時;你在哪裏發佈//更新變量在這裏,我總是最終沒有幫助我。所以我認爲,而不是JFrame我需要mainFrame(它擴展了我以前使用的JFrame),所以沒有工作...所以基本上我不知道這是甚至假設讓我更新它。我會讀這本書建議「骯髒的富客戶端」肯定... – Zeveso 2010-11-22 23:26:40

+0

事實證明`component.repaint()`更符合你所尋找的內容。抱歉。我已經更新了我的答案。 – 2010-11-24 20:14:20

1

我建議你買到書Filthy Rich Clients。有一章講解了Swing的線程模型的細節。

基本上在Swing中,任何修改GUI的代碼都應該在Event Dispatcher Thread中執行。您在那裏使用的SwingUtilities類爲您提供了一種將事件發佈到事件隊列的簡便方法,該事件隊列由EDT分派。這就是invokeLater方法所做的,它需要一個new Runnable()作爲最終在EDT上執行的參數。

從書:

中,invokeLater()實現需要 負責創建和排隊一個特殊的 事件包含了Runnable的。這個 事件在EDT上以 的順序進行處理,就像任何 其他事件一樣。當其到達時,通過運行 Runnable的run()方法調度 。

0

這是所有GUI編程中很常見的元素。您有一個線程可以處理繪製GUI,獲取輸入和運行回調。如果另一個線程試圖改變與GUI相關的對象,它將與GUI線程發生衝突。舉個例子,舉個例子,繪製一些東西的方法是一半,然後你改變另一個線程的顏色。

所有的invokeLater都會排隊等待GUI線程運行。通過「稍後」它實際上幾乎立即運行,但當前線程不必等待它。 GUI線程可能正在進行繪製或等待回調,以便延遲執行您提供的代碼。

0

需要成爲會員,所以我們可以改變它,還是從內部類

protected long secret=0; 

使用它......這需要在你的代碼的地方它會得到運行...

JFrame f = new JFrame("foo"); 
new Thread(){ 
     public void run() { 
      for(;;){ 
       try { 
        sleep(1000); 
       } catch Interrupted (Exception ix){ 
        return; 
       } 
       // TODO update your secret key here 
       // please don't use random() 

       SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         f.setTitle("secret "+x); 
        } 
       }); 
      } 
     } 
    }).start(); 

....

,使其正確繪製永遠只更新從EDT搖擺。

當您在EDT(在事件處理程序中運行代碼)時,如果您確實需要,可以調用paintImmediately()。