Question

I have a frame that opens when you click file>new user, but the text fields are all squished together.

I'm trying to have them all stacked vertically so I use new GridLayout(3, 2) as my LayoutManager. However, the stuff for the new window is all the way at the bottom.

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class App extends JFrame implements ActionListener
{
    private final int WIDTH = 300;
    private final int HEIGHT = 550;
    private int control = 0;
    String[] username = new String[10];
    String[] pass = new String[10];
    private String tempName;
    private String tempPass;

    Container con = getContentPane();
    JPanel panel = new JPanel();
    private JTextField name = new JTextField();
    private JPasswordField password = new JPasswordField();

    JMenuBar mainBar = new JMenuBar();
    JMenu menu1 = new JMenu("File");
    JMenu menu2 = new JMenu("Edit");
    JMenuItem newUser = new JMenuItem("New User");

    JButton but1 = new JButton("Log In");
    JButton but2 = new JButton("test");

    JLabel error = new JLabel("Login info not corret\n Or user not registered.");
    JLabel success = new JLabel("Success!");

    /////////////stuff for dialog///////////////////
    JPanel panel2 = new JPanel();
    JTextField newModalUser = new JTextField();
    JPasswordField newModalPass = new JPasswordField();
    JPasswordField newModalPassCon = new JPasswordField();
    JButton register = new JButton("Register");
    ////////////////////////////////////////////////
    public static void main(String[] args)
    {
       App frame = new App();
    }

    public App()
    {
       //just settin some stuff up
       super("For The Bold");
       setSize(WIDTH, HEIGHT);

       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setLocationRelativeTo(null);
       //setResizable(false);
       setVisible(true);

       //add menubar
       setJMenuBar(mainBar);
       mainBar.add(menu1);
       menu1.add(newUser);

       //background of main JFrame
       setContentPane(new JLabel(new ImageIcon("//Users//ryanchampin//Desktop//GUI app//image.png")));

       //test names in the arrays 
       username[0] = "ryan";
       pass[0] = "test";

       //main stuff in the middle
       //panel.setBackground(Color.RED);
       panel.setSize(300,300);
       panel.add(name);
       panel.add(password);
       panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS ));
       panel.add(but1);

       panel.add(but2);

       add(panel,new GridBagConstraints());
       setLayout(new GridBagLayout());

       //assign action listener
       but1.addActionListener(this);
       newUser.addActionListener(this);

       register.addActionListener(this);
   }


   public void actionPerformed(ActionEvent e)
   {
      Object source = e.getSource();
      tempName = name.getText();
      tempPass = password.getText();

      if(source == but1)
      {
            for(int x = 0; x < username.length; x++)
            {
                if(tempName.equalsIgnoreCase(username[x]) && tempPass.equals(pass[x]))
                {               
                    //display success JLabel
                    add(success);
                    System.out.println("success");
                    break;
                }
                else 
                {
                    success.setText(null);
                    add(error);
                    name.setText(null);
                    password.setText(null);
                }   
            }
       }
       else
          if(source == newUser)
          {
               panel.setVisible(false);
               setLayout(new GridLayout(3,2));
               add(panel2);
               panel2.add(newModalUser);
               panel2.add(newModalPass);
               panel2.add(newModalPassCon);
               panel2.add(register);
          }
          else if(source == register)
               System.out.println("yay it worked");
   }
}
Was it helpful?

Solution

  • Avoid using setSize(...) or setPreferredSize(...) if possible.
  • Instead let the components and their layout managers set their own sizes.
  • Use a CardLayout to swap views instead of what you're doing. If you do this, the CardLayout will size its container to fit all the "cards" that it has been given.
  • Don't forget to call pack() on the GUI after adding all components
  • Don't forget to call setVisible(true) after adding all components and after calling pack.
  • When creating new JTextFields and JPasswordFields, pass in an int for the number of columns into the constructors.

Edit
You ask:

whats pack() used for?

The pack() method tells the GUI to have all the layout managers of its constituent containers to lay out their components, and then to set the best size of the GUI after every component has been properly placed.

OTHER TIPS

If you want spacing in a GridLayout, you can use the setHgap(int) and setVgap(int) methods to set the number of pixels of space that will appear between each element in the grid.

In your code, there are two ways you could do this: construct a GridLayout and call the two setter methods on it, then pass it into the setLayout(LayoutManager) method:

GridLayout layout = new GridLayout(3, 2);
layout.setHgap(5); // or whatever number of pixels you want
layout.setVgap(5); // same
setLayout(layout);

Alternatively, you could cast the LayoutManager you would get from calling getLayout() and call the two methods on it:

setLayout(new GridLayout(3, 2));
((GridLayout) getLayout()).setHgap(5);
((GridLayout) getLayout()).setVgap(5);

if you want them stacked vertically, wouldn't it be easier to keep using BoxLayout?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top