Arhn - архитектура программирования

прослушиватель действий для JDialog для нажатой кнопки

У меня есть основное приложение, где есть таблица со значениями. Затем я нажимаю кнопку «Добавить», появляется новое всплывающее окно типа CUSTOM (я сделал это сам) JDialog. Там я могу ввести значение, поставить несколько галочек и нажать «Подтвердить». Поэтому мне нужно прочитать этот ввод из диалогового окна, чтобы я мог добавить это значение в таблицу в основном приложении. Как я могу прослушать, когда нажата кнопка «подтвердить», чтобы после этого я мог прочитать это значение?

addISDialog = new AddISDialog();
addISDialog.setVisible(true);
addISDialog.setLocationRelativeTo(null);
//somekind of listener...
//after "Confirm" button in dialog was pressed, get value
value = addISDialog.ISName;

  • Я реализовал прослушиватель внутри JDialog, и я могу слушать кнопку внутри этого диалога, но мне нужно слушать эту кнопку вне диалога - в основном приложении, где я вызвал этот диалог 15.12.2011
  • Вы можете редактировать класс JDialog? Если это так, вы можете передать ActionEvent другому классу, реализующему интерфейс ActionListener, и этот класс сможет делать то, что вы хотите. 15.12.2011
  • Я сам сделал AddISDialog (открытый класс AddISDialog расширяет JDialog, реализует ActionListener), так что да, я могу его редактировать. Что вы имеете в виду, перенаправляя ActionEvent в другой класс? Как я могу это сделать? 15.12.2011
  • Один из способов сделать это — зарегистрировать PropertyChangeListener в экземпляре JDialog и заставить экземпляр JDialog использовать экземпляр PropertyChangeSupport, который вызовет событие изменения свойства, указывающее, что была нажата кнопка подтверждения. 15.12.2011
  • добавить это значение в таблицу Вы можете передать модель таблицы в диалоговое окно в конструкторе (или реализовать метод setModel() в пользовательском диалоговом окне). Кстати, чтобы быстрее получить помощь, опубликуйте SSCCE. 15.12.2011
  • addISDialog.setLocationRelativeTo(null); должен вероятно быть чем-то вроде addISDialog.setLocationRelativeTo(mainApplication); 15.12.2011

Ответы:


1

Если диалоговое окно исчезнет после того, как пользователь нажмет подтверждение:

  • и вы хотите, чтобы диалоговое окно вело себя как модальный JDialog, тогда это легко, поскольку вы знаете, где в коде будет находиться ваша программа, как только пользователь завершит работу с с диалогом - это будет сразу после того, как вы вызовете setVisible(true) в диалоге. Таким образом, вы просто запрашиваете состояние диалогового объекта в строках кода сразу после вызова setVisible(true) в диалоговом окне.
  • Если вам нужно иметь дело с немодальным диалоговым окном, вам нужно добавить WindowListener в диалоговое окно, чтобы получать уведомления, когда окно диалогового окна становится невидимым.

Если диалог должен оставаться открытым после того, как пользователь нажмет подтверждение:

  • Тогда вам, вероятно, следует использовать PropertyChangeListener, как было предложено выше. Либо так, либо предоставьте диалоговому объекту общедоступный метод, который позволяет внешним классам добавлять ActionListener к кнопке подтверждения.

Для получения более подробной информации, пожалуйста, покажите нам соответствующие фрагменты вашего кода или, что еще лучше, sscce.

Например, чтобы позволить классу JDialog принимать внешних слушателей, вы можете дать ему JTextField и JButton:

class MyDialog extends JDialog {
   private JTextField textfield = new JTextField(10);
   private JButton confirmBtn = new JButton("Confirm");

и метод, который позволяет внешним классам добавлять ActionListener к кнопке:

public void addConfirmListener(ActionListener listener) {
  confirmBtn.addActionListener(listener);
}

Затем внешний класс может просто вызвать метод `addConfirmListener(...) для добавления своего ActionListener в confirmBtn.

Например:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class OutsideListener extends JFrame {
   private JTextField textField = new JTextField(10);
   private JButton showDialogBtn = new JButton("Show Dialog");
   private MyDialog myDialog = new MyDialog(this, "My Dialog");

   public OutsideListener(String title) {
      super(title);
      textField.setEditable(false);

      showDialogBtn.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent arg0) {
            if (!myDialog.isVisible()) {
               myDialog.setVisible(true);
            }
         }
      });

      // !! add a listener to the dialog's button
      myDialog.addConfirmListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            String text = myDialog.getTextFieldText();
            textField.setText(text);
         }
      });

      JPanel panel = new JPanel();
      panel.add(textField);
      panel.add(showDialogBtn);

      add(panel);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(400, 300);
   }

   private static void createAndShowGui() {
      JFrame frame = new OutsideListener("OutsideListener");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyDialog extends JDialog {
   private JTextField textfield = new JTextField(10);
   private JButton confirmBtn = new JButton("Confirm");

   public MyDialog(JFrame frame, String title) {
      super(frame, title, false);
      JPanel panel = new JPanel();
      panel.add(textfield);
      panel.add(confirmBtn);

      add(panel);
      pack();
      setLocationRelativeTo(frame);
   }

   public String getTextFieldText() {
      return textfield.getText();
   }

   public void addConfirmListener(ActionListener listener) {
      confirmBtn.addActionListener(listener);
   }
}

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

Правка 2
Пример использования модального диалогового окна:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class OutsideListener2 extends JFrame {
   private JTextField textField = new JTextField(10);
   private JButton showDialogBtn = new JButton("Show Dialog");
   private MyDialog2 myDialog = new MyDialog2(this, "My Dialog");

   public OutsideListener2(String title) {
      super(title);
      textField.setEditable(false);

      showDialogBtn.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent arg0) {
            if (!myDialog.isVisible()) {
               myDialog.setVisible(true);

               textField.setText(myDialog.getTextFieldText());
            }
         }
      });

      JPanel panel = new JPanel();
      panel.add(textField);
      panel.add(showDialogBtn);

      add(panel);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(400, 300);
   }

   private static void createAndShowGui() {
      JFrame frame = new OutsideListener2("OutsideListener");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyDialog2 extends JDialog {
   private JTextField textfield = new JTextField(10);
   private JButton confirmBtn = new JButton("Confirm");

   public MyDialog2(JFrame frame, String title) {
      super(frame, title, true); // !!!!! made into a modal dialog
      JPanel panel = new JPanel();
      panel.add(new JLabel("Please enter a number between 1 and 100:"));
      panel.add(textfield);
      panel.add(confirmBtn);

      add(panel);
      pack();
      setLocationRelativeTo(frame);

      ActionListener confirmListener = new ConfirmListener();
      confirmBtn.addActionListener(confirmListener); // add listener
      textfield.addActionListener(confirmListener );
   }

   public String getTextFieldText() {
      return textfield.getText();
   }

   private class ConfirmListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {
         String text = textfield.getText();
         if (isTextValid(text)) {
            MyDialog2.this.setVisible(false);
         } else {
            // show warning
            String warning = "Data entered, \"" + text + 
               "\", is invalid. Please enter a number between 1 and 100";
            JOptionPane.showMessageDialog(confirmBtn,
                  warning,
                  "Invalid Input", JOptionPane.ERROR_MESSAGE);
            textfield.setText("");
            textfield.requestFocusInWindow();
         }
      }
   }

   // true if data is a number between 1 and 100
   public boolean isTextValid(String text) {
      try {
         int number = Integer.parseInt(text);
         if (number > 0 && number <= 100) {
            return true;
         }
      } catch (NumberFormatException e) {
         // one of the few times it's OK to ignore an exception
      }
      return false;
   }

}
15.12.2011
  • Я думаю, что понял вашу идею, но теперь есть еще одна связанная проблема: перед отправкой действия слушателю мне нужно подтвердить данные в диалоге при нажатии кнопки «Подтвердить». Только когда данные верны (когда верны - диалог закрывается, иначе - нет), нужно прочитать значение для дальнейших действий. Я могу отправить какое-то уведомление слушателю из диалогового класса, но я не знаю, как 15.12.2011
  • Тогда не следуйте приведенному выше коду. Что вам нужно сделать, так это сделать диалоговое окно модальным, а действие кнопки подтверждения подтвердить данные и закрыть диалоговое окно только в том случае, если данные в порядке. Затем ваша основная программа запросит класс диалогового окна для данных в коде сразу после вызова setVisible(true) в диалоговом окне. 16.12.2011
  • @PooLaS: см. редактирование примера модального диалогового решения выше. 16.12.2011
  • Я сделал несколько общедоступных методов в диалоговом классе, поэтому я дважды проверяю данные - в диалоговом окне для закрытия и в основном для ввода новых данных. Спасибо, парни 17.12.2011
  • Это не работает, потому что, если я нажму x в окне, оно сработает как кнопка «Подтвердить», что не является предполагаемым поведением. 19.12.2019

  • 2

    Почему бы вам не проверить, виден ли ваш jDialog?

    yourJD.setVisible(true);
    while(yourJD.isVisible())try{Thread.sleep(50);}catch(InterruptedException e){}
    

    это тоже работает.

    26.10.2016
  • Что-то пошло не так с форматированием вашего кода. Обратитесь к справке по уценке - код и предварительно отформатированный текст и, пожалуйста, отредактировать свой пост. 26.10.2016

  • 3
    import javax.swing.JOptionPane;
    

    или если вы уже качаетесь

    import javax.swing.*;
    

    вас прикроют.

    После условного запуска JOptionPane для отправки вашего предупреждения или любого другого модального сообщения:

        JOptionPane.showMessageDialog(
                null,
                "Your warning String: I can't do that John",
                "Window Title",
                JOptionPane.ERROR_MESSAGE);
    

    проверьте параметры для JOptionPane.*, чтобы определить тип сообщения.

    17.09.2013
  • Этот ответ не решает проблему, которую пытается решить ОП. 11.02.2014
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..