使用EventQueue.invokeLater(例如,從長時間運行的後臺非EDT線程進程生成的輸出)執行更新我的swing GUI不同於用戶單擊的位置的所有處理器。處理長時間運行的JEditorPane setText進程的最佳做法
在我當前的場景中,我有一個TCPIP套接字讀取後臺線程進程,它返回需要更新JEditorPane對象的數據。我使用JEditorPane setText調用。問題是,將setText調用放在invokeLater例程中會凍結大文件的GUI(例如案例測試19,790 KB)。
我試圖解決這個問題是在非EDT後臺線程中執行setText操作。這似乎解決了這個問題,但是,我擔心最佳實踐,因爲Java 7中的JEditorPane setText(我正在使用的JDK)不是線程安全的。但是,在我看來,這裏執行的冗長過程在JDK的DefaultEditorKit.read中,並且在該方法內,唯一會影響GUI的代碼位於doc.insertString調用中(除非我我錯了)。現在,當您查看JDK的PlainDocument.java insertString方法時,它會記錄IT是線程安全的,因此可以認爲此解決方案是合理的。
無論其...
壓力測試我的申請,我周圍的GUI一些隨機點擊,目前有一個樹節點動畫的運行,和下面的大負荷期間,確實出現了動畫放慢有一點,因此我擔心我沒有執行最好的解決方案(也很關心未來的JRE在這裏搞砸我,因此不依賴於當前正在使用線程安全的insertString)。
我已經調查過並看到這個問題「如何處理長時間運行的JEditorPane setText」之前已經被問過,但沒有合適的答案。
問題1)有沒有人對我目前的觀察有想法?
問題2)有沒有人有關於如何實現這個另一個想法?
注意JEditorPane是我唯一的選擇,因爲我最終將支持動態字體的IDE外觀和感覺。
還要注意下面的調用在EventQueue.invokeLater例程中調用,所以最初的editorPane工作在EDT中。
public void updateBigDataEditorPane(final JEditorPane editorPane, final String inStr) {
// Update editor object and content.
editorPane.setContentType("text/plain");
editorPane.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
editorPane.setDocument(editorPane.getEditorKit().createDefaultDocument());
// Content update. NOTE in non-EDT thread to stop GUI freeze with large content.
new Thread(new Runnable() {
@Override
public void run() {
//// synchronized
synchronized(tabsLock) {
// Set content.
editorPane.setText(inStr);
} //// synchronized
}
}).start();
}
使用SwingWorker下載文本並使用它的方法來應用它... – MadProgrammer 2014-09-06 22:04:45
@MadProgrammer SwingWorker將應用與上述相同的原理(並且一旦我建立了上述的正確性,我將把它改爲使用SwingWorker)。也就是說,setText是在後臺完成的,而不是在EDT中完成的(SwingWorker本質上就是這麼做的,對嗎?),那麼EDT中需要的任何後續操作都是在done方法中完成的。我假設這就是你的意思,因爲否則將setText放在SwingWorker done方法中會與我原來的問題代碼具有相同的效果 - 在EDT中執行setText會凍結GUI。思考? – 2014-09-07 18:46:09
否。SwingWoker爲您提供發佈/處理方法,允許您使用EDT同步更新。事實是,您可以簡單地使用done方法,該方法在EDT中也被稱爲更新UI。請記住,Swing通常不是線程安全的。 – MadProgrammer 2014-09-07 21:25:26