2

I am having a weird issue with my initial JFrame login. When I run the program it will only pull up the cancel JButton at first. Then if I minimize the frame it shows everything like it should. Is there a reason for this? If so, how do I fix it?

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;

public class example 
{
   public static void main (String[] args)
   {    
      JFrame frame = new JFrame("Login");
      frame.setVisible(true);
      frame.setSize(350,150);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      JLabel label1 = new JLabel("User Id: ");
      JLabel label2 = new JLabel("Password: ");
      JTextField txt2 = new JTextField(20);
      JButton button = new JButton("login");
      JTextField txt = new JTextField(20);
      frame.add(label1);
      frame.add(txt);
      frame.add(label2);
      frame.add(txt2);

      String user = txt.getText();
      String password = txt2.getText();

      JButton button2 = new JButton("Cancel");
      frame.add(button);
      frame.add(button2);
      button2.addActionListener (new Action2()); 
      frame.setVisible(true);
      frame.setLayout(new FlowLayout());

      button.addActionListener(new ActionListener()
      { 
         public void actionPerformed( ActionEvent e)
         {   
            if ("abc".equals(txt.getText()) && "123".equals(txt2.getText())) 
            {
               JFrame frame2 = new JFrame("Student");
               frame2.setVisible(true);
               frame2.setSize(200,200);
               frame.setVisible(false);
            }
            if ("def".equals(txt.getText()) && "456".equals(txt2.getText())) 
            {
               JFrame frame2 = new JFrame("Instructor");
               frame2.setVisible(true);
               frame2.setSize(200,200);
               frame.setVisible(false);
            }
            if ("ghi".equals(txt.getText()) && "789".equals(txt2.getText())) 
            {
               JFrame frame2 = new JFrame("Teacher");
               frame2.setVisible(true);
               frame2.setSize(200,200);
               frame.setVisible(false);
            }
            else
            {
               System.out.println("Invalid Password");
            }
         } 
      });
   }

   static class Action2 implements ActionListener {        
      public void actionPerformed (ActionEvent e) 
      {     
         System.exit(0);
      } 
   }
}
kiheru
  • 6,588
  • 25
  • 31
programmer 20
  • 59
  • 1
  • 6

1 Answers1

2

The setVisible(true) should be the last method call.

Also, it is recommended to run swing applications in their own thread, as specified by the Java spec: Concurrency in Swing > Initial Threads: docs.oracle.com

So you should ideally run the Swing application as so:

//example from the referenced java documentation
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        createAndShowGUI();
    }
});

For more information about this which might be clearer: Will the real Swing Single Threading Rule please stand up?

The createAndShowGUI() method is not required, it is an arbitrary method name and its function is to call a method that basically does everything you've already written for your Swing application (with the modification of setVisible(true) invoked at the very end instead.)

So you should do something like this:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;

public class example 
{
   public static void main (String[] args)
   {    
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
            //you can alternatively replace 'createAndShowGUI()' with 'new example()'
        }
    });
   }

   public static void createAndShowGUI() {
       new example();
   }   

   public example() {
      JFrame frame = new JFrame("Login");
      //frame.setVisible(true);
      frame.setSize(350,150);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      JLabel label1 = new JLabel("User Id: ");
      JLabel label2 = new JLabel("Password: ");
      JTextField txt2 = new JTextField(20);
      JButton button = new JButton("login");
      JTextField txt = new JTextField(20);
      frame.add(label1);
      frame.add(txt);
      frame.add(label2);
      frame.add(txt2);

      String user = txt.getText();
      String password = txt2.getText();

      JButton button2 = new JButton("Cancel");
      frame.add(button);
      frame.add(button2);
      button2.addActionListener (new Action2()); 
      //frame.setVisible(true);
      frame.setLayout(new FlowLayout());

      button.addActionListener(new ActionListener()
      { 
         public void actionPerformed( ActionEvent e)
         {   
            if ("abc".equals(txt.getText()) && "123".equals(txt2.getText())) 
            {
               JFrame frame2 = new JFrame("Student");
               frame2.setVisible(true);
               frame2.setSize(200,200);
               frame.setVisible(false);
            }
            if ("def".equals(txt.getText()) && "456".equals(txt2.getText())) 
            {
               JFrame frame2 = new JFrame("Instructor");
               frame2.setVisible(true);
               frame2.setSize(200,200);
               frame.setVisible(false);
            }
            if ("ghi".equals(txt.getText()) && "789".equals(txt2.getText())) 
            {
               JFrame frame2 = new JFrame("Teacher");
               frame2.setVisible(true);
               frame2.setSize(200,200);
               frame.setVisible(false);
            }
            else
            {
               System.out.println("Invalid Password");
            }
         } 
      });
      frame.setVisible(true);
   }

   static class Action2 implements ActionListener {        
      public void actionPerformed (ActionEvent e) 
      {     
     System.exit(0);
      } 
   }
}

You should as well edit the button.addActionListener(new ActionListener() with the appropriate modifications as I have done in the public example() constructor (move the setVisible(boolean) method calls) and also add EXIT_ON_CLOSE for the new JFrames you have created here.

APengue
  • 138
  • 6
  • Thank you! That makes a lot of sense. I doubt I would have ever figured out that the frame.setVisible(true) was causing the issue. – programmer 20 Apr 16 '15 at 17:35