2016-07-08 11 views
-1

私はJTextAreaコンポーネントのGUIアプリを持っています。いくつかの情報を記録するために使用されます。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上で[OK]を動作しますが、Linux上で、いくつかのコールの後に全体のアプリがハングアップするようです。スタックを分析すると、GUIスレッドが状態にあることがわかります。

"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私はこのサイトのユーザーでもありますが、「不完全」と呼ぶかもしれない質問に対処していますが、例を拡張する方法については議論しませんが、代わりに答えようとします。とにかく、私は質問を修正し、**完全な例を追加しました。コピーして貼り付けるだけです。 **実際の**ヘルプに感謝します。 – Kao

+4

[イベントディスパッチスレッド](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)でSwing GUIオブジェクト_only_を作成し、操作します。 – trashgod

答えて

0

@trashgodはコメントで書かれているので、GUIオブジェクトはイベントディスパッチスレッド上でのみ操作する必要があります。これは、hereのようにSwingUtilities.invokeLater()を使用してこれを達成することができます。

これは、問題を解決しlog()方法、の固定コードです:

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