Search code examples
javaswingjpanelboxlayoutpreferredsize

Keep BoxLayout From Expanding Children


I want to stack some JComponents vertically inside a JPanel so they stack at the top and any extra space is at the bottom. I'm using a BoxLayout. The components will each contain a JTextArea that should allow the text to wrap if necessary. So, basically, I want the height of each of these components to be the minimum necessary for displaying the (possibly wrapped) text.

Here's a contained code example of what I'm doing:

import javax.swing.*;
import java.awt.*;
public class TextAreaTester {
    public static void main(String[] args){
        new TextAreaTester();
    }
    public TextAreaTester(){
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel,BoxLayout.PAGE_AXIS));
        panel.setPreferredSize(new Dimension(100,400));
        for(int i = 0; i<3; i++){
            JPanel item = new JPanel(new BorderLayout());
            JTextArea textarea = new JTextArea("this is a line of text I want to wrap if necessary");
            textarea.setWrapStyleWord(true);
            textarea.setLineWrap(true);
            textarea.setMaximumSize( textarea.getPreferredSize() );
            item.add(textarea,BorderLayout.NORTH);
            panel.add(item);
        }
        panel.add(Box.createGlue());
        frame.add(panel);
        frame.setVisible(true);
        frame.pack();  
    }
}

The child JPanels are expanding to fill the vertical space. I tried using glue because I thought that's what glue was for, but it seems to do nothing at all. Any help?

Note: I have found questions that look almost identical, but none with answers I can apply.


Solution

  • One solution: nest JPanels with the outer JPanel using Borderlayout and adding the BoxLayout using JPanel to this one BorderLayout.NORTH, also known as BorderLayout.PAGE_START:

    Edit for Kleopatra:

    import javax.swing.*;
    import java.awt.*;
    
    public class TextAreaTester {
       public static void main(String[] args) {
          new TextAreaTester();
       }
    
       public TextAreaTester() {
          JFrame frame = new JFrame();
          JPanel panel = new JPanel();
          panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
          // panel.setPreferredSize(new Dimension(100,400));
          for (int i = 0; i < 3; i++) {
             JPanel item = new JPanel(new BorderLayout());
             // item.setLayout(new BoxLayout(item,BoxLayout.LINE_AXIS));
             JTextArea textarea = new JTextArea(
                   "this is a line of text I want to wrap if necessary", 3, 35);
             textarea.setWrapStyleWord(true);
             textarea.setLineWrap(true);
             // textarea.setMaximumSize(textarea.getPreferredSize());
             // item.setMaximumSize( item.getPreferredSize() );
             item.add(new JScrollPane(textarea), BorderLayout.NORTH);
             panel.add(item);
          }
          panel.add(Box.createGlue());
    
          JPanel mainPanel = new JPanel(new BorderLayout()) {
             private final int prefW = 100;
             private final int prefH = 400;
    
             @Override
             public Dimension getPreferredSize() {
                return new Dimension(prefW, prefH);
             }
          };
          // mainPanel.setPreferredSize(new Dimension(100, 400));
          mainPanel.add(panel, BorderLayout.PAGE_START);
    
          frame.add(mainPanel);
          frame.setVisible(true);
          // frame.getContentPane().add(jp);
          frame.pack();
       }
    }