问题
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?
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/29942999/removing-anonymous-listener