Java, классы большого GUI, со многими ActionListeners; лучший способ организовать слушателей?

Я разрабатываю java-программы в течение 1½ года. В настоящее время я работаю над летним проектом, который включает в себя довольно большой графический интерфейс пользователя.

Мой графический интерфейс состоит из нескольких панелей с вкладками. Каждая панель имеет свой класс. Каждая панель имеет несколько кнопок jButtons.

Теперь я подошел к точке, где в моих классах с вкладками было так много анонимных внутренних классов (для ActionListeners), что я уверен, что должен быть лучший способ; если не для эффективности, то для ремонтопригодности - это становится довольно беспорядок.

Мой вопрос таков: лучше ли организовать слушателей, когда их у каждого из них есть в каждом классе? Я думал о кластеризации слушателей в соответствующих классах - например, следующий пример кода:

public class SomeListeners implements ActionListener{
 @Override
 public void actionPerformed(ActionEvent e){
 String command = e.getActionCommand();
 switch(command){
 case "This button":
 doThis();
 break;
 case "That button":
 doThat();
 break; 
 }
 } 
}

Или может быть еще лучший способ?

Заранее спасибо:)

6 ответов

Вы можете попробовать следующий подход:

Используйте реальные классы вместо анонимных классов. Каждый ListenerClass реализует только один вариант использования/функциональность. Имя класса должно описывать UseCase. Затем вы можете организовать классы в одном или нескольких пакетах, чтобы сгруппировать их по категориям, которые соответствуют используемым случаям, которые реализует Listener в пакете.

Это означает, что вы создаете иерархию абстракции, которая организует такие функции, как древовидная структура.

Если через некоторое время кто-то должен поддерживать Слушателей, он может найти Слушателя, сначала ищет пакет, который подходит для UseCase, а затем для самой UseCase. Поскольку у вас будет меньше пакетов, тогда Classes будет проще и быстрее найти Listener.

Еще один способ подумать: если у вас так много событий на одной вкладке, что вы получаете проблемы с организацией их в коде, как вы их визуализируете на вкладке? Можете ли вы справиться с этим эргономично для пользователя? Может быть, решение может состоять в разделении функциональности на более чем одну Tab? Но поскольку я не знаю вашего пользовательского интерфейса, я не могу сказать слишком много об этом.


Я бы рекомендовал использовать один класс из типа javax.swing.AbstractAction

Пример:

Action leftAction = new LeftAction(); //LeftAction code is shown later
...
button = new JButton(leftAction)
...
menuItem = new JMenuItem(leftAction);
leftAction = new LeftAction("Go left", anIcon,
 "This is the left button.",
 new Integer(KeyEvent.VK_L));

...

class LeftAction extends AbstractAction {
 public LeftAction(String text, ImageIcon icon,
 String desc, Integer mnemonic) {
 super(text, icon);
 putValue(SHORT_DESCRIPTION, desc);
 putValue(MNEMONIC_KEY, mnemonic);
 }
 public void actionPerformed(ActionEvent e) {
 displayResult("Action for first button/menu item", e);
 }
}


Per duffymo: используйте инъекцию зависимостей и пройдите в Listeners. Это даст вам возможность повторно использовать и изменять их по своему усмотрению.

Для меня (на воздушной подушке): Это не должно быть Spring, поскольку Guice будет работать нормально. И это будет хорошо работать с предложением treeno, а также предложением Тима Herold (1+ к ним обоим). Все это касается наилучшего возможного ослабления сцепления и сцепления.


что-то вроде этого кода

public class SomeListeners implements ActionListener{
 @Override
 public void actionPerformed(ActionEvent e){
 String command = e.getActionCommand();
 switch(command){
 case "This button":
 doThis();
 break;
 case "That button":
 doThat();
 break; 
 }
 } 
}


В какой-то момент анонимные внутренние классы переходят от "удобного" к злобному беспорядку. Вы прошли эту точку.

Как и Тим, я предлагаю вам использовать AbstractAction. Однако для расширения создайте свой собственный абстрактный подкласс, который может читать его имя, значок, описание (для всплывающих подсказок) и т.д. Из файла конфигурации. Таким образом, вы можете интернационализировать код, а другие (маркетинг) могут легко менять кнопки с "Сохранить" на "SuperSomethingTM" или что-то еще. И графический художник может легко изменить значок. Расширьте этот класс для фактической реализации.

Одним из дополнительных преимуществ AbstractAction является то, что они могут быть отключены. Итак, если никаких изменений не будет сохранено, вы можете легко отключить меню "Сохранить", кнопку "Сохранить" и значок "Сохранить" на панели инструментов.

Существуют различные способы хранения и чтения этой информации конфигурации. Один из них - ResourceBundle.

(напечатано на моем Nook, так что это на короткой стороне, другие могут свободно расширяться)


JSR 296 должен был обеспечить основу для того, что вы делаете, и многое другое, о котором упоминалось здесь (i18n, Actions и т.д.). Наиболее активная реализация - это Better Swing Application Framework или BSAF. Хорошую статью о том, как использовать любую реализацию JSR 296, можно найти здесь.

licensed under cc by-sa 3.0 with attribution.