实施actionPerformed的最佳方式?

时间:2011-05-02 16:56:38

标签: java

在Java中,我们有两种方法来实现actionPerformed:

  1. 每个类一个actionPerformed方法:使用if-else检查事件源;
  2. 使用匿名内部类并在创建该对象的位置实现actionPerformed方法;
  3. 对于选项1,很容易跟踪actionPerformed代码的位置,因为每个类只有一个方法。我们可以轻松找到该方法,然后查看内部以找到我们正在寻找的代码。但是,如果我们有很多动作监听器,那么if-else子句可能会太多。

    对于选项2,要找到actionPerformed代码的位置并不容易,因为它遍布整个类。如果您有许多动作侦听器,则跟踪actionPerformed实例将更加困难。

    我个人更喜欢选项1,因为维护代码要容易得多,即使性能可能比选项2效率低。

    每种方法的优缺点是什么?在选择如何实施actionPerformed时还应该考虑什么?您更喜欢哪种方式?

    修改

    所以根据下面A. Lee的建议,有第三个选项。 它是选项1和选项2的组合:使用匿名内部类,但将它们放在一个类中的一个位置。 我认为这是一个好主意。

4 个答案:

答案 0 :(得分:3)

我认为actionPerformed方法中的long if-else链是丑陋的,原因有几个 - 每次都要进行不必要的检查,以确定哪个是ActionEvent的适当接收器代码,随着代码的增长,它变得越来越多难以维护。

如果您希望将所有操作处理程序放在一个位置,请使用initializeActionListeners方法将ActionListener绑定到控件。或者将它们绑定在初始化它们的位置,以便事件处理程序更接近您的小部件/控件本身,例如,

// not thread-safe
private JLabel getSomeLabel() {
    if (someLabel == null) {
        someLabel = new JLabel("Some label, huh");
        someLabel.addActionListener(...)
    }
    return someLabel;
}

答案 1 :(得分:1)

错误的替代方案:问题不是匿名类与长大的if-else结构(你可以很容易地在后者中使用后者)。问题是,是否有一个语义上强大的类(匿名或非匿名)只完成一项工作,是唯一一个完成它的人。毕竟,我们在OO-land; - )

所以:严格禁止任何if-then-else结构。

答案 2 :(得分:0)

我使用第三个选项,我编写了自己的管理器,通过注释直接将方法绑定到JButtons。

我将其作为OpenSource项目提供,您可以在https://github.com/MarkyVasconcelos/Towel/wiki/ActionManager

上查看

优点是你不需要实现任何ActionListener,也不需要匿名内部类。

所有操作都在您班级的方法中。

答案 3 :(得分:0)

在大多数情况下,没有太大的区别,建议一个在另一个上面。

我会说:如果情况类似,将它们放在一起,但只能从那里调用适当的方法:

    public void actionPerformed (ActionEvent e)
    {
            String cmd = e.getActionCommand ();
            if (cmd.equals (cmdNextPage))        nextPage ();
            else if (cmd.equals (cmdLastPage))   lastPage ();
            else if (cmd.equals (cmdOk))         ok ();
            // ... and so on

这样,您可以轻松地调用方法,独立于事件,可能来自测试框架,或者进行一些撤消/重放。常见的模式显然是可见的。

在极少数情况下,您可能有兴趣单独取消注册单个事件和来源。然后,每个ActionEvent的单个侦听器似乎更适合。

从纯OOP的角度来看,我认为每个Button的单个监听器(例如)更直接,而且从一个不成熟的优化愿望中,我对20或40个ActionListener感到不舒服,但在我的理性时刻,我不相信40个ActionListener会产生可衡量的影响。但它们混乱了你的文件系统,你的IDE浏览器,所以我想最终有一个合理的理由,以保持较低的监听器数量。

普通的监听器在按钮工厂中很容易使用:

    private void addButton (JPanel jp, String cmd, String ttt)
    {
            JButton jb = new JButton (cmd);
            jb.setToolTipText (ttt);
            jp.add (jb);
            jb.addActionListener (this);
            buttonlist.add (jb);
    }

    /**   @return a Panel with Action-Buttons.     */
    private JPanel createControlPanel ()
    {
            JPanel m = new JPanel ();
            m.setLayout (new BoxLayout (m, BoxLayout.Y_AXIS));

            JPanel jpc = new JPanel ();
            jpc.setLayout (new FlowLayout ());
            buttonlist = new ArrayList <JButton> ();

            addButton (jpc, cmdLastPage, "last page");
            addButton (jpc, cmdNextPage, "next page");
            addButton (jpc, cmdOk, "save");
            addButton (jpc, cmdEsc, "exit");

它非常简单明了,在哪里添加新按钮以及如何添加。我发现它非常易于维护。