处理 MVC 模型、jbuttons 和 ActionListener 的 getSource() 方法

Dealing with MVC model, jbuttons and ActionListener's getSource() method

所以我在使用 MVC 编写程序时偶然发现了这个问题。 我在 View class 中有一个 private JButton。我编写了将侦听器添加到所有相应按钮的方法。但是,当我尝试对 ActionPerformed() 部分进行编码时,它会抛出有关 JButton 不可见的错误。

JButton 设置为 public 完全解决了问题,但这样做正确吗?是否有另一种设置 ActionListener 而不使 JButton public 的方法?

public class learningView extends JFrame {
    private JButton viewButton = new JButton("View Resources");

    public void addButtonListener(ActionListener listenerForButtons) { 

    viewButton.addActionListener(listenerForButtons);
    saveButton.addActionListener(listenerForButtons);
    addButton.addActionListener(listenerForButtons);

    }
}

public class learningController {

    private learningModel theModel;
    private learningView theView;

    public learningController(learningModel theModel, learningView theView) {

    this.theModel = theModel;
    this.theView = theView;

    this.theView.addButtonListener(new buttonListener());

}

class buttonListener implements ActionListener {

    public void actionPerformed(ActionEvent e) {

        if (e.getSource() == theView.viewButton) {// This is where problem arises

        }

    }

}

}

视图和控制器的 Hastebin classes(没有模型)为了方便。 http://www.hastebin.com/ecawolusal.avrasm

由于 viewButton 具有对 LearningVew 的私有访问权限,因此在 类 上下文之外将无法访问它。

现在,在更改访问级别之前,您可以考虑更改方法。

与其向每个通知外部源的按钮添加一个 ActionListener,不如让视图监控按钮本身更简单。

在您为这将如何破坏 MVC 而大发雷霆之前,我们的想法是让视图为相关按钮引发一个更简单、更专用的事件,例如,viewButton 可以raise viewWasActivated 或其他东西,然后控制器会响应。

这将需要您为视图和控制器定义一个 interface 合同,以便它们知道它们能够相互传递哪些信息以及可能触发哪些事件。这可以保护视图控件,意味着您无需公开不必要的内容。

更详细地演示了here

另一种选择是使用按钮的 actionCommand 属性 而不是将按钮的引用与事件源进行比较,但是您首先需要检查按钮的来源动作事件是一个按钮...我个人不喜欢 "bulk" ActionListeners,它们很快就会变得很乱...