Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing anonymous listener

When trying to adopt the style of implementing a listener using anonymous or nested class in order to hide the notification methods for other uses than listening (i.e. I don't want anybody to be able to call actionPerformed). For example from java action listener: implements vs anonymous class:

public MyClass() {
    myButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            //doSomething
        }
    });
}

The question is if theres an elegant way to remove the listener again using this idiom? I figured out that the instantiation of ActionListener does not produce equal objects every time so Collection.remove() won't remove the originally added object.

In order to be considered equal the listeners should have the same outer this. To implement equals I would need to get hold of outer this for the other object. So it will go something like this (which I find a little bit clumpsy):

interface MyListener {
    Object getOuter();
}

abstract class MyActionListener extends ActionListener
    implement MyListener {
}

public MyClass() {
    myButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            // doSomething on MyClass.this
        }
        public Object getOuter() {
           return MyClass.this;
        }
        public boolean equals(Object other)
        {
           if( other instanceof MyListener )
           {
              return getOuter() == other.getOuter();
           }
           return super.equals(other);
        });
    }
 }

Or will I be forced to keep the ActionListener object as a (private) member of the outer class?

like image 440
skyking Avatar asked Apr 29 '15 11:04

skyking


2 Answers

Well that's the beauty of anonymous classes - they're anonymous :-)

No, there's no similarly elegant idiom to remove the listener again. The only way is to iterate through getActionListeners() and remove the one you want. Of course, if there is only one it's as easy as:

myButton.removeActionListener( myButton.getActionListeners()[ 0 ] );

which is not too ugly.

like image 31
Anders R. Bystrup Avatar answered Sep 17 '22 23:09

Anders R. Bystrup


Assign your anonymous listener to a private local variable, e.g.

public MyClass() {
    private Button myButton = new Button();
    private ActionListener actionListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            //doSomething
        }
    };
    private initialize() {
        myButton.addActionListener(actionListener);
    }
}

Later you can use the private variable actionListener to remove it again.

like image 191
Uwe Plonus Avatar answered Sep 16 '22 23:09

Uwe Plonus