编程动作侦听器的常用方法是什么?

我刚开始学习如何使用动作监听器。 根据我的理解,它的工作方式如下:

  1. 默认情况下,有些类包含“addActionListener”方法(例如按钮类)。

  2. 使用此方法,我们向对象添加一个动作侦听器。 例如: listenedObject.addActionListener(listeningObject)

  3. 当执行具有“listenedObject”的动作时,将调用“listenObject”的“actionPerformed”方法。 所以,这意味着当我们为listenObject编写一个类时,我们需要放置“actionPerformed”方法。

我不清楚,我们是否应该为每个想要听的对象创建一个新类。 在我看来,这不是一个优雅的解决方案。 另一方面,如果我们有一个动作监听器类用于所有(或至少很多)对象,那么我们遇到问题,因为这个类的实例不知道哪个对象正在调用“actionPerformed”方法(我们需要知道,因为actionPerformed执行的操作因此方法的调用方式而异。

在我看来,我们需要创建的每个被监听对象都是“个人”动作监听器,我们可以通过将特定值设置为动作监听器的相应字段来实现。 但我不确定这是一个标准的方法吗? 人们通常如何做到这一点?

处理这种情况的最常见方式 – 从我自己的个人经验来看 – 就是简单地创建一个匿名的内联类。 喜欢这个:

 listenedObject.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { // Your action handling code in here } }); 

而且我经常看到人们调用包含listenedObject的对象的方法。 例如,在具有按钮的Dialog中:

 myOkayButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { okayButtonPressed(); } }); 

然后在对话框类中:

 private void okayButtonPressed() { // Do what we need to do } 

Personnaly,如果可能的话,我更喜欢使用Action类(作为AbstractAction的子类的示例)而不是简单地依赖于动作侦听器。 这样,我可以为原始窗口小部件提供名称,图标,工具提示等等……

我总是发现有用的方法(用于导航 )是创建一个匿名内部类,然后委托给外部类:

 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方法然后有很多丑陋的if-else比较来确定哪个按钮实际上已经被压力 – 根本不是OO!

你当然不应该过分担心这种事情的性能方面 – 它们极端可能微不足道! 过早优化是一件坏事

我一直觉得有用的方法是创建一个单独的类来实现ActionListener接口以及执行该操作所需的所有其他方法。 这样,动作不依赖于特定对象,可以通过按钮,菜单等触发。我猜有点像Command模式 。 它使代码简单。

匿名类不可重用。

重定向到包含listenedObject的对象会导致难以维护的巨大类。

请注意,出于某种原因,removeActionListener方法存在。 如果您收听的对象将死于处理事件的对象,则可以跳过侦听器。 但是,如果组件侦听从外部源提供的模型,则应在addNotify中添加侦听器并在removeNotify方法中删除它们。 否则你可能会有一个memory leaks。

也许它实际上并非目前,但我相信在不久的将来(在Java 7发布之后)这样的事情将是常见的方式:

 listenedObject.addActionListener ( #{doSmth();} );