Java Swing: удаление анонимного ActionListener из компонента
Я создал массив JButtons
с анонимным ActionListeners
, и при определенных условиях я хочу удалить все ActionListeners
, но для метода .removeActionListeners
требуется ActionListener
в качестве аргумента. Как я могу удалить прослушиватели действий?
for (int i=0; i < button.length; i++){
button[i] = new JButton();
button[i].addActionListener(listener.new ButtonListener());
}
Ответы
Ответ 1
Вы можете получить их с помощью getActionListeners:
for( JButton currentButton: button ) {
for( ActionListener al : currentButton.getActionListeners() ) {
currentButton.removeActionListener( al );
}
}
Я не уверен, что он будет выброшен ConcurrentModificationException
.
Ответ 2
Я понимаю ваш вопрос, и, как предложили другие, повторяя все действия, слушатели из класса клиента могут решить вашу непосредственную проблему.
-
В этом случае то, что вы действительно пытаетесь сделать, это расширить функциональность JButton, и это один из способов решения этой проблемы - расширьте JButton и добавьте метод под названием removeAllActionListeners()
(который не принимает никаких параметров).
- Внутри этого метода вы можете выполнять итерацию
через всех слушателей действий и
удалить их. Я думаю, что это лучше
дизайн, если вы делаете это здесь, чем в
класс клиента.
-
Если вы не хотите этого делать, я думаю, что предложение Tom Hawtin использовать состояние в вашем ButtonListener - хорошая идея.
-
В противном случае у вас всегда есть возможность отказаться от очень "хакерского" способа, который заключается в том, чтобы хранить коллекцию слушателей действий в вашем классе клиента.
-
Map<JButton, ButtonListener>
(если всегда будет только один прослушиватель на кнопку) или
-
Map<JButton, List<ButtonListener>>
(если может быть несколько слушателей на кнопку) - это то, что я могу использовать.
Я думаю, что методы 1 и 2 предпочтительны, а метод 3 указывает на плохой дизайн (но гораздо проще взломать вместе).
Обратите внимание: если вы действительно используете метод 1 или что-то подобное, убедитесь, что методы или атрибуты, к которым вы обращаетесь, являются потокобезопасными (как упоминается OscarRyz), а если нет, используйте synchronized
для обеспечения безопасности потока.
Ответ 3
Вы не можете. Никто не ссылается на эти объекты. Чтобы их можно было удалить, вам необходимо сохранить его как член/переменную данных в вашем коде, а затем передать эту переменную методу removeActionListener()
. Однако вы можете использовать метод getActionListeners()
для получения массива всех объектов ActionListener
, связанных с Button
. Затем вам нужно будет выяснить, какой из них удалить, но если есть только один, это должно быть легко; -)