1

I currently have two frames, when you run the application the first JFrame that shows is a login, it has two input fields and a button. When the user logs in and is verified, I would like to close the frame and start up the second one.

So, the only thing I can think of doing is doing setVisible(false) for the login frame and setVisible(true) for the Main frame.

Is there a better way to do this, or is that the only way?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
  • 1
    If you do this, you'll also want to call `dispose()` or set the `JFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)`. – Greg Kopff Jan 18 '13 at 22:56

2 Answers2

2

Personnally, I would start up your second JFrame immediately and replace your first frame with a modal JDialog which would be owned by the JFrame.

See also this answer to The Use of Multiple JFrames, Good/Bad Practice?

Here is a basic demo of what I suggest:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestLogin {
    private JFrame frame;
    private boolean authenticated;
    private JTextField login;
    private JPasswordField password;

    protected void initUI() {
        frame = new JFrame(TestLogin.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        frame.setVisible(true);
    }

    protected void showLoginDialog() {
        authenticated = false;
        final JDialog dialog = new JDialog(frame, "Please provide your credentials");
        dialog.setModal(true);
        JPanel panel = new JPanel(new GridBagLayout());
        JPanel buttonPanel = new JPanel();
        login = new JTextField(40);
        password = new JPasswordField(20);
        JLabel loginLabel = new JLabel("Login:");
        JLabel passwordLabel = new JLabel("Password:");
        JButton ok = new JButton("OK");
        ok.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // Here perform authentication and set authentication flag to appropriate value
                authenticated = true;
                if (authenticated) {
                    setUpFrame();
                    dialog.dispose();
                }
            }
        });
        JButton cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        dialog.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                if (!authenticated) {
                    System.exit(0);
                }
            }
        });
        dialog.getRootPane().setDefaultButton(ok);
        buttonPanel.add(ok);
        buttonPanel.add(cancel);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.fill = GridBagConstraints.HORIZONTAL;
        panel.add(loginLabel, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1.0;
        panel.add(login, gbc);
        gbc.gridwidth = 1;
        gbc.weightx = 0;
        panel.add(passwordLabel, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1.0;
        panel.add(password, gbc);
        panel.add(buttonPanel, gbc);
        dialog.add(panel);
        dialog.pack();
        dialog.setLocationRelativeTo(frame);
        while (!authenticated) {
            dialog.setVisible(true);
        }
    }

    protected void setUpFrame() {
        frame.add(new JLabel("Successfully authenticated"));
        frame.revalidate();
        frame.repaint();
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TestLogin testLogin = new TestLogin();
                testLogin.initUI();
                testLogin.showLoginDialog();
            }

        });
    }

}
Community
  • 1
  • 1
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
0

There are several ways to do that.
E.g. you could reuse your 1st JFrame. Therefore remove the components you got on your 1st frame, add the ones for the 2nd and then repaint() the frame.
But I wouldn't consider that as good practice.
As Andrew Thompson suggested, you could also use a CardLayout to just initialize one JFrame, show your login-card and then switch to the fully initialized 2nd full-application card. This way you will get rid of those repaints.
You could also show your 2nd frame (your application first) and then use a modal JDialog to the let user log in.

Zhedar
  • 3,480
  • 1
  • 21
  • 44