2017-02-24 1 views
1

MVP 디자인 패턴을 사용하여 Java로 GUI 응용 프로그램을 작성하고 있습니다. JButton 개체는 View 클래스에 속하고 ActionListener 개체는 Presenter에 속합니다. 발표자가보기의 JButtonsActionListener을 추가 할 수있는 간결한 방법을 찾고 있는데, (1) 단추 모양을 public으로 만들고보기의 JButtons 객체를 Presenter에 노출시키는 간결한 방법

과 같은보기에 여러 가지 방법을 추가하지 않아도됩니다 (2).

public class View { 

    class WrappedJButton { 
    private JButton b; 

    public WrappedJButton(String name){ 
     this.b = new JButton(name); 
    } 

    public void addActionListener(ActionListener l) { 
     b.addActionListener(l); 
    } 
    } 

    public final WrappedJButton next = new WrappedJButton("Next"); 
    public final WrappedJButton prev = new WrappedJButton("Previous"); 

    public void setup() { 
    JPanel buttons = new JPanel(); 
    buttons.setLayout(new FlowLayout()); 
    buttons.add(previous.b); 
    buttons.add(next.b); 
} 
} // end view 

class Presenter { 

    public Presenter() { 
    View view = new View(); 

    view.next.addActionListener(event -> { 
     // Respond to button push 
    }); 
    } 
} // end Presenter 

이 래퍼 잘 작동 :

private JButton foo; 
private JButton bar; 

public void addActionListenerToButtonFoo(ActionListener l) { 
    foo.addActionListener(l); 
} 

public void addActionListenerToButtonBar(ActionListener l) { 
    bar.addActionListener(l); 
} 

// (imagine typing 10 more of these trivial functions and having 
// them clutter up your code) 
나는 합리적으로 잘 작동 한 기술을 발견했다. 래핑 된 버튼을 public으로 만들면 발표자가 이름으로 참조 할 수 있습니다 (내 IDE에서 코드 완성을 사용할 수 있음). 그러나 WrappedJButton 개체이기 때문에 발표자가 할 수있는 것은 ActionListener를 추가하는 것뿐입니다. 보기는 전용 b 필드를 통해 "실제"단추를 가져 와서 개체에 "전체"액세스 할 수 있습니다.

질문 :

  1. 은 더 나은/청소기 솔루션이 있습니까? 아마도 뭔가가보기에서 b 필드에 액세스 할 필요가 없게되는 것입니까?
  2. 이 솔루션을 일반화 할 수있는 방법이 있나요? 잘라 내기 및 붙여 넣기 WrappedJButton 내가 작성하는 모든 뷰 클래스에? I WrappedJButton을 인터페이스로 이동하려고 시도했습니다 (보기 구현). 하지만 그렇게하면 View가 더 이상 개인 b 필드에 액세스 할 수 없습니다.

    public class WrappedJButton { 
        final JButton b; 
    
        WrappedJButton(String name){ 
         this.b = new JButton(name); 
        } 
    
        public void addActionListener(ActionListener l) { 
         b.addActionListener(l); 
        } 
    } 
    

    다른에게 :

답변

0

나는 그것을합니다 (Presenter가 다른 패키지에있는 가정) 패키지 수준에 랩 버튼을 노출시켜 복사 붙여 넣기에게 WrapperJButton 클래스를 방지하기 위해 괜찮을 것이라고 생각 방법은지도에있는 버튼을 저장할 수 :

class ButtonMap<E extends Enum<E>> { 
    private final EnumMap<E, JButton> map; 

    ButtonMap(Class<E> buttonEnum){ 
     map = new EnumMap<>(buttonEnum); 
     for(E e : buttonEnum.getEnumConstants()){ 
      map.put(e, new JButton(e.toString())); 
     } 
    } 

    JButton get(E e){ 
     return map.get(e); 
    } 

} 

같이 수있는이지도를 사용하여보기 :

public class View { 

    private final ButtonMap<ViewButton> buttonMap = new ButtonMap<>(ViewButton.class); 
    public enum ViewButton{ 
     NEXT("Next"), 
     PREV("Prev"); 

     private final String name; 

     private ViewButton(String name){ 
      this.name = name; 
     } 

     @Override 
     public String toString(){ 
      return name; 
     } 
    } 

    public void setup() { 
     JPanel buttons = new JPanel(); 
     buttons.setLayout(new FlowLayout()); 
     buttons.add(buttonMap.get(ViewButton.PREV)); 
     buttons.add(buttonMap.get(ViewButton.NEXT)); 
    } 

    public void addActionListener(ViewButton button, ActionListener l){ 
     buttonMap.get(button).addActionListener(l); 
    } 

} // end view 

버튼지도는 비공개 필드로 숨겨져 있습니다. 단추의 addActionListener 메서드 만 노출됩니다.