2016-07-08 97 views
-1

我有一個GUI應用程序JTextArea組件。它用於記錄一些信息:JTextArea在Linux上阻塞線程?

import javax.swing.*; 

public class MainWindow { 

    private JTextArea myTextArea; 

    public static void main(String[] args) { 
     new MainWindow(); 
    } 

    public MainWindow() { 
     JFrame mainFrame = new JFrame(); 
     myTextArea = new JTextArea(); 

     mainFrame.setBounds(100,100,100,100); 
     mainFrame.add(myTextArea); 
     mainFrame.setVisible(true); 

     for (int i=0; i< 100; i++) 
      log("Minimal, Complete, Verifable!"); 
    } 

    private void log(String message) { 
     myTextArea.append(message); 
    } 
} 

它可以在Windows 7上正常工作。但是,在Linux上它似乎在幾次調用後掛起整個應用程序。對堆棧的分析顯示GUI線程處於BLOCKED狀態:

"Thread-4" prio=10 tid=0x00007f68e8a63000 nid=0xce7 waiting for monitor entry [0x00007f68f0b40000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at java.awt.Component$AccessibleAWTComponent.getLocationOnScreen(Component.java:9445) 
    - waiting to lock <0x00000007980597e8> (a java.awt.Component$AWTTreeLock) 
    at javax.swing.JComponent$AccessibleJComponent.getLocationOnScreen(JComponent.java:3670) 
    at javax.swing.text.JTextComponent$AccessibleJTextComponent.caretUpdate(JTextComponent.java:2608) 
    at javax.swing.text.JTextComponent.fireCaretUpdate(JTextComponent.java:407) 
    at javax.swing.text.JTextComponent$MutableCaretEvent.fire(JTextComponent.java:4415) 
    at javax.swing.text.JTextComponent$MutableCaretEvent.stateChanged(JTextComponent.java:4437) 
    at javax.swing.text.DefaultCaret.fireStateChanged(DefaultCaret.java:802) 
    at javax.swing.text.DefaultCaret.changeCaretPosition(DefaultCaret.java:1277) 
    at javax.swing.text.DefaultCaret.handleSetDot(DefaultCaret.java:1173) 
    at javax.swing.text.DefaultCaret.setDot(DefaultCaret.java:1154) 
    at javax.swing.text.DefaultCaret$Handler.insertUpdate(DefaultCaret.java:1726) 
    at javax.swing.text.AbstractDocument.fireInsertUpdate(AbstractDocument.java:202) 
    at javax.swing.text.AbstractDocument.handleInsertString(AbstractDocument.java:749) 
    at javax.swing.text.AbstractDocument.insertString(AbstractDocument.java:708) 
    at javax.swing.text.PlainDocument.insertString(PlainDocument.java:130) 
    at javax.swing.JTextArea.append(JTextArea.java:477) 

什麼可能導致此問題?

+0

@Kao有多嚴重你對此有何評論? –

+0

@AndrewThompson我也是這個網站的用戶,我經常處理一些你可能稱之爲「不完整」的問題,但是我沒有討論如何擴展一個例子,而是嘗試幫助回答它。 無論如何,我修改了這個問題並添加了一個** complete **示例。只需複製粘貼它,好嗎?我會感激**實際**幫助。 – Kao

+4

在[事件派發線程](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)上構建和操作Swing GUI對象_only_。 – trashgod

回答

0

由於@trashgod已經寫入註釋,所以GUI對象只能在事件分派線程上進行操作。人們可以使用SwingUtilities.invokeLater()來實現這一點,如here所述。

這是log()方法,它解決了這個問題的一個固定的代碼:

private void log(final String message) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      infoTextArea.append(LogUtils.formatLogMessage(message)); 
     } 
    }); 
}