3

I have been getting away with bash scripting along with some java (console) and python for my programming needs. Figured it's about time I tidy up my work into some graphical environment and I stumbled on a basic task that kept me hang for hours now.

The main function calls a login JDialog before starting the main app window. The JDialog instance runs a basic auth check (simple if statement) and sets a class field in the login dialog as true/false accordingly. I would love to retrieve in the calling class the result of this check and the username typed in the textbox. Seems next to impossible.

So, what is the optimal way of creating a new instance of a window (whatever is more suitable frame, dialog...) and be able to retrieve some class fields? Forms I have in mind are a little bit more complex than a yes/no answer. I should be able to bring up a login window, a settings window, or a form with parameters for a report.

Edit: Some code to sample the problem.

public class Main extends JFrame {

private JPanel contentPane;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Login login = new Login();
                login.showLogin();
                System.out.println(login.getTheText());

                Main frame = new Main();
                frame.setVisible(false);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public Main() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    setContentPane(contentPane);
}

}

public class Login extends JDialog {

private JTextField txtTest;
public void showLogin() {
    try {
        Login dialog = new Login();
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setVisible(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public String getTheText() {
    return txtTest.getText();
}
public Login() {
    setModal(true);
    setBounds(100, 100, 450, 300);
    getContentPane().setLayout(null);

    txtTest = new JTextField();
    txtTest.setText("test");
    txtTest.setBounds(112, 141, 86, 20);
    getContentPane().add(txtTest);
    txtTest.setColumns(10);

}

}

I set the text field txtTest to "test" at creation. I keep on receiving the original "test" value in Main, no matter what I type in the box.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Louis Papaloizou
  • 284
  • 1
  • 3
  • 11
  • 1
    See [this answer](http://stackoverflow.com/a/20286447/2587435) for creating a modal `JDialog` login – Paul Samsotha Jan 10 '14 at 17:46
  • You're ignoring my recommendations for some reason since you're not using a modal dialog-- why? If you have good reason to do so, please tell us why, but please don't just ignore the recs. Also please look at the link in my answer from over an hour ago. – Hovercraft Full Of Eels Jan 10 '14 at 18:14
  • I am using modal (I think) with the statement setModal(true); The text comes to the console after dialog is closed so I assumed the modal statement is ok. Will try with constructor. – Louis Papaloizou Jan 10 '14 at 18:19
  • Sorry, you're right. You're not querying the dialog when it returns or setting your JFrame visible. See edit to answer. – Hovercraft Full Of Eels Jan 10 '14 at 18:28

2 Answers2

6

Make sure that the JDialog is set up to be a modal JDialog which can be done by using an appropriate JDialog constructor or via a setter method. Doing this means that when you set it visible, the calling code stops and does not resume until the dialog is no longer visible. Once that happens the calling code restarts right after it stops. You can then query your dialog object for the value held by its fields.

For a concrete example, please see my answer to a similar question here.


You're not querying your JDialog after it returns. i.e.,

   System.out.println(login.getTheText());
   String text = login.getTheText();
   Main frame = new Main(text);  // and pass it into the other class.

This is already all explained and demonstrated in my link. Please read it. Also:

  • You will need to pass the info into main either by creating a constructor to do this or by using a setter method.
  • You're calling setVisible(false) on your main GUI JFrame for an unknown reason.
  • Don't setBounds or use null layout. Use layout managers and pack your GUIs.
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
3

You do the same thing you'd do for any Java POJOs: pass any required object references into the GUI elements (either through the constructor or setXXX() on them).

Two common practices is through the use of listeners (to mark when events happen) or through Queues when doing a producer/consumer pattern.

Without more information that's all I can provide.

I will add however, be when doing GUI work be very aware of what thread context your executing on. Any time you are modifying a GUI object or its underlying model you must be in the Swing Event Dispatch Thread. Any long running tasks must execute in a separate worker thread. I see many, many issues on SO where people fail to understand that. See the Oracle Docs for details.

Jason Nichols
  • 11,603
  • 5
  • 34
  • 53