2015-02-02 4 views
2

자바 스윙 작업에 가장 적합한 방법은 무엇일까? 나는 자바 스윙 응용 프로그램에서 기본적으로 메인 스레드와 이벤트 디스패치에 의해 두 개의 스레드가 있다는 것을 압니다. 이런 식으로 창을 만들고 보여줍니다.스윙 동시성 및 이벤트 발송 스레드

public class Main { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(()-> new MyWindow().initializeAndShow()); 
    } 

하지만 런타임시 Java 스윙에서 어떻게 작동해야하는지 알고 싶습니다. 예를 들어 버튼 클릭시 JText에서 텍스트를 설정하는 경우입니다. 나는 항상 이렇게 할 필요가 있니?

SwingUtilities.invokeLater(()-> button.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) 
      { 

       SwingUtilities.invokeLater(()-jtext.setText("HelloFromAWTThread"); 
      } 
     });  

은 올바른, 내가 지금까지 버튼도 너무 리스너가 파견 스레드에서 설정해야하거나 정확하지 않은 UI의 일부로서 생각인가? 그리고 JText 설정도 AWT 스레드에 있어야합니까?

+1

* "JText의 텍스트 설정 .."* JText 란 무엇입니까? 신경 쓰지 마세요. 더 나은 도움을 받으려면 [MCVE] (http://stackoverflow.com/help/mcve) (최소한의 완전한 검증 가능한 예) 또는 [SSCCE] (http://www.sscce.org/) (짧음, 자체 포함됨, 올바른 예). –

답변

5

생각보다 훨씬 간단합니다.

물론 UI 요소 (e.h 레이블 텍스트 설정, 버튼에 수신기 추가 등)의 수정은 이벤트 발송 스레드 (EDT)에서만 수행해야합니다.

하지만 대부분의 경우 이는 EDT에서 모든 이벤트 (예 : 마우스 또는 버튼 누르기)를 처리하므로 실제 청취자가 EDT에서 실행되므로 실제 제한이 없습니다. 당신이 리스너를 등록 할 경우

그래서, 단지

button.addActionListener(new ActionListener() { 
    /* called by the EDT when the button has been clicked */ 
    public void actionPerformed(ActionEvent e) { 
     jtext.setText("HelloFromAWTThread"); 
    } 
}); 

또는 자바 8 람다와 더 간단 할 :

button.addActionListener(e -> jtext.setText("HelloFromAWTThread")); 

당신이 장기를 실행하려는 경우 그것은 단지 더 복잡 점점 실행중인 작업, 예. I/O 작업 (파일 로딩, 네트워크 요청 수행) 또는 차단 작업은 EDT를 너무 오래 차지하므로 시간 소모적 인 계산 (PI의 1 백만 자릿수 계산, 소수 분해 등), UI 이벤트를 처리하지 못하게합니다. 따라서 이러한 작업은 별도의 스레드에서 실행해야합니다. 그러나 EDT가 아닌 다른 스레드에서 UI를 업데이트 할 수 없으므로 SwingUtilities.invokeLater(updateTask)을 호출하여 EDT에 UI 업데이트 태스크를 '전달'할 수 있습니다.