移除匿名监听器

5
当尝试采用使用匿名或嵌套类实现监听器的风格时,目的是为了隐藏通知方法以防止被用于除监听之外的其他用途(例如,我不希望任何人能够调用actionPerformed)。例如来自 Java ActionListener:implements vs anonymous class 的示例:
public MyClass() {
    myButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            //doSomething
        }
    });
}

问题是是否有一种优雅的方法使用这个习语来删除监听器?我发现ActionListener的实例化不会每次产生相同的对象,因此Collection.remove()将无法删除最初添加的对象。
为了被认为是相等的,监听器应该具有相同的外部this。要实现equals,我需要获取其他对象的外部this。所以它将变成这样(我觉得有点笨重):
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);
        });
    }
 }

还是说我必须将ActionListener对象作为外部类的(私有)成员变量来保存?


你可以通过在匿名类中重写equals()方法使这些对象相等,对吧? - Alex Salauyou
为什么不能使用removeActionListener? - Chetan Kinger
removeActionListener 的实现取决于被移除的对象与提供给 removeActionListener 的对象相等。我编辑了问题,并解释了我认为实现 equals() 将会有一些额外开销。 - skyking
2个回答

4
将您的匿名监听器分配给一个私有局部变量,例如:
public MyClass() {
    private Button myButton = new Button();
    private ActionListener actionListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            //doSomething
        }
    };
    private initialize() {
        myButton.addActionListener(actionListener);
    }
}

稍后,您可以使用私有变量 actionListener 再次移除它。

虽然这不是我期望的答案,但看起来需要将侦听器分配给一个局部变量。 - skyking

4

匿名类的美丽之处在于它们是匿名的。

没有同样优雅的习语来移除监听器。唯一的方法是通过遍历 getActionListeners() 并删除你想要的那个。当然,如果只有一个监听器,那就很容易了:

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

尽量不丑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接