sinθ
sinθ

Reputation: 11493

Border Layout not taking up all available space

I'm new to swing, and I suspect the issue has something to do with the BoxLayout. I'm trying to make a series of textfields and labels be one after the other on top of a frame. This is my code:

public static void main(String[] args) {
    JFrame frame = new JFrame("New Message");
    frame.setSize(100, 100);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JTextArea textArea = new JTextArea();
    frame.add(textArea, BorderLayout.CENTER);

    JPanel list = new JPanel();
    list.setLayout(new BoxLayout(list, BoxLayout.Y_AXIS));
    frame.add(list, BorderLayout.NORTH);

    String[] labels = {"To: ", "Cc: ", "Bcc: ", "Subject: "};
    for (int i = 0; i < labels.length; i++) {
        JLabel l = new JLabel(labels[i]);
        JTextField f = new JTextField();
        JPanel p = new JPanel();
        p.add(l, BorderLayout.WEST);
        p.add(f, BorderLayout.CENTER);
        list.add(p);
    }

    frame.pack();

    frame.setVisible(true);

}

This is the result: enter image description here

What I want is the To, Cc, Bcc and Subject to be all the way on the left and the TextField to take up the rest of the space.

Upvotes: 1

Views: 4176

Answers (3)

Guillaume Polet
Guillaume Polet

Reputation: 47608

Few side-notes:

  • Start your UI from the EDT by wrapping the UI-initialisation in a SwingUtilities.invokeLater
  • It is always a good idea to specify number of columns for a JTextField, and both rows and columns for a JTextArea
  • It is useless to call setSize(), if you call pack() after. In general, forget about using setSize()/setLocation/setBounds() on any Swing component (leave all that to LayoutManager's)

GridBagLayout does a pretty good job here. GroupLayout can work too.

See this example:

import java.awt.BorderLayout;
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.JTextField;
import javax.swing.SwingUtilities;

public class Mail {

    protected void initUI() {
        JFrame frame = new JFrame("New Message");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel list = new JPanel(new GridBagLayout());
        frame.add(list, BorderLayout.CENTER);
        GridBagConstraints labelGBC = new GridBagConstraints();
        labelGBC.insets = new Insets(3, 3, 3, 3); // Put some space between elements for nicer look
        labelGBC.anchor = GridBagConstraints.WEST; // Align left within its cell
        GridBagConstraints fieldGBC = new GridBagConstraints();
        fieldGBC.gridwidth = GridBagConstraints.REMAINDER; // Last element of the row
        fieldGBC.weightx = 1.0; // Cell takes up all extra horizontal space
        fieldGBC.fill = GridBagConstraints.HORIZONTAL; // Fill the cell horizontally
        fieldGBC.insets = new Insets(3, 3, 3, 3); // Put some space between elements for nicer look
        String[] labels = { "To: ", "Cc: ", "Bcc: ", "Subject: " };
        for (int i = 0; i < labels.length; i++) {
            JLabel l = new JLabel(labels[i]);
            JTextField f = new JTextField(50);
            list.add(l, labelGBC);
            list.add(f, fieldGBC);
        }
        GridBagConstraints taGBC = new GridBagConstraints();
        taGBC.gridwidth = 2;
        taGBC.weightx = 1.0; // Cell takes up all extra horizontal space
        taGBC.weighty = 1.0; // Cell takes up all extra vertical space
        taGBC.fill = GridBagConstraints.BOTH; // Fill cell in both direction
        taGBC.insets = new Insets(3, 3, 3, 3); // Put some space between elements for nicer look
        JTextArea textArea = new JTextArea(10, 80);
        list.add(new JScrollPane(textArea), taGBC);

        frame.pack();

        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Mail().initUI();
            }
        });

    }
}

And the result

enter image description here

Upvotes: 3

tofcoder
tofcoder

Reputation: 2382

You can try to set a BorderLayout on each JPanel p:

public static void main(String[] args) {
    JFrame frame = new JFrame("New Message");
    frame.setSize(100, 100);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JTextArea textArea = new JTextArea();
    frame.add(textArea, BorderLayout.CENTER);

    JPanel list = new JPanel();
    list.setLayout(new BoxLayout(list, BoxLayout.Y_AXIS));
    frame.add(list, BorderLayout.NORTH);

    String[] labels = {"To: ", "Cc: ", "Bcc: ", "Subject: "};
    for (int i = 0; i < labels.length; i++) {
        JLabel l = new JLabel(labels[i]);
        JTextField f = new JTextField();
        JPanel p = new JPanel(new BorderLayout());
        p.add(l, BorderLayout.WEST);
        p.add(f, BorderLayout.CENTER);
        list.add(p);
    }

    frame.pack();

    frame.setVisible(true);

}

Upvotes: 1

Alepac
Alepac

Reputation: 1831

Try java.awt.FlowLayout to see one component next to the other.

Upvotes: 1

Related Questions