2016-07-08 32 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)); 
     } 
    }); 
}