Search code examples
javaswingawtlayout-managergridbaglayout

Why are all my components clustered at the center of the JFrame


I'm using a grid bag layout to create a layout that looks like this: enter image description here

but what I have is this: enter image description here

Why is this happening? I've specified left alignment and to take up all horizontal space but i still end up with this. Here's my code:

public DepotView()
{
    setSize(FRAME_WIDTH,FRAME_HEIGHT);
    setLocationRelativeTo ( null );

    getContentPane ().setLayout ( new GridBagLayout());

    JPanel workerPanel = createTextAreaPanel("Processing: ",workerArea);
    GridBagConstraints c = new GridBagConstraints();
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 2;
    c.gridheight = 1;
    c.weightx = 1;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.anchor = GridBagConstraints.FIRST_LINE_START;
    getContentPane().add ( workerPanel );


    JPanel customerPanel = createTextAreaPanel("Customers: ",textArea);
    c = new GridBagConstraints();
    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.5;
    c.insets = new Insets(5,5,5,5);
    getContentPane().add ( customerPanel );

    JPanel depotPanel = createTextAreaPanel("Depot: ",depotArea);
    c = new GridBagConstraints();
    c.gridx = 1;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.5;
    c.insets = new Insets(5,5,5,5);
    getContentPane().add ( depotPanel );


    //pack();
    setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );

Solution

  • The problem is that the size of your frame is smaller than the total preferred size of your content pane. From there, you get a swcrewed layout.

    A few more things:

    • use pack() instead of setSize() on your JFrame to get an appropriate frame size.
    • avoid using gridx/gridy, they tend to make constraint complex and hard to maintain
    • anchor/fill should almost always be combined with weightx and/or weighty bigger than 0
    • instead of using the default FlowLayout of JPanel, use a LayoutManager which will take advantage of extra avilable space (for example BorderLayout)
    • don't use static variables, it is just evil
    • your textarea variables are always empty.

    Here is a piece of code which seems to work quite well:

    import java.awt.BorderLayout;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.SwingUtilities;
    
    public class DepotView extends JFrame {
    
        private JTextArea textArea;
        private JTextArea depotArea;
        private JTextArea workerArea;
    
        public DepotView() {
    
            getContentPane().setLayout(new GridBagLayout());
    
            JPanel workerPanel = createTextAreaPanel("Processing: ", workerArea = new JTextArea());
            GridBagConstraints c = new GridBagConstraints();
            c.gridwidth = GridBagConstraints.REMAINDER;
            c.weightx = 1.0;
            c.weighty = 1.0;
            c.fill = GridBagConstraints.BOTH;
            c.anchor = GridBagConstraints.FIRST_LINE_START;
            getContentPane().add(workerPanel, c);
    
            JPanel customerPanel = createTextAreaPanel("Customers: ", textArea = new JTextArea());
            c = new GridBagConstraints();
            c.insets = new Insets(5, 5, 5, 5);
            c.fill = GridBagConstraints.BOTH;
            c.weightx = 1.0;
            c.weighty = 1.0;
            c.anchor = GridBagConstraints.FIRST_LINE_START;
            getContentPane().add(customerPanel, c);
    
            JPanel depotPanel = createTextAreaPanel("Depot: ", depotArea = new JTextArea());
            c = new GridBagConstraints();
            c.weightx = 1.0;
            c.weighty = 1.0;
            c.gridwidth = GridBagConstraints.REMAINDER;
            c.insets = new Insets(5, 5, 5, 5);
            c.fill = GridBagConstraints.BOTH;
            getContentPane().add(depotPanel, c);
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            pack();
            setLocationRelativeTo(null);
        }
    
        private JPanel createTextAreaPanel(String label, JTextArea textArea) {
            JPanel customerQueuePanel = new JPanel(new BorderLayout());
    
            customerQueuePanel.add(new JLabel(label), BorderLayout.NORTH);
            textArea.setRows(15);
            textArea.setColumns(20);
            textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 14));
            textArea.setEditable(false);
    
            JScrollPane scrollPane = new JScrollPane(textArea);
            customerQueuePanel.add(scrollPane);
            return customerQueuePanel;
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new DepotView().setVisible(true);
                }
            });
        }
    
    }