简体   繁体   中英

Set height but not width of JTextArea

I have multiple JTextArea s inside a JPanel . I am using a BoxLayout to make them align vertically and fill the width of the container.

It works, but they seem to expand to fill the entire height as well.

What I really want is simple - a text area that wraps text where I can control the width but allow the height to scale dynamically as more lines are added. The above method was just my best attempt at it. If there is a solution that uses a different layout manager, different text component, etc, that works.

minimal verifiable example below:

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setPreferredSize(new Dimension(300, 300));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel textAreas = new JPanel();
    textAreas.setLayout(new BoxLayout(textAreas, BoxLayout.Y_AXIS));

    JTextArea area1 = new JTextArea();
    area1.append("this is a string");
    area1.setLineWrap(true);
    area1.setWrapStyleWord(true);
    textAreas.add(area1);

    JTextArea area2 = new JTextArea("and another that is much longer, so that it wraps to the next line");
    area2.setLineWrap(true);
    area2.setWrapStyleWord(true);
    textAreas.add(area2);

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setViewportView(textAreas);

    frame.add(scrollPane);
    frame.pack();
    frame.setVisible(true);
}

I have done research on this topic on my own, including looking at different layout managers ( http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html ), and checking other questions on the site, but I haven't had much luck.

TLDR: Can I make it so each element of a layout has a height that scales to its content but a fixed width? If so how?

What I really want is simple - a text area that wraps text where I can control the width but allow the height to scale dynamically as more lines are added.

The BoxLayout respects the maximum size so the text area grows to fill all the space available in the panel. You can override the getMaximumSize() method to return the preferred height by using something like:

JTextArea area1 = new JTextArea()
{
    public Dimension getMaximumSize()
    {
        Dimension d = super.getMaximumSize();
        d.height = getPreferredSize().height;

        return d;
    }
};

It works...

Not really. Make the frame wider and the text will unwrap. Then shrink the frame and the scrollbar will appear. That is the text will not wrap again

What you need to do is force the panel added to the scroll pane to be the same width as the viewport. This will allow wrapping to work properly.

You do this by implementing the Scrollable interface on the panel. Specifically you need to override the getScrollableTracksViewportWidth() method to return true .

Or an easier solution is to use the Scrollable Panel class which allows you to set properties of the panel to control this behaviour.

You can replace a JPanel with the ScrollablePanel :

//JPanel textAreas = new JPanel();
ScrollablePanel textAreas = new ScrollablePanel();
textAreas.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );

Edit:

If there is a solution that uses a different layout manager

Without overriding the getMaximumSize() method of the text areas and when using the Scrollable Panel you should be able to use the following layout managers.

The GridBagLayout allows you to specify the "weightx" constraint. This will allow the component to fill all the available space in the panel.

Or if you don't like specifying all the constrains of the GridBagLayout you could use the Relative Layout which support vertical/horizontal layout of components at their preferred size.

You would just need to use the following to force the component to fill the horizontal space:

//textAreas.setLayout(new BoxLayout(textAreas, BoxLayout.Y_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
textAreas.setLayout(rl);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM