Java: прозрачно обрабатывать событие изменения состояния

#java #oop

#java #ооп

Вопрос:

У меня есть представление, в котором есть несколько кнопок «флаг» ( JToggleButton ). Когда пользователь нажимает кнопку с флажком, я хочу обновить массив, который отслеживает, какие кнопки отмечены. Это довольно просто, и вот что я сделал:

 ...
   bflag[i].addItemListener(this); //View listens to state change
...

void itemStateChange(ItemEvent ie) {
   try {
      jtb = (JToggleButton)ie.getSource();
      //Update mark array
   }
   catch (ClassCastException cce) {}
}
  

Это работает просто отлично, но это некрасиво с try / catch. Я бы предпочел сделать что-то вроде этого:

 void itemStateChange(ItemEvent ie) {
   handleStateChange(ie.getSource());
}

void handleStateChange(JToggleButton jtb) {
   //handle state change
}

void handleStateChange(Object o) {}
  

Это намного приятнее, но единственная проблема заключается в том, что Object метод будет срабатывать, даже если источником является JToggleButton (потому что, в конце концов, JToggleButton это Object an).

Я также рассматривал возможность использования двойной отправки, но для этого потребовалось бы переопределить JToggleButton метод, который запускает itemStateChange() , а я не знаю, что это такое (и это кажется небезопасным).

Есть предложения о том, как заставить это работать без try / catch, условной проверки и т.д.?

Ответ №1:

Я думаю, вам нужно будет явно проверить тип.

   if(ie.getSource() instanceof JToggleButton){
      //toggle button logic
  }else{
      //something else
  }
  

В качестве альтернативы вы можете использовать анонимные внутренние классы для реализации ваших слушателей и вообще избежать необходимости проверять источник.


Что-то вроде этого:

  toggleBtn.addItemListener(new ItemListener(){
         public void itemStateChange(ItemEvent ie){
            //handle toggle button event
         }
 });
  

Комментарии:

1. Я думаю, что это намного уродливее, чем проверка приведения (или, по крайней мере, одинаково уродливо). Пожалуйста, подробнее остановитесь на схеме «анонимный внутренний класс».

2. @tandu Даже если оператор instanceof не улучшает красоту кода, это может быть предпочтительнее использования исключения в качестве механизма управления потоком. Я также обновил ответ примером использования анонимного внутреннего класса.

3. Анонимный внутренний класс должен был бы знать о представлении, чтобы обновить массив. Это не так.

4. Внутренний класс может обращаться к любому члену содержащего его класса. Таким образом, если массив доступен из содержащего его класса, он должен быть доступен из внутреннего класса.

5. Ах, вы правы. Но единственная проблема заключается в том, что массив необходимо обновить относительно кнопки переключения (есть несколько кнопок переключения), и анонимный класс также не может определить, какая кнопка вызвала событие!