Проблема с ActionListener и ActionEvent

У меня техническая проблема с моим ActionListener. Видите ли, у меня есть одна кнопка, которая имеет несколько возможных действий, в зависимости от того, какой элемент меню был нажат ранее. Поэтому я создал ActionListener с ActionEvent e. Предполагается, что «e» проверяет одно из трех условий (потому что у меня есть 3 элемента меню — «Добавить», «Удалить» и «Изменить»), и в зависимости от того, какой из них выбран, происходящие действия отличаются друг от друга.

Проблема в том, что ни одно из условий e.getSource() никогда не проверяется (хотя я проверял их несколько раз. Я застрял в этой проблеме уже 3 дня, так что, честно говоря, небольшая помощь была бы очень Добро пожаловать!

А пока, счастливого Рождества и счастливого Нового года!

 private void buttonValidateActionPerformed(java.awt.event.ActionEvent evt){                                              
    // TODO add your handling code here:
  ActionListener l = (ActionEvent e) -> {
     if(e.getSource()==menuItemAdd)
     {
         System.out.println("eureka!");
         buttonResearch.setEnabled(false);
      if (evt.getSource()== buttonValidate)
        {

        DataTransac dt = new DataTransac();
        dt.ajouterProgrammeurs("...");

        }
     }
     if(e.getSource()==itemDelete)
     {
         if(evt.getSource()== buttonValidate)
         {

        DataTransac dt = new DataTransac();
        dt.deleteProgrammers("...");

         }
     }
     if(e.getSource()==itemModify)
     {
         if(evt.getSource()==buttonValidate)
         {

        DataTransac dt = new DataTransac();
       dt.modifyProgrammeurs("...");

         }
     }


  };

  menuItemAdd.addActionListener(l);
  itemDelete.addActionListener(l);
  itemModify.addActionListener(l);




  /*

   */

}                                   

Редактировать: я попробовал метод ".equals()", однако он тоже не сработал.

ActionListener l = (ActionEvent e) -> {
     if(e.equals(menuItemAjouter))
     {
         System.out.println("eureka!");
         buttonResearch.setEnabled(false);
      if (evt.getSource()== buttonValidate)
        {

        DataTransac dt = new DataTransac();

        dt.addProgrammers("...");

        }
        ...

Редактировать 2: после тестирования метода хеширования я случайно наткнулся на странную ошибку. Сначала, когда я нажимаю кнопку «Добавить» MenuItem, а затем кнопку «Подтвердить», ничего не происходит. Однако, если я нажму кнопку «Подтвердить», затем «Добавить элемент меню, код сработает... Я собираюсь попробовать другие условия.


person Fares    schedule 24.12.2018    source источник
comment
Не добавляйте ActionListener внутрь другого ActionListener. Добавьте ActionListener к каждому пункту меню ровно один раз, а не каждый раз, когда пользователь нажимает кнопку. Пусть этот слушатель сохранит ActionEvent в закрытом поле, чтобы его мог использовать отдельный ActionListener кнопки.   -  person VGR    schedule 24.12.2018
comment
@BrentR Нет, не работает, но все равно спасибо за попытку!   -  person Fares    schedule 24.12.2018
comment
Пожалуйста, отредактируйте свой вопрос и покажите, что еще вы пробовали. Не заменяйте текущий код, так как это может привести к тому, что текущие ответы будут казаться бессмысленными. Добавьте новый код в конец вопроса.   -  person VGR    schedule 24.12.2018
comment
@VGR Я не понимаю, когда вы говорите о добавлении ActionListener внутри другого ActionListener. ActionListeners добавляются после последней скобки и точки с запятой. Можете ли вы перефразировать то, что вы сказали, пожалуйста?   -  person Fares    schedule 24.12.2018
comment
buttonValidateActionPerformed(ActionEvent evt) очевидно вызывается из ActionListener кнопки. Этот метод вызывается, когда пользователь нажимает вашу кнопку. Внутри этого метода вы добавляете новый ActionListener к каждому пункту меню, чего делать не следует. Как теперь выглядит код, при первом нажатии кнопки пользователем элементы меню не имеют собственных ActionListeners. Когда пользователь нажимает кнопку во второй раз, каждый пункт меню имеет один ActionListener. В следующий раз каждый пункт меню будет иметь два ActionListeners. Потом три, потом четыре и так далее.   -  person VGR    schedule 24.12.2018


Ответы (2)


У меня есть одна кнопка, которая имеет несколько возможных действий, в зависимости от того, какой элемент меню был нажат ранее.

Источником ActionEvent, запускаемого в ответ на нажатие кнопки, является кнопка, которая была нажата. Вы не можете использовать это, чтобы узнать об элементах управления, с которыми ранее взаимодействовал пользователь. По крайней мере, не напрямую.

Поток управления в вашем графическом интерфейсе мне не совсем ясен, но ваши альтернативы делятся на несколько категорий:

  • Используйте разные кнопки вместо того, чтобы делать одну и ту же кнопку ответственной за разные действия.
  • Если вы хотите продолжить настройку какого-либо режима с помощью пунктов меню, то сохраните текущий режим в некоторой общей переменной, доступной для обработчика событий кнопки, и пусть он использует ее вместо источника действия.
  • Или, возможно, ваши пункты меню изменяют, какие из нескольких целевых ActionListeners установлены на кнопке, чтобы выбор эффекта мог управляться вызываемым слушателем.

Любой из первых двух гораздо предпочтительнее последнего, который я предлагаю главным образом для полноты картины.

person John Bollinger    schedule 24.12.2018

Это очень запутанный вопрос.

Я собираюсь начать с того, что использование getSource обычно является плохой идеей. Это связывает это действие с компонентом — именно та проблема, от которой слушатели должны избавиться. Это как вернуться к JDK 1.00, а этого никто не хочет, только теперь мы добавили дополнительные сложности. Кроме того, Swing имеет тенденцию использовать составные компоненты (это шаблон проектирования Composite).

Давайте посмотрим на ваш код.

private void buttonValidateActionPerformed(java.awt.event.ActionEvent evt){
// СЛЕДУЕТ добавить сюда код обработки: ActionListener l = (ActionEvent e) -> {

Что здесь происходит. Слушатель настоящего действия, пожалуйста, встаньте. Поместите несколько printfs (или используйте отладчик), чтобы убедиться, что поток управления соответствует ожиданиям.

 if(e.getSource()==menuItemAdd)
 {
     System.out.println("eureka!");
     buttonResearch.setEnabled(false);
  if (evt.getSource()== buttonValidate)

Я предполагаю, что где-то вы также написали.

buttonValidate = menuItemAdd;

Стоит проверить в вашем слушателе, что у вас все настроено правильно. Попробуйте несколько printfs вверху.

System.err.println("e.getSource(): "+System.identityHashCode(e.getSource());
System.err.println("buttonValidate: "+System.identityHashCode(buttonValidate));
System.err.println("menuItemAdd: "+System.identityHashCode(menuItemAdd));
System.err.println("itemDelete: "+System.identityHashCode(itemDelete));
System.err.println("itemModify: "+System.identityHashCode(itemModify));

Если вы где-то испортили какое-то назначение, это должно проявиться как неожиданные хэш-коды объектов.

Я предлагаю сделать резервную копию кода и добавить один прослушиватель действий для каждого действия. Вам не нужны эти if операторы повсюду. Затем в каждом слушателе они могут проверить состояние, если это необходимо.

person Tom Hawtin - tackline    schedule 24.12.2018