0

그래서 GUI를 작성하기 위해 스윙을 사용하고 MVC 디자인 패턴을 구현하는 Java 응용 프로그램을 가지고 있기 때문에 많은 인스턴스로 끝납니다. SwingWorker은 컨트롤러를 호출하는 데 사용되며 EventQueue.invokeLater()에 대한 많은 호출이 컨트롤러에서 뷰로 연결됩니다. 이는 스윙과 MVC 모범 사례의 단일 스레드 성격의 길을 가야하는 것처럼 보였지만, 지금은 많은 여러 번 다음과 같은 패턴을 복제 코드를 가지고 : 내가 쓸 수 있는지 알고EventQueue.invokeLater()를 여러 번 호출하여 코드 중복을 피하십시오.

public class MainController{ 
    private final View someView; 
    public void someMethod(Object data){ 
     // Do stuff with the data; maybe change the model. 
     EventQueue.invokeLater(new Runnable(){ 
      @Override 
      public void run() { 
       someView.updateView(Object someObject); //This is the code that I actually need to execute 
      } 
     }); 
    } 
} 

public class View extends JPanel{ // or whatever 
    private final MainController controller; 
    public class someListener implements ActionListener{ 
     public void actionPerformed(ActionEvent e) { 
      new SwingWorker<Void,Void>(){ 
       public Void doInBackground(){ 
        controller.someMethod(object); // This is the code I actually want to execute 
        return null; 
       } 
      }.execute(); 
     } 
    } 
} 

EventQueue.invokeLater()에 대한 호출에 runnable을 전달하는 메서드이지만 실행 가능한 코드를 구현하는 데 필요한 모든 코드를 복제해야합니다. 실제로 실행해야하는 대부분의 코드 조각은 EDT 나 SwingWorker에서 실행해야한다는 점 외에는 공통점이 많지 않으므로 SwingWorker을 확장하거나 Runnable을 구현하는 것이 도움이되지 않습니다. 제 질문은이 복제본을 어떻게 피할 수 있습니까? 디자인에 문제가 있습니까? 아니면이 모든 오버 헤드 코드없이 메서드 호출을 수행 할 수있는 방법이 있습니까?

+0

컨트롤러가 멀티 스레드입니까? 일반적으로 뷰는주의를 기울이지 않아도되지만 컨트롤러는 EDT 물론 외부에서 UI를 업데이트하지 않도록 모든 노력을 기울여야합니다. – MadProgrammer

+2

SwingWoker # publish/process 또는 SwingWorker # done을 사용하여 작업자를 EDT와 다시 동기화하십시오 ... – MadProgrammer

+0

예, 컨트롤러가 멀티 스레드입니다. 'SwingWorker'의 다른 메소드를 사용하지 않는 이유는 컨트롤러가 모델로부터 데이터를 가져와 뷰를 업데이트하는 데 사용하기 때문에 뷰에 모델에 대한 액세스 권한을 부여하거나 코드를 필요로하지 않기 때문입니다. 컨트롤러에 속해서보기에 있어야합니다. – dramzy

답변

0

마침내이 문제가 해결되었습니다. GUI 구성 요소를 업데이트 할 때 컨트롤러의 EventQueue.invokeLater()을 호출하는 대신에, 이제 호출에서 컨트롤러가 호출하는 뷰에 메서드를 래핑합니다. 이렇게하면 컨트롤러의 크기가 수백 줄 줄었습니다.