javaswinglayoutlayout-managerspringlayout

SpringLayout not correctly spacing


I am using Spring Layout to design a gui for an application I am building. I am having an issue with spring layout; the components do not have correct spacing between then, specifically the message box and the send button as seen in the picture:

Spring Layout Issue

Here is the code for the application:

package com.cliff777.chat;

import java.awt.Container;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;

public class ChatMain
{
final int WIDTH = 800;
final int HEIGHT = 600;

JTextField messageBox = new JTextField(); //write a message in
JTextArea chatBox = new JTextArea(); //displays the messages
JButton sendButton = new JButton("Send");

void setupGui(Container container)
{
    container.setPreferredSize(new Dimension(WIDTH, HEIGHT));

    SpringLayout layout = new SpringLayout();
    container.setLayout(layout);

    container.add(messageBox);
    container.add(chatBox);
    container.add(sendButton);


    layout.putConstraint(SpringLayout.NORTH, chatBox, 5, SpringLayout.NORTH, container);
    layout.putConstraint(SpringLayout.WEST, chatBox, 5, SpringLayout.WEST, container);
    layout.putConstraint(SpringLayout.EAST, chatBox, 5, SpringLayout.EAST, container);
    layout.putConstraint(SpringLayout.SOUTH, chatBox, 5, SpringLayout.NORTH, messageBox);
    layout.putConstraint(SpringLayout.SOUTH, chatBox, 5, SpringLayout.NORTH, sendButton);

    layout.putConstraint(SpringLayout.WEST, messageBox, 5, SpringLayout.WEST, container);
    layout.putConstraint(SpringLayout.SOUTH, messageBox, 5, SpringLayout.SOUTH, container);
    layout.putConstraint(SpringLayout.EAST, messageBox, 5, SpringLayout.WEST, sendButton);

    layout.putConstraint(SpringLayout.EAST, sendButton, 5, SpringLayout.EAST, container);
    layout.putConstraint(SpringLayout.SOUTH, sendButton, 5, SpringLayout.SOUTH, container);



    //container.add(messageBox);
    //container.add(chatBox);
    //container.add(sendButton);


}

public ChatMain()
{
    JFrame frame = new JFrame("Chat");

    setupGui(frame.getContentPane());

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);

    chatBox.setEditable(false);

    while(true)
    {
        chatBox.setText(chatBox.getText() + messageBox.getText());
        messageBox.setText("");

        try
        {
            Thread.sleep(5000);
        }
        catch (Exception e)
        {

        }
    }

}

public static void main(String[] args)
{
    new ChatMain();     
}
}

Solution

  • Declaring preferred size container.setPreferredSize(new Dimension(WIDTH, HEIGHT)); does not automatically means that layout knows the width and height of the container. Actually the layout knows them (width and height) but it also want to know how to behave on window resizing. SpringLayout likes to ignore sizes and do it every time it can.
    The following constraints may be the ones you need:

    // set the borders of chatBox
    layout.putConstraint(SpringLayout.NORTH, chatBox, 5, SpringLayout.NORTH, container);
    layout.putConstraint(SpringLayout.WEST, chatBox, 5, SpringLayout.WEST, container);
    layout.putConstraint(SpringLayout.EAST, chatBox, 5, SpringLayout.EAST, container);
    
    // set the borders of messageBox
    layout.putConstraint(SpringLayout.NORTH, messageBox, 5, SpringLayout.SOUTH, chatBox);
    layout.putConstraint(SpringLayout.WEST, messageBox, 5, SpringLayout.WEST, container);
    
    // set the borders of sendButton
    layout.putConstraint(SpringLayout.NORTH, sendButton, 5, SpringLayout.SOUTH, chatBox);
    layout.putConstraint(SpringLayout.WEST, sendButton, 5, SpringLayout.EAST, messageBox);
    
    // the most importent part set the borders of container (you need only bottom-right)
    layout.putConstraint(SpringLayout.EAST, container, 5, SpringLayout.EAST, sendButton);
    layout.putConstraint(SpringLayout.SOUTH, container, 5, SpringLayout.SOUTH, sendButton);
    

    The main problem in your program was not clear borders for container and as a result strange overlapping.

    For more complicated tasks you may look in the direction of GridBagLayout.