2014-09-22 1 views
0

actionPerformed (ActionEvent e)가 Event Dispatch Thread (EDT)와는 다른 스레드에서 실행됩니까? 이 문턱 actionPreformed 내부 ++을하는 것은 불가능 실행 javax.swing.SwingUtilities.isEventDispatchThread()는 세 가지 경우 모두에서 진정한 returnd하지만actionPerformed (ActionEvent e)가 Event Dispatch Thread (EDT)와 다른 스레드에서 실행됩니까?

public void main(String args[]){ 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
        Frame f = new Frame(); 
        f.setVisible(true); 
        javax.swing.SwingUtilities.isEventDispatchThread() 
       } 
      catch(Exception e){ e.printStackTree;} 
} 

public Frame() 
{ //...some code.... 

    JButton btn = new JButton(); 
    //int a; 
    javax.swing.SwingUtilities.isEventDispatchThread() 
    btn.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      //..some code.... 
      javax.swing.SwingUtilities.isEventDispatchThread() 
      //a++; 
     } 
    } 
} 

: 나는 다음과 같은 코드를 작성 말한다.

전체 프로젝트가 EDT 내에서 실행 중이지만 EDT가 Frame() 생성자와 actionPreformed() 함수에 대해 새로운 다른 스레드를 시작했지만이 프로젝트를 디버깅하고 잘못된 경우 수정합니다. . 그런 이유로 actionPreformed()의 스레드를 끝낼 수있는 다른 스레드에서 생성 된 변수 a를 사용하여 actionPreformed()의 가능성을 벗어나기 위해 일반 " int '', 'final int' '만이 허용됩니다.

이 예제에서 actionPrefromed() 함수는 Frame() 생성자의 스레드와 다른 스레드에서 실행됩니까?

1.1 그렇다면 actionPreformed() 함수에서 a를 수정할 수없는 이유는 무엇입니까?

1.2 그렇다면 프레임() 생성자에 보관할 수있는 값을 어떻게 저장할 수 있습니까? 또는 적어도 다른 버튼으로 액세스 할 수 있습니까?

왜 프레임 f를 만들거나 보이는 것으로 설정하는 것이 가장 먼저 ETD 내부에서 수행해야합니까?

+0

너무 많은 질문 ... 귀하의 초기 질문은 다음 질문을 할 일이 없습니다 ... 첫 번째 질문 : ActionPerformed는 edt에서 실행됩니다. – Ben

답변

4

문제는 스레딩이 아닙니다. 익명의 ActionListener 클래스는 다른 클래스입니다. ActionListener의 수명은 로컬 변수 'a'의 수명보다 길기 때문에 수정할 수 없습니다. 따라서, 그것은 최종해야합니다.

실제로 '생성자에 변수 유지'를 시도한 다음 수명이 긴 클래스가이를 수정할 수있게하는 것은 전혀 의미가 없습니다.

저는 여러분이 원하는 가장 가까운 것은 'a'를 Frame 클래스의 멤버 변수로 만드는 것이라고 생각합니다. 그런 다음해야 할 경우 "Frame.this.a"를 사용하여 ActionListener에서 액세스 할 수 있지만 Frame의 공용 메서드가 더 좋습니다.

마지막으로 프레임을 만들고 "visible"로 설정하는 것은 EDT에서 수행됩니다. 그 이유는 그것이 Swing 구성 요소를 수정하는 것이 안전한 유일한 스레드이기 때문입니다.