javaswingawtlayout-managerboxlayout

Why BoxLayout is taking extra space?


I am working on a Client-Server Chatting Application in which I am trying to create Speech Bubble like we have in WhatsApp

I want to show sent messages on the right side of the frame and received messages on the left side of the frame, I am trying to achieve this using BoxLayout but it is taking extra space (like in picture below)
enter image description here

This is what I have done till now

a1.setLayout(new BoxLayout(a1, BoxLayout.Y_AXIS));
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));

The extra space you see between the two messages is because of BoxLayout which I am using
What to do in this case? and any alternatives how can we achieve this by not using BoxLayout?


Solution

  • So the FlowLayout respected the preferred height, but it also respected the preferred width.

    Instead you need a layout that will:

    1. respect the height of the component you add to the BoxLayout
    2. fills the width of the available space.

    You can use a BorderLayout for this:

    import java.awt.*;
    import javax.swing.*;
    
    public class SSCCE extends JPanel
    {
        public SSCCE()
        {
            setLayout( new BorderLayout() );
    
            Box vertical = Box.createVerticalBox();
            add(vertical, BorderLayout.PAGE_START);
    
            for (int i = 0; i < 10; i++)
            {
                JPanel left = new JPanel( new BorderLayout() );
                left.add(new JLabel("left message " + i), BorderLayout.LINE_START);
                vertical.add( left );
                JPanel right = new JPanel( new BorderLayout() );
                right.add(new JLabel("right message " + i), BorderLayout.LINE_END);
                vertical.add( right );
            }
        }
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add( new JScrollPane(new SSCCE()) );
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args) throws Exception
        {
            java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
        }
    }