9

I have main application where is table with values. Then, I click "Add" button, new CUSTOM (I made it myself) JDialog type popup comes up. There I can input value, make some ticks and click "Confirm". So I need to read that input from dialog, so I can add this value to table in main application. How can I listen when "confirm" button is pressed, so I can read that value after that?

addISDialog = new AddISDialog();
addISDialog.setVisible(true);
addISDialog.setLocationRelativeTo(null);
//somekind of listener...
//after "Confirm" button in dialog was pressed, get value
value = addISDialog.ISName;
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Paulius Vindzigelskis
  • 2,121
  • 6
  • 29
  • 41
  • I implemented listener inside JDialog and I can listen to button inside that dialog, but I need to listen to that button outside dialog - in main application, where I called that dialog – Paulius Vindzigelskis Dec 15 '11 at 16:45
  • 1
    Can you edit the `JDialog` class? If so, you could forward the `ActionEvent` to another class that implements the `ActionListener` interface and that class can do what you want. – mre Dec 15 '11 at 16:47
  • I made AddISDialog myself (public class AddISDialog extends JDialog implements ActionListener) so yes, I can edit it. What do you mean forwarding ActionEvent to another class? How I can I do it? – Paulius Vindzigelskis Dec 15 '11 at 16:51
  • 2
    One way to do it is to register a `PropertyChangeListener` to the `JDialog` instance and have the `JDialog` instance use a `PropertyChangeSupport` instance that will fire a property change event indicating that the confirm button was pushed. – mre Dec 15 '11 at 16:54
  • *"add this value to table"* You might pass the table model to the dialog in the constructor (or implement a `setModel()` method in the custom dialog). BTW - For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Dec 15 '11 at 17:14
  • 1
    `addISDialog.setLocationRelativeTo(null);` should *probably* be something like `addISDialog.setLocationRelativeTo(mainApplication);` – Andrew Thompson Dec 15 '11 at 17:16

3 Answers3

15

If the dialog will disappear after the user presses confirm:

  • and you wish to have the dialog behave as a modal JDialog, then it's easy, since you know where in the code your program will be as soon as the user is done dealing with the dialog -- it will be right after you call setVisible(true) on the dialog. So you simply query the dialog object for its state in the lines of code immediately after you call setVisible(true) on the dialog.
  • If you need to deal with a non-modal dialog, then you'll need to add a WindowListener to the dialog to be notified when the dialog's window has become invisible.

If the dialog is to stay open after the user presses confirm:

  • Then you should probably use a PropertyChangeListener as has been suggested above. Either that or give the dialog object a public method that allows outside classes the ability to add an ActionListener to the confirm button.

For more detail, please show us relevant bits of your code, or even better, an sscce.

For example to allow the JDialog class to accept outside listeners, you could give it a JTextField and a JButton:

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

and a method that allows outside classes to add an ActionListener to the button:

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

Then an outside class can simply call the `addConfirmListener(...) method to add its ActionListener to the confirmBtn.

For example:

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);
   }
}

Caveats though: I don't recommend subclassing JFrame or JDialog unless absolutely necessary. It was done here simply for the sake of brevity. I also myself prefer to use a modal dialog for solving this problem and just re-opening the dialog when needed.

Edit 2
An example of use of a Modal dialog:

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;
   }

}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I think I got your idea, but now there is another connected problem: Before sending action to listener, I need to confirm data in dialog when pressed Confirm button. Just when data is valid (when valid - dialog closes, else - doesn't), value has to be read for further actions. I can fire some kind of notification to listener from dialog class, but I don't know how – Paulius Vindzigelskis Dec 15 '11 at 18:42
  • Then don't go by the code above. What you need to do is to make the dialog modal, and have its confirm button's action validate the data and only close the dialog if the data is OK. Then have your main program query the dialog class for the data in the code immediately after calling `setVisible(true)` on the dialog. – Hovercraft Full Of Eels Dec 15 '11 at 20:51
  • @PooLaS: see edit for an example of a modal dialog solution above. – Hovercraft Full Of Eels Dec 15 '11 at 22:29
  • 1
    I made few public methods in dialog class, so i verify data twice - in dialog for closing and in main for entering new data. Thanks guys – Paulius Vindzigelskis Dec 17 '11 at 16:12
  • This doesn't work, because if I press "x" of the window it works like "Confirm" button which is not intended behaviour – Lucas Dec 19 '19 at 09:56
0

Why don't you check if your jDialog is visible?

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

this works, also.

Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
AndreaTaroni86
  • 549
  • 12
  • 27
  • 2
    Something went wrong with your code formatting. Consult [Markdown help - Code and Preformatted Text](http://stackoverflow.com/editing-help#code) and please [edit] your post. – Bhargav Rao Oct 26 '16 at 08:50
-2
import javax.swing.JOptionPane;

or if you're already swinging

import javax.swing.*;

will have you covered.

After conditional trigger JOptionPane to send your warning or whatever modal message:

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

check your options for JOptionPane.* to determine message type.