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>
# 1 楼答案
我会选择b防守,因为这是最佳实践选项。但是,如果你真的打算使用代码,那么你就没有理由不去做。然而,想象一下,如果你在将来某个时候重新使用它,改变一些东西,发现你编写了可以直接重用的好代码,你会多么高兴
# 2 楼答案
对于侦听器是独占的(例如anon侦听器),我使用(a)
如果监听器将被重用(例如,
this
是ActionListener的一个实例),我将把它写成:如果您有几个复选框,并且它们的处理方式相同,那么
instanceof
是有意义的# 3 楼答案
我都不会
如果单击复选框将开始一些操作,我会附加一个ItemListener,然后只需查看ItemEvent中的选择状态
然而,复选框通常不会调用操作,而是管理状态。因此,更好的方法是检查所有复选框,以响应启动操作的任何内容
编辑:关于OP提出的更大问题的一些评论
首先,重要的是要认识到,Swing的很大一部分代表了实现的便利性,而不是一致的行为模型JCheckBox和JButton除了在他们的空间内点击是有意义的这一事实之外,没有任何共同点。然而,它们都继承自AbstractButton,后者提供了实现细节,比如按钮的标签。它还假设按钮被“按下”,按下按钮将启动一些有意义的行为(动作)。然而,在JCheckbox的情况下,按下按钮并不重要,状态的变化是重要的。该状态更改被通知给ItemListener——它也在AbstractButton上定义,尽管状态更改对其他按钮类型来说没有意义(JavaDoc甚至说“复选框”)
Swing做对了一件事——如果很难使用的话——就是一个Action与启动该操作的控件是分开的。动作对象可以从多个控件中调用:菜单项、对话框上的按钮、按键等等。从设计的角度来看,更重要的是,它让你摆脱了一个通用的“倾听者”的想法,试图找出需要发生什么。例如,我见过一些应用程序,其中一个监听器接收来自整个菜单系统的输入,然后通过一个大的if/else链来确定按下了哪个菜单项。使用Actions意味着你有更多的类,但从长远来看,它会给你一个更易于维护的应用
最后,从可用性的角度来看,维护状态的控件(如JCheckbox和JTextArea)与启动操作的控件(如JButton和JMenuItem)之间存在差异。我见过一个(网络)应用程序,点击单选按钮可以进入另一个页面。那太糟糕了。即使您计划在内部使用侦听器来更新某个模型的状态,您也应该问问自己,为什么GUI元素集合本身不能为您提供模型
# 4 楼答案
在(b)中,严格来说,你确实应该做一个瞬间检查,但这并不是那么重要。我认为这两行代码都是可以接受的,尽管(b)是“更好的代码”
不过,在动作侦听器中通常只需调用另一个根据复选框定制的方法。所以它看起来像这样: