我刚开始学习如何使用动作侦听器。根据我的理解,它的工作方式如下:
默认情况下,有些类包含“addActionListener”方法(例如按钮类)。
使用此方法,我们向对象添加一个动作侦听器。例如:listenedObject.addActionListener(listeningObject)
。
当执行具有“listenedObject”的动作时,将调用“listenObject”的“actionPerformed”方法。所以,这意味着当我们为listenObject编写一个类时,我们需要设置“actionPerformed”方法。
我不清楚,我们是否应该为每个想听的对象创建一个新类。在我看来,这不是一个优雅的解决方案。另一方面,如果我们有一个动作监听器类用于所有(或至少很多)对象,那么我们遇到问题,因为这个类的实例不知道哪个对象正在调用“actionPerformed”方法(我们需要知道,因为actionPerformed执行的操作因此方法的调用方式而异。)
在我看来,我们需要创建的每个侦听对象都是“个人”动作侦听器,我们可以通过将特定值设置为动作侦听器的相应字段来实现。但我不确定这是一个标准的方法吗?人们通常如何做到这一点?
答案 0 :(得分:7)
最常见的处理方法 - 从我自己的个人经验来看 - 就是简单地创建一个匿名的内联类。像这样:
listenedObject.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
// Your action handling code in here
}
});
我经常看到人们调用包含listenedObject的对象的方法。例如,在具有按钮的对话框中:
myOkayButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
okayButtonPressed();
}
});
然后在对话框类中:
private void okayButtonPressed() {
// Do what we need to do
}
答案 1 :(得分:2)
Personnaly,如果可能的话,我更喜欢使用Action类(作为AbstractAction
的子类)而不是简单地依赖于动作侦听器。这样,我可以为原始窗口小部件提供名称,图标,工具提示等等......
答案 2 :(得分:2)
我一直觉得有用的方法(用于导航目的)是创建一个匿名内部类,然后委托给外部类:
listenedObject.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
listenedObject_actionPerformed(evt);
}
});
private void listenedObject_actionPerformed(ActionEvent evt) {
//Your handling goes here
}
使用结构查找(在IDEA中使用CTRL + F12,在Eclipse中使用CTRL + O),可以更轻松地在IDE中处理代码。
使用单个类(如GUI MyCoolPanel
)作为其一组组件(按钮等)的公共侦听器的问题是actionPerformed
方法有很多丑陋{ {1}}比较以确定实际上已经按下了哪个按钮 - 根本不是OO!
你当然不应该过分担心这种事情的表现方面 - 它们可能在极端情况下可以忽略不计!过早优化是着名的一件坏事
答案 3 :(得分:1)
我一直觉得有用的方法是创建一个单独的类来实现ActionListener接口以及执行该操作所需的所有其他方法。这样,动作不依赖于特定对象,可以通过按钮,菜单等触发。有点像Command pattern我猜。它使代码简单。
匿名类不可重复使用。
重定向到包含listenedObject的对象会导致难以维护的巨大类。
答案 4 :(得分:0)
请注意,removeActionListener方法存在的原因。如果您收听的对象将死于处理事件的对象,则可以跳过侦听器清理。但是,如果组件侦听从外部源提供的模型,则应在addNotify中添加侦听器并在removeNotify方法中删除它们。否则你可能会有一个记忆泄漏。
答案 5 :(得分:0)
也许现在实际上并不是这样,但我相信在不久的将来(在Java 7发布之后)这样的事情会是常见的方式:
listenedObject.addActionListener ( #{doSmth();} );