我正在使用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
字段。
问题:
b
字段? WrappedJButton
剪切并粘贴到我编写的每个View类中?一世
尝试将WrappedJButton
移动到界面中(查看
实现);但是,当我这样做时,View不再能够访问
私人b
字段。答案 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
方法。