2014-10-21 2 views
0

이 포럼에 대한 또 다른 질문이 있습니다. 자바가있는 작은 응용 프로그램을 쓰고 있는데 여기에는 여러 개의 스레드가 있습니다. 두 개의 다른 클래스에있는 두 개의 스레드가 있습니다. 하나의 스레드 (스레드 1)가 모든 JFrame 구성 요소를 정의합니다. (JPanels, JButtons, ActionListeners 등) 다른 스레드에서 (스레드 2) 변수 (v)가 특정 값과 같은지 확인하려고합니다.()이 변수가 으로 변경되면 해당 같은 스레드이 JLabel을 업데이트한다고 가정합니다. (지금이 라벨을 라벨라고 부르 자.) 그렇지 않습니다. 내가 잘못하고있는 일이 있습니까? 모든 클래스의 메서드를 작성하려고 시도했습니다 - 레이블의 텍스트를 변경하지만이 메서드를 thread2에서 호출하면 레이블을 업데이트하지 않습니다. thread1을 포함하는 수퍼 클래스를 호출 해 보았습니다.하지만 그 차이는 없습니다. 또한 repaint() 메서드를 호출했지만 도움이되지 않습니다.Java의 스레드에서 레이블의 텍스트를 변경할 수 있습니까?

두 개의 다른 스레드에서이 JLabel을 업데이트하려면 어떻게 할 수 있는지 알려 주시기 바랍니다. 사전에

감사합니다, ~ 레인

코드 :

클래스 1 :

JFrame frame = new JFrame(); 
JPanel panel = new JPanel(); 
JLabel label = new JLabel("V does not equal 98 Yet..."); 
Thread thread1 = new Thread(){ 

    public void run(){ 

    panel.add(label); 
    frame.add(panel); 
    System.out.println("Components added!"); 

    } 
}); 

public void setLabelText(String text){ 
    label.setText(text); 
} 

클래스 1 = 2 :

v = 0; 
Thread thread2 = new Thread(){ 

    public void run(){ 

    while(v < 98){ 

     System.out.println("V equals -" + v + "-."); 
     v ++; 
    } 
    Class1 otherClass = new Class1(); 
    otherClass.label.setText("V is now equal to: " + v); 
    otherClass.repaint(); 
    otherClass.setLabelText("V is now equal to: " + v); 
    otherClass.repaint(); 
    } 
}); 
+4

스윙은 단일 스레드 프레임 워크이며, 스레드로부터 안전하지 않습니다. 즉, 모든 작성, ulceration 및 UI 수정은 이벤트 발송 스레드의 컨텍스트 내에서 수행되어야합니다. 또한 y가 EDT의 컨텍스트 내에서 코드를 실행하지 않거나 실행하지 않아야 함을 의미합니다. 이로 인해 프로그램이 중단 된 것처럼 보이게됩니다. 그래서 당신의 질문에 대한 대답은, 아니오, 절대로, 당신이해야 할 일을해야만합니다. 업데이트가 EDT로 다시 동기화되도록하려면 SwingUtilities.invokeLater를 사용하는 SwingWorker를 사용하는 것이 좋습니다. – MadProgrammer

+0

Well said. 어떤 쓰레드라도'SwingUtilities.invokeLater()'에 의해 AWT/ETD/Swing 쓰래드에서 코드가 실행되도록 할 수 있습니다. (같은 이름의 다른 모든 이름) –

+0

이런 식으로해서는 안됩니다. 클래스 1의 인스턴스를 두 개 만들면 스레드 1의 인스턴스는 스레드 2의 인스턴스와 같지 않으므로 하나를 변경하면 다른 인스턴스에는 아무런 영향을 미치지 않습니다. – MadProgrammer

답변

8

스윙 하지 스레드 안전합니다. 나는 반복하십시오 Event Dispatch Thread (EDT)

이외의 스레드에서 스윙 객체의 모든 메소드를 호출하지 않는 여러 다른 스레드에서 이벤트를지고 당신이 그들을 직접 스윙 객체에 영향을 가지고 싶다면, 당신은 사용해야합니다

// Note you must use final method arguments to be available inside an anonymous class 
private void changeJLabel(final JLabel label, final String text) { 
    EventQueue.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     myLabel.setText(text); 
    } 
    }); 
} 
+0

하지만 그렇게 많은 요청에 대해 많은 스레드를 생성하지 않을까요? – SMUsamaShah

+1

@ LifeH2O 아니요, 단 하나의 스레드 인 Event Dispatch Thread가 있습니다. 이것은 스레드가 처리 할 작업을 예약합니다. – durron597

+0

이것은 http://stackoverflow.com/questions/9029795/new-runnable-but-no-newthread는'새로운 Runnable() {}'설명합니다 – SMUsamaShah

관련 문제