Java Swing:如何从组件中删除匿名 ActionListener

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4048006/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:55:51  来源:igfitidea点击:

Java Swing: How to remove an anonymous ActionListener from a component

javaswing

提问by comp sci balla

I created an array of JButtonswith anonymous ActionListenersand under certain conditions I want to remove all the ActionListeners, but the .removeActionListenersmethod requires an ActionListeneras an argument. How would I go about removing the action listeners?

我创建了一个JButtonswith 匿名数组,ActionListeners并且在某些条件下我想删除所有ActionListeners,但是该.removeActionListeners方法需要 anActionListener作为参数。我将如何删除动作侦听器?

for (int i=0; i < button.length; i++){
    button[i] = new JButton();
    button[i].addActionListener(listener.new ButtonListener());
}

回答by Chris Thompson

You can't. Nobody has a reference to those objects. In order to be able to remove them you'll need to store it as a data member/variable in your code and then pass that variable to the removeActionListener()method. However, what you could do is use the getActionListeners()method to get an array of all of the ActionListenerobjects associated with the Button. You'll then need to figure out which one to remove, but if there's only one, that should be easy ;-)

你不能。没有人引用这些对象。为了能够删除它们,您需要将其作为数据成员/变量存储在代码中,然后将该变量传递给removeActionListener()方法。但是,您可以做的是使用该getActionListeners()方法获取ActionListenerButton. 然后,您需要确定要删除哪一个,但如果只有一个,那应该很容易 ;-)

回答by OscarRyz

You can get them with: getActionListenersmethod:

您可以使用以下方法获取它们:getActionListeners方法:

for( JButton currentButton: button ) {
    for( ActionListener al : currentButton.getActionListeners() ) {
        currentButton.removeActionListener( al );
    }
}

I'm not sure if it will thrown a ConcurrentModificationExceptionthough.

我不确定它是否会抛出一个ConcurrentModificationException

回答by bguiz

I understand your question, and as others have suggested, iterating through all the actions listeners from the client class may solve your immediate problem.

我理解您的问题,正如其他人所建议的那样,迭代来自客户端类的所有操作侦听器可能会解决您的直接问题。

  1. H/w in this case, what you are really trying to do is extend the functionality of a JButton, and that is one way to tackle this problem - extend JButton and add a method called removeAllActionListeners()(which does not take any parameters).

    • Inside this method you can iterate through all action listeners and remove them. I think it is better design if you do this here than in the client class.
  2. If you don't want to do that, then I think Tom Hawtin's suggestion to use state within your ButtonListener is a good idea.

  3. Failing which, you always have the option of falling back on a very "hacky" way, which is to store a collection of the action listeners in your client class.

    • Map<JButton, ButtonListener>(if there's always only going to be one listener per button), or
    • Map<JButton, List<ButtonListener>>(if there can be multiple listeners per button) is what I might use.
  1. 在这种情况下,您真正​​想做的是扩展 JButton 的功能,这是解决此问题的一种方法 - 扩展 JButton 并添加一个调用的方法removeAllActionListeners()(不带任何参数)。

    • 在此方法中,您可以遍历所有动作侦听器并删除它们。我认为如果你在这里这样做比在客户端类中进行更好的设计。
  2. 如果您不想这样做,那么我认为 Tom Hawtin 在您的 ButtonListener 中使用状态的建议是一个好主意。

  3. 如果失败,您总是可以选择退回到一种非常“hacky”的方式,即在您的客户端类中存储一组动作侦听器。

    • Map<JButton, ButtonListener>(如果每个按钮总是只有一个听众),或
    • Map<JButton, List<ButtonListener>>(如果每个按钮可以有多个侦听器)是我可能使用的。

I think methods 1and 2are preferable, and method 3indicates poor design (but is much easier to hack together).

我认为方法12更可取,方法3表明设计不佳(但更容易一起破解)。

Note that, if you do indeed use method 1, or something similar, check that the methods or attributes you are accessing are thread safe (as mentioned by OscarRyz), and if not, use synchronizedto ensure thread safety.

请注意,如果您确实使用了方法1或类似的方法,请检查您正在访问的方法或属性是否是线程安全的(如 OscarRyz 所述),如果不是,请使用synchronized以确保线程安全。