将View的JButtons对象公开给Presenter

时间:2017-02-24 20:06:56

标签: java private mvp inner-classes code-completion

我正在使用MVP设计模式在Java中编写GUI应用程序。 JButton个对象属于View类,ActionListener个对象属于Presenter。我正在寻找一种简洁的方法,允许演示者将ActionListener添加到视图JButtons,而无需(1)创建按钮public和(2) )无需向视图中添加一堆类似于

的视图
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允许Presenter按名称引用它们(这允许我的IDE使用代码完成);但是,因为它们是WrappedJButton个对象,所以Presenter可以做的唯一事情就是添加一个ActionListener。视图可以得到满满的#34;通过抓住"真实"来访问对象按钮通过私人b字段。

问题:

  1. 是否有更好/更清洁的解决方案?或许那样的东西 将无需访问视图中的b字段?
  2. 有没有办法概括这个解决方案,所以我不必这样做     将WrappedJButton剪切并粘贴到我编写的每个View类中?一世     尝试将WrappedJButton移动到界面中(查看     实现);但是,当我这样做时,View不再能够访问     私人b字段。

1 个答案:

答案 0 :(得分: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方法。