Search code examples
javaswingjpanelpreferredsize

Java Swing JPanel Object Sizes all match JTextField size


I've got an unusual issue with all of the objects inside of a JPanel taking the size of the JTextField. Even if I try to force a size on the other objects, they still take the size specified for the textfield as their own. For example, I'm trying to setup a single panel in its own method as follows:

private JPanel setupID() {
    JLabel projLbl = new JLabel("Project ID:");
    JButton verifyBtn = new JButton("Verify ID");
    projID = new JTextField(25);
    verifyBtn.setToolTipText("Verifies that the entered ID is not already in use.");
    JPanel theID = new JPanel(new GridLayout(1,0));
        theID.add(projLbl);
        theID.add(projID);
        theID.add(verifyBtn);
    return theID;
}

What I end up with is a window that looks like this... enter image description here The JFrame frame; that this is being loaded into has the frame.pack() method called on it to auto adjust the frame size. If I create the individual objects in a BorderLayout() in different areas (WEST,CENTER,EAST for example) they'll work as intended, but when they're loaded into the panel, they all size based off the JTextField(25). Any ideas why this is?


Solution

  • As Code-Guru and asemax has pointed out. It would appear that you are using a GridLayout, which is designed to layout components in a grid, evenly, using the available space.

    Try using something like a GridBagLayout instead...

    enter image description here

    public class BadLayout08 {
    
        public static void main(String[] args) {
            new BadLayout08();
        }
    
        public BadLayout08() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (Exception ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new GridBagLayout());
                add(new JLabel("Project ID:"));
                add(new JTextField(25));
                add(new JButton("Verify ID"));
            }
    
        }
    
    }
    

    You may find A Visual Guide to Layout Managers of some use when you need to decide on which layout to use.