Search code examples
javaswingjframejtextfield

Java - JTextField fills all frame


I am trying to achieve a very simple task: To make a JTextField that doesn't fill all screen. Currently I see this possible only with setMaximumSize, is there any other way? Here's my code:

JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
window.setSize(screenSize.width / 2, screenSize.height / 2);
window.setLocation(screenSize.width / 4, screenSize.height / 4);
window.setResizable(false);
JPanel pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
pane.setBorder(new EmptyBorder(10, 10, 10, 10));
pane.add(new JTextField(10));
window.setContentPane(pane);

Solution

  • The problem comes from BoxLayout:

    For a top-to-bottom box layout, the preferred width of the container is that of the maximum preferred width of the children. If the container is forced to be wider than that, BoxLayout attempts to size the width of each component to that of the container's width (minus insets). If the maximum size of a component is smaller than the width of the container, then X alignment comes into play.

    (emphasis mine). So your option with BoxLayout is, as you mentioned, to set the maximum size (and then handle the alignment if needed):

    JTextField textField = new JTextField(10);
    textField.setMaximumSize(textField.getPreferredSize());
    textField.setAlignmentX(Component.LEFT_ALIGNMENT); // If needed
    

    Otherwise, you will have to use a different LayoutManager. A lot of things work. For starters, just remove the line

    pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
    

    to use the default FlowLayout.

    Note that if you place more components into the frame, this issue can "fix itself" since other components might be resized instead.