2

Hey guys I'm an amateur programmer (in Gr12) and am working on a program that asks a user for a username and password through a custom JDialog (created using eclipse WindowBuilder)

The problem I'm having is retrieving the data from the "popup", I coded a test program but the values are displayed before i can enter any data.

here is my code:

package winowbuilderstuff;
public class TestDialog {

/**
 * @param args
 */
public static void main(String[] args) {
    LoginDialog login = new LoginDialog ();


    login.setVisible(true);

    String username = login.getUser();
    String password = login.getPass();

    System.out.println("Username: " + username);
    System.out.println("Password: " + password);


}

}

package winowbuilderstuff;

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class LoginDialog extends JDialog {

private final JPanel contentPanel = new JPanel();
private JTextField txtfUsername;
private JPasswordField pswrdf;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    try {
        LoginDialog dialog = new LoginDialog();
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setVisible(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * Create the dialog.
 */
public LoginDialog() {
    setTitle("Login");
    setBounds(100, 100, 478, 150);
    getContentPane().setLayout(new BorderLayout());
    contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
    getContentPane().add(contentPanel, BorderLayout.CENTER);
    contentPanel.setLayout(null);
    {
        JLabel lblUsername = new JLabel("Username");
        lblUsername.setBounds(25, 13, 68, 14);
        contentPanel.add(lblUsername);
    }
    {
        txtfUsername = new JTextField();
        txtfUsername.setToolTipText("Enter your username");
        txtfUsername.setBounds(137, 13, 287, 17);
        contentPanel.add(txtfUsername);
        txtfUsername.setColumns(10);
    }

    JLabel lblPassword = new JLabel("Password");
    lblPassword.setBounds(25, 52, 68, 14);
    contentPanel.add(lblPassword);

    pswrdf = new JPasswordField();
    pswrdf.setToolTipText("Enter your password");
    pswrdf.setBounds(137, 50, 287, 17);
    contentPanel.add(pswrdf);
    {
        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
        getContentPane().add(buttonPane, BorderLayout.SOUTH);
        {
            JButton btnLogin = new JButton("Login");
            btnLogin.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    getUser();
                    getPass();
                    dispose();
                }
            });
            btnLogin.setActionCommand("OK");
            buttonPane.add(btnLogin);
            getRootPane().setDefaultButton(btnLogin);
        }
        {
            JButton btnCancel = new JButton("Cancel");
            btnCancel.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {

                    dispose();

                }
            });
            btnCancel.setActionCommand("Cancel");
            buttonPane.add(btnCancel);
        }
    }
}

public String getUser(){
    return txtfUsername.getText();
}

public String getPass(){
    return pswrdf.getText();
}


}
Jordan.J.D
  • 7,999
  • 11
  • 48
  • 78
  • `contentPanel.setLayout(null);` Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Jul 23 '15 at 18:31
  • ..oh, and don't put a tag for your IDE unless the question is **about** the IDE. – Andrew Thompson Jul 23 '15 at 18:32
  • Please see edit to answer. – Hovercraft Full Of Eels Jul 23 '15 at 19:55

1 Answers1

3
  1. Make your JDialog modal. This can be done via a super(...) constructor call or a simple method call.
  2. If you do the above, then the dialog will freeze the calling code at the site that you call setVisible(true) and then will return to the calling code at that same point when the dialog is no longer visible.
  3. So immediately after the setVisible(true), query your dialog object for its user name and password by calling your getUser() and getPass() methods on it.
  4. Some side recommendations:
    • Avoid calling getText() on a JPasswordField as that is not safe code. Instead get the char[] from it via getPassword() and use this as this is much safer.
    • You should avoid use of null layout and use of setBounds(...) for component placement as this makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain.

e.g., this change is all that is needed:

 public LoginDialog() {
     super(null, ModalityType.APPLICATION_MODAL);  // add this line

For example:

import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import javax.swing.*;

public class TestDialog2 {
   private static void createAndShowGui() {
      int result = MyLoginPanel.showDialog();
      if (result == JOptionPane.OK_OPTION) {
         String userName = MyLoginPanel.getUserName();
         char[] password = MyLoginPanel.getPassword();

         System.out.println("User Name: " + userName);
         System.out.println("Password:  " + new String(password));
      }
   }

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

@SuppressWarnings("serial")
class MyLoginPanel extends JPanel {
   private static MyLoginPanel myLoginPanel = new MyLoginPanel();
   private static JDialog myDialog;
   public static final String RETURN_STATE = "return state";
   private static final int COLUMNS = 20;
   private JTextField userNameField = new JTextField(COLUMNS);
   private JPasswordField passField = new JPasswordField(COLUMNS);
   private int returnState = Integer.MIN_VALUE;

   private MyLoginPanel() {
      setLayout(new GridBagLayout());
      add(new JLabel("User Name:"), createGbc(0, 0, 1));
      add(userNameField, createGbc(1, 0, 2));
      add(new JLabel("Password:"), createGbc(0, 1, 1));
      add(passField, createGbc(1, 1, 2));
      add(new JLabel(""), createGbc(0, 2, 1));

      JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));

      buttonPanel.add(new JButton(new LoginAction("Login")));
      buttonPanel.add(new JButton(new CancelAction("Cancel")));

      add(buttonPanel, createGbc(1, 2, 2));
   }

   private GridBagConstraints createGbc(int x, int y, int width) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = width;
      gbc.gridheight = 1;
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      int right = x == 0 ? 15 : 5;
      gbc.insets = new Insets(5, 5, 5, right);
      gbc.anchor = x == 0 ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
      return gbc;
   }

   public void setReturnState(int returnState) {
      this.returnState = returnState;
      firePropertyChange(RETURN_STATE, Integer.MIN_VALUE, returnState);
   }

   public int getReturnState() {
      return returnState;
   }

   private class LoginAction extends AbstractAction {
      public LoginAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         returnState = JOptionPane.OK_OPTION;
         Window win = SwingUtilities.getWindowAncestor(MyLoginPanel.this);
         win.dispose();
      }
   }

   private String _getUserName() {
      return userNameField.getText();
   }

   private char[] _getPassword() {
      return passField.getPassword();
   }

   public static String getUserName() {
      return myLoginPanel._getUserName();
   }

   public static char[] getPassword() {
      return myLoginPanel._getPassword();
   }

   private class CancelAction extends AbstractAction {
      public CancelAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         returnState = JOptionPane.CANCEL_OPTION;
         Window win = SwingUtilities.getWindowAncestor(MyLoginPanel.this);
         win.dispose();
      }
   }

   public static int showDialog() {
      if (myDialog == null) {
         myDialog = new JDialog(null, "Test", ModalityType.APPLICATION_MODAL);
         myDialog.add(myLoginPanel);
         myDialog.pack();
      }
      myDialog.setVisible(true);
      return myLoginPanel.getReturnState();
   }

}

Or easier still, just use a JOptionPane as your modal dialog. You can pass a JPanel into it easily.

For example:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class TestDialog3 {
   private static void createAndShowGui() {
      MyLoginPanel3 myLoginPanel3 = new MyLoginPanel3();
      int result = JOptionPane.showConfirmDialog(null, myLoginPanel3, "Log On", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
      if (result == JOptionPane.OK_OPTION) {
         String userName = myLoginPanel3.getUserName();
         char[] password = myLoginPanel3.getPassword();

         System.out.println("User Name: " + userName);
         System.out.println("Password:  " + new String(password));
      }
   }

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

@SuppressWarnings("serial")
class MyLoginPanel3 extends JPanel {
   private static final int COLUMNS = 20;
   private JTextField userNameField = new JTextField(COLUMNS);
   private JPasswordField passField = new JPasswordField(COLUMNS);

   public MyLoginPanel3() {
      setLayout(new GridBagLayout());
      add(new JLabel("User Name:"), createGbc(0, 0, 1));
      add(userNameField, createGbc(1, 0, 2));
      add(new JLabel("Password:"), createGbc(0, 1, 1));
      add(passField, createGbc(1, 1, 2));
      add(new JLabel(""), createGbc(0, 2, 1));

   }

   private GridBagConstraints createGbc(int x, int y, int width) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = width;
      gbc.gridheight = 1;
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      int right = x == 0 ? 15 : 5;
      gbc.insets = new Insets(5, 5, 5, right);
      gbc.anchor = x == 0 ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
      return gbc;
   }


   public String getUserName() {
      return userNameField.getText();
   }

   public char[] getPassword() {
      return passField.getPassword();
   }

}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373