2016-07-08 4 views
-1

JTextArea 구성 요소가있는 GUI 응용 프로그램이 있습니다. 몇 가지 정보를 기록하는 데 사용됩니다 그것은 그러나 윈도우 7에 대한 확인 작업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); 
    } 
} 

를, 리눅스에 몇 통화 후 전체 응용 프로그램을 걸 것으로 보인다. 스택 분석 결과 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)에서 _only_ Swing GUI 객체를 생성하고 조작하십시오. – 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)); 
     } 
    }); 
} 
관련 문제