2

This has probably been answered here, but my searches drew up a blank, perhaps I am looking for the wrong thing.

How can I stop a JTextArea and a JTextField from stretching? Does swing provide a panel spacer of some sort which I can add that will be stretched before any other elements will?

I have a JPanel which fills a JFrame with a set size. It uses a BoxLayout set to PAGE_AXIS. If I add a JTextArea with size 3,100 it ignores these row/columns sizes and fills all the available space.

Similarly I have a JPanel with a GridLayout. If I add a JTextField, rather than be the size in columns that I specify, it fills the entire space in the grid.

Edit: The drawing below shows what I would like (at the top) and what I get. enter image description here

Lieuwe
  • 1,734
  • 2
  • 27
  • 41
  • Please post some piece of code to investigate the issue. – Braj Apr 15 '16 at 08:31
  • 1
    Start by having a look at [Laying Out Components Within a Container](http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html) for some more details about the different layout managers, something like `FlowLayout` and `GridBagLayout` would do the job – MadProgrammer Apr 15 '16 at 08:34
  • Provide ASCII art or a simple drawing of the *intended* layout of the GUI at minimum size, and if resizable, with more width and height. – Andrew Thompson Apr 15 '16 at 08:39

3 Answers3

1

Few words directly from documentation on How to Use GridLayout

A GridLayout object places components in a grid of cells. Each component takes all the available space within its cell, and each cell is exactly the same size. If the GridLayoutDemo window is resized, the GridLayout object changes the cell size so that the cells are as large as possible, given the space available to the container.

GridLayout doesn't consider the size of the component. It tries to fit the component in available space in rows and columns.


Try to avoid setting size explicitly. There is a very good post about Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? that can help you to design it in a better way.


There are lots of layout managers that can fit as per your requirements. Please have a look at How to Use Various Layout Managers


You can use GridBagLayout instead of GridLayout to divide the components in rows and columns just like table layout that gives you more control on grid width, height, margin, padding, column, rows etc.

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
  • Thanks for those useful links. The reason I want to specify sizes is because I have input constraints (i.e. I want a maximum of 8 characters in that JTextView which is why I create it as `new JTextView(8)`) In other UI libraries I worked with (Android/Qt) you can add spacers or empty panels and set the 'stretch factors' of these components so it isn't (in this case) the TextView/Area that stretches to fill the available space. – Lieuwe Apr 15 '16 at 08:44
1

You cannot do serious layouts withe GridLayout or BoxLayout. Forget about them.

The first question is: Are you sure you don't want the JTextArea and JTextField to grow? It is a standard in UI that these components are growing and shrinking; the first one in both directions and the second one horizontally.

Anyway, I post solutions for GroupLayout and MigLayout, which are the managers I highly recommend.

a) Solution with GroupLayout

Each component has three sizes: minimum, preferred, and maximum. These are set to some sensible defaults for each component. This is why the JTextField tends to grow horizontally; its maximum value is set to a very large number.

package com.zetcode;

import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class GroupLayoutStretchingEx extends JFrame {

    public GroupLayoutStretchingEx() {

        initUI();
    }

    private void initUI() {

        JTextArea area = new JTextArea(12, 20);
        area.setBorder(BorderFactory.createEtchedBorder());
        JLabel input = new JLabel("Input");
        JTextField textField = new JTextField(15);

        createLayout(area, input, textField);

        setTitle("Stretching");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    private void createLayout(JComponent... arg) {

        Container pane = getContentPane();
        GroupLayout gl = new GroupLayout(pane);
        pane.setLayout(gl);

        gl.setAutoCreateContainerGaps(true);
        gl.setAutoCreateGaps(true);

        gl.setHorizontalGroup(gl.createParallelGroup(GroupLayout.Alignment.TRAILING)
                .addComponent(arg[0], GroupLayout.DEFAULT_SIZE,
                        GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addGroup(gl.createSequentialGroup()
                        .addComponent(arg[1])
                        .addComponent(arg[2], GroupLayout.DEFAULT_SIZE,
                                GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        );

        gl.setVerticalGroup(gl.createSequentialGroup()
                .addComponent(arg[0], GroupLayout.DEFAULT_SIZE,
                        GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addGroup(gl.createParallelGroup()
                        .addComponent(arg[1])
                        .addComponent(arg[2], GroupLayout.DEFAULT_SIZE,
                                GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            GroupLayoutStretchingEx ex = new GroupLayoutStretchingEx();
            ex.setVisible(true);
        });
    }
}

In GroupLayout, you need to set the correct values for the maximum component size in the addComponent() method.

JTextArea area = new JTextArea(12, 20);

By setting the number of rows and columns for the JTextArea, we set a preffered size for this component. This value is later used by the layout manager in its calculations.

b) Solution with MigLayout

In MigLayout, we control the resizement of the components with various constraints, such as fill, grow, or push. By not using them, the components do not grow.

package com.zetcode;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;

public class MigLayoutStretchingEx extends JFrame {

    public MigLayoutStretchingEx() {

        initUI();
    }

    private void initUI() {

        JTextArea area = new JTextArea(12, 20);
        area.setBorder(BorderFactory.createEtchedBorder());
        JLabel input = new JLabel("Input");
        JTextField textField = new JTextField(15);

        createLayout(area, input, textField);

        setTitle("MigLayout example");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void createLayout(JComponent... arg) {

        setLayout(new MigLayout());

        add(arg[0], "wrap");
        add(arg[1], "split 2");
        add(arg[2], "growx");
        pack();
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            MigLayoutStretchingEx ex = new MigLayoutStretchingEx();
            ex.setVisible(true);
        });
    }
}

And here is the screenshot:

Screenshot from the MigLayout example

Jan Bodnar
  • 10,969
  • 6
  • 68
  • 77
0

In My code I just set the number of columns

JTextField data = new JTextField();
data.setColumns(30);
Theresa Forster
  • 1,914
  • 3
  • 19
  • 35