tags:

views:

70

answers:

3

I created an array of JButtons with anonymous ActionListeners

and under certain conditions I want to remove all the ActionListeners, but the .removeActionListeners method requires an ActionListener as an argument. How would I go about removing the Action Listeners?

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

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 ActionListener objects 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 ;-)

Chris Thompson
+1  A: 

You can get them with: getActionListeners method:

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

I'm not sure if it will thrown a ConcurrentModificationException though.

OscarRyz
Probably not...I'm willing to bet it stores the listeners internally as an ArrayList and then copies them into an array of ActionListeners to return them. Curious to see if it would though...
Chris Thompson
Nobody would return an internal array, would they? (Which doesn't resize anyway.)
Tom Hawtin - tackline
for( ActionListener al : button.getActionListeners() ) That won't compile but it was a nice idea
comp sci balla
for (JButton b: button) for( ActionListener al : b.getActionListeners() ) b.removeActionListener(al); That works
comp sci balla
Well yeap... you have to do it for each button. I'll update
OscarRyz
+1  A: 

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.

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

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 synchronized to ensure thread safety.

bguiz