2017-02-24 20 views
1

我在Java中使用MVP的設計模式編寫GUI應用程序。 JButton對象屬於View類,ActionListener對象屬於Presenter。我在尋找一個簡潔的方式,讓演示者ActionListener s添加到視圖的JButtons無:(1)使按鈕public和(2),而不必一堆的方法添加到看起來像揭露查看的Jbutton將簡潔的方式反對主持人

視圖
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 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 

此包裝效果很好。製作包裝的按鈕public允許演示者通過名稱引用它們(這允許我的IDE使用代碼完成);但是,因爲它們是WrappedJButton對象,所以Presenter只能添加一個ActionListener。通過在私人b字段中抓取「真實」按鈕,視圖可以「完全」訪問對象。

問題:

  1. 是否有一個更好/更清潔的解決方案?或許有些 將消除需要訪問View中的b場?
  2. 有沒有辦法來概括這個解決方案,所以我不必 剪切和粘貼WrappedJButton到每一個視圖類我寫?我 試圖移動WrappedJButton到接口(其查看 器具);但是,當我這樣做,查看不再具有訪問 私人b場。

回答

0

我認爲這將是確定,以避免拷貝粘貼的WrapperJButton類通過暴露在封裝級包裹按鈕(假設的Presenter駐留在不同的包中):

public class WrappedJButton { 
    final JButton b; 

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

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

一種不同方法可以是按鈕保存在地圖:

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方法。