2013-09-25 41 views
0

我有一個簡單的JAVA程序,它只是增加int變量並在JLabel中顯示它的值。 我創建一個新的線程適當的(線程安全的)通過調用其內部EventQueue.invokeLater()與運行的類更新的JLabel其運行方法簡單地做EventQueue的緩慢工作

EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      label.setText("" + number); 
     } 
    }); 

當我運行程序,符合市場預期標籤的數量開始增長迅速從1到大約5000,但隨後開始減速,我開始看到像100255,173735和235678這樣的標籤更新,以及它們之間的阻塞GUI的大停頓。 但是,當我編譯時不使用EventQueue.invokeLater(),直接調用label.setText("" + number);一切工作正常和完美,我可以看到我的標籤每個數字如何變化非常快。但我當然意識到在這種情況下,我的方法不是線程安全的。

有什麼問題?在我看來,EventQueue工作緩慢或什麼的。

回答

3

可能是事件隊列被阻塞了。您可能需要考慮合併事件以刪除多餘的條目,這是因爲當您將事件排隊時,它們可能會比排出和執行動作更快。

每次將事件添加到隊列時,都會查詢現有事件以查看他們是否將新事件與自己合併。隨着隊列的備份,越來越多的事件必須被查詢,並且系統逐漸落後。這對於鼠標事件很有用,但是在這種簡單的(和人爲的)情況下,它可能是有害的。

話雖如此,我隱約記得,GUI代碼已經過優化,不會嘗試合併不會覆蓋適當方法的事件,因此您的問題可能只是一個簡單的積壓。

您可以直接調用setText而不是直接調用setText,您可以創建一個自定義事件來設置組件上的文本,實現它的合併並使用它,以便在任何給定時間只有最近的文本處於待處理狀態。如果你這樣做,你想根據以前設置的內容設置文本,最好保留該值,並始終設置GUI小部件,而不是通過getText回想GUI小部件的當前值。否則合併要困難得多。

+0

感謝您的回答!但是,通過合併事件,你的意思是什麼?事件label.setText(「hello」)和label.setText(「goodbye」)被認爲是一樣的嗎?而且我仍然不明白爲什麼在開始時似乎都沒問題,但隨後情況變得更糟,儘管所有過程在開始時都非常相似。只需增加,排隊,更新標籤。 –

+0

如果EventQueue包含太多項目,它可以緩慢工作嗎?有什麼方法可以檢查EventQueue是否包含任何項目? –

+0

合併setText事件與保留給定組件的最近期一樣簡單(IOW,setText總是替換同一組件的未決setText),因爲文本完全替代了之前的內容。 –