有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Swing中的java操作侦听器和事件源

好的,那么如果我向GUI元素添加一个ActionListener,并且它是我使用该ActionListener唯一的元素,那么我使用以下哪一行(a,b)来获得复选框选中状态是否重要

final JCheckBox checkbox = (JCheckBox)this.buildResult.get("cbDebugTick");
checkbox.addActionListener(new ActionListener() {
    @Override public void actionPerformed(ActionEvent event){               
            boolean bChecked =
            // (a) checkbox.isSelected();
            // (b) ((JCheckBox)event.getSource()).isSelected();
            model.setPrintDebugOn(bChecked);
        }
});

对我来说,如果我将ActionListener对象添加到多个GUI元素中,那么我应该使用(b)

在(b)中,既然是我添加了动作监听器,那么盲目地将event.getSource()转换为JCheckBox可以吗,还是应该进行防御性编程并进行instanceof检查

注意:这个问题一般是针对事件听众的;KDGRGGORY有一些优点,特别是RE:我忽略过的复选框。p>


共 (4) 个答案

  1. # 1 楼答案

    我会选择b防守,因为这是最佳实践选项。但是,如果你真的打算使用代码,那么你就没有理由不去做。然而,想象一下,如果你在将来某个时候重新使用它,改变一些东西,发现你编写了可以直接重用的好代码,你会多么高兴

  2. # 2 楼答案

    对于侦听器是独占的(例如anon侦听器),我使用(a)

    如果监听器将被重用(例如,this是ActionListener的一个实例),我将把它写成:

    @Override
    public void actionPerformed(ActionEvent event) {
        Object src = event.getSource();
        if (src == checkbox) {
            boolean bChecked = checkbox.isSelected();
            // ...
        }
    }
    

    如果您有几个复选框,并且它们的处理方式相同,那么instanceof是有意义的

  3. # 3 楼答案

    我都不会

    如果单击复选框将开始一些操作,我会附加一个ItemListener,然后只需查看ItemEvent中的选择状态

    然而,复选框通常不会调用操作,而是管理状态。因此,更好的方法是检查所有复选框,以响应启动操作的任何内容


    编辑:关于OP提出的更大问题的一些评论

    首先,重要的是要认识到,Swing的很大一部分代表了实现的便利性,而不是一致的行为模型JCheckBoxJButton除了在他们的空间内点击是有意义的这一事实之外,没有任何共同点。然而,它们都继承自AbstractButton,后者提供了实现细节,比如按钮的标签。它还假设按钮被“按下”,按下按钮将启动一些有意义的行为(动作)。然而,在JCheckbox的情况下,按下按钮并不重要,状态的变化是重要的。该状态更改被通知给ItemListener——它也在AbstractButton上定义,尽管状态更改对其他按钮类型来说没有意义(JavaDoc甚至说“复选框”)

    Swing做对了一件事——如果很难使用的话——就是一个Action与启动该操作的控件是分开的。动作对象可以从多个控件中调用:菜单项、对话框上的按钮、按键等等。从设计的角度来看,更重要的是,它让你摆脱了一个通用的“倾听者”的想法,试图找出需要发生什么。例如,我见过一些应用程序,其中一个监听器接收来自整个菜单系统的输入,然后通过一个大的if/else链来确定按下了哪个菜单项。使用Actions意味着你有更多的类,但从长远来看,它会给你一个更易于维护的应用

    最后,从可用性的角度来看,维护状态的控件(如JCheckbox和JTextArea)与启动操作的控件(如JButton和JMenuItem)之间存在差异。我见过一个(网络)应用程序,点击单选按钮可以进入另一个页面。那太糟糕了。即使您计划在内部使用侦听器来更新某个模型的状态,您也应该问问自己,为什么GUI元素集合本身不能为您提供模型

  4. # 4 楼答案

    在(b)中,严格来说,你确实应该做一个瞬间检查,但这并不是那么重要。我认为这两行代码都是可以接受的,尽管(b)是“更好的代码”

    不过,在动作侦听器中通常只需调用另一个根据复选框定制的方法。所以它看起来像这样:

     @Override public void actionPerformed(ActionEvent event) {                                  
        //your treatment would be in this method, where it would be acceptable to use (a)                  
        onCheckBoxActionPerformed(event)
    }