Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 显示视图的简洁方式';将JButtons对象发送给演示者_Java_Private_Mvp_Inner Classes_Code Completion - Fatal编程技术网

Java 显示视图的简洁方式';将JButtons对象发送给演示者

Java 显示视图的简洁方式';将JButtons对象发送给演示者,java,private,mvp,inner-classes,code-completion,Java,Private,Mvp,Inner Classes,Code Completion,我正在用Java编写一个使用MVP设计模式的GUI应用程序JButton对象属于视图类,而ActionListener对象属于Presenter。我正在寻找一种简洁的方法,允许演示者向视图的JButtons中添加ActionListener,而无需(1)将按钮公开,(2)向视图中添加一组类似的方法 private JButton foo; private JButton bar; public void addActionListenerToButtonFoo(ActionListener l

我正在用Java编写一个使用MVP设计模式的GUI应用程序
JButton
对象属于视图类,而
ActionListener
对象属于Presenter。我正在寻找一种简洁的方法,允许演示者向视图的
JButtons
中添加
ActionListener
,而无需(1)将按钮
公开
,(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
这个包装很好用。将包装好的按钮
公开
允许演示者按名称引用它们(这允许我的IDE使用代码完成);但是,由于它们是
WrappedJButton
对象,演示者唯一能做的就是添加一个ActionListener。通过私有
b
字段抓取“real”按钮,视图可以“完全”访问对象

问题:

  • 是否有更好/更清洁的解决方案?也许是 是否不需要访问视图中的
    b
    字段
  • 有没有办法推广这个解决方案,这样我就不必这么做了 将
    WrappedJButton
    剪切并粘贴到我编写的每个视图类中?我 尝试将
    WrappedJButton
    移动到界面中(哪个视图 工具);但是,当我这样做时,视图不再具有访问 专用
    b
    字段

  • 我认为可以通过在包级别公开包装的按钮来避免复制粘贴
    WrapperJButton
    类(假设
    Presenter
    位于不同的包中):

    另一种方法是将按钮存储在地图中:

    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);
        }
    
    } 
    
    class按钮映射{
    私有地图;
    ButtonMap(buttonEnum类){
    map=新的EnumMap(按钮数);
    对于(E:buttonEnum.getEnumConstants()){
    put(e,newjbutton(e.toString());
    }
    }
    JButton get(E){
    返回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
    
    公共类视图{
    私有最终按钮映射按钮映射=新按钮映射(ViewButton.class);
    公共枚举视图按钮{
    下一个(“下一个”),
    上交所(“上交所”);
    私有最终字符串名;
    私有视图按钮(字符串名称){
    this.name=名称;
    }
    @凌驾
    公共字符串toString(){
    返回名称;
    }
    }  
    公共作废设置(){
    JPanel按钮=新的JPanel();
    按钮.setLayout(新的FlowLayout());
    buttons.add(buttonMap.get(ViewButton.PREV));
    添加(buttonMap.get(ViewButton.NEXT));
    }  
    public void addActionListener(视图按钮,ActionListener l){
    buttonMap.get(按钮).addActionListener(l);
    }
    }//结束视图
    

    按钮映射使用专用字段隐藏。只有按钮的
    addActionListener
    方法是公开的。

    我认为可以通过在包级别公开包装好的按钮来避免复制粘贴
    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);
        }
    
    } 
    
    class按钮映射{
    私有地图;
    ButtonMap(buttonEnum类){
    map=新的EnumMap(按钮数);
    对于(E:buttonEnum.getEnumConstants()){
    put(e,newjbutton(e.toString());
    }
    }
    JButton get(E){
    返回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
    
    公共类视图{
    私有最终按钮映射按钮映射=新按钮映射(ViewButton.class);
    公共枚举视图按钮{
    下一个(“下一个”),
    上交所(“上交所”);
    私有最终字符串名;
    私有视图按钮(字符串名称){
    this.name=名称;
    }
    @凌驾
    公共字符串toString(){
    返回名称;
    }
    }  
    公共作废设置(){
    JPanel按钮=新的JPanel();
    按钮.setLayout(新的FlowLayout());
    buttons.add(buttonMap.get(ViewButton.PREV));
    添加(buttonMap.get(ViewButton.NEXT));
    }  
    public void addActionListener(视图按钮,ActionListener l){
    buttonMap.get(按钮).addActionListener(l);
    }
    }//结束视图
    
    按钮映射使用专用字段隐藏。仅显示按钮的
    addActionListener
    方法