Search code examples
jpaneljcomponentflowlayoutboxlayout

JPanel FlowLayout Force Component Wrap


I have an JPanel that uses by default a FlowLayout manager. I like the advantage of the document style FlowLayout in which I add components one at a time with automatic wrapping but would like a component to force selection of a new line.

I read if I used a BoxLayout I could insert a sort of component return key and force the components to start on a new line. I need guidance regarding my decision and which is a better approach.

I have a JLabel and JTextField on one line and would like to place a JTextArea wrapped inside a JScrollPane below.


Solution

    • Use a combination of FlowLayout and BorderLayout. It's a good idea to nest layouts to get your desired result.
    • The JLabel and the JTextField would go in one JPanel with FlowLayout
    • Then another JPanel with BorderLayout will hold the previous panel at the NORTH position, and the JTextArea with JScrollPane at the CENTER position.

      JPanel topPanel = new JPanel();
      JLabel label = new JLabel("Text Field Label");
      JTextField jtf = new JTextField(20);
      topPanel.add(label);
      topPanel.add(jtf);
      
      JPanel bothPanel = new JPanel(new BorderLayout());
      JTextArea jta = new JTextArea(20, 40);
      bothPanel.add(topPanel, BorderLayout.NORTH);
      bothPanel.add(new JScrollPane(jta));
      

    Have a look at Laying Out Components Within a Container

    enter image description here

    import java.awt.BorderLayout;
    import java.awt.Color;
    
    import javax.swing.BorderFactory;
    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;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class FlowBorderDemo {
    
        public FlowBorderDemo() {
            JPanel topPanel = new JPanel();
            JLabel label = new JLabel("Text Field Label");
            label.setForeground(Color.white);
            JTextField jtf = new JTextField(20);
            topPanel.add(label);
            topPanel.add(jtf);
            topPanel.setBackground(Color.black);
    
    
            JPanel bothPanel = new JPanel(new BorderLayout());
            JTextArea jta = new JTextArea(20, 40);
            JScrollPane scrollPane = new JScrollPane(jta);
            scrollPane.setBorder(BorderFactory.createMatteBorder(3, 0, 0, 0, Color.GRAY));
            bothPanel.add(topPanel, BorderLayout.NORTH);
            bothPanel.add(scrollPane);
            bothPanel.setBorder(BorderFactory.createMatteBorder(3, 8, 3, 8, Color.GRAY));
    
            JLabel copyLabel = new JLabel("<html>&copy;2014 peeskillet</html>");
            copyLabel.setBackground(Color.LIGHT_GRAY);
            copyLabel.setHorizontalAlignment(JLabel.CENTER);
            bothPanel.add(copyLabel, BorderLayout.PAGE_END);
    
    
            JFrame frame = new JFrame();
            frame.add(bothPanel);
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager
                                .getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException
                            | IllegalAccessException
                            | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    new FlowBorderDemo();
                }
            });
        }
    }