I am developing a Swing application using BorderLayout
to position the components. Since BorderLayout.CENTER
positions components to whatever is left after the other components are placed, and that fact is making my GUI look weird, I was wondering if there was a way to position components to true center, rather than in between the two sides. Since BorderLayout
spaces make a component fill an entire space, I'm guessing the solution would be to wrap the component into a JPanel
. However, positioning the component to the center of this panel will make the component be closer to one side than another if you have components on other sides. How do I work around this?
These images demonstrate the problem and the ideal solution; the gray border represents the BorderLayout.SOUTH
(wrapped in a JPanel
) of the main frame. The black squares represents components that are throwing the center component off. The red square represents the component that needs to be centered.
Problem:
Ideal solution:
As I see the problem, in order for the red component to be centered the right and left components must be of equal size.
You might be able to use the Relative Layout.
The RelativeLayout
will allow you to make the right/left components the same size while keeping the center component at its preferred size. As the frame is resized space will be added/removed from the right/left components.
For example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
JPanel left = new JPanel( new FlowLayout(FlowLayout.LEFT) );
JPanel leftBox = new JPanel();
leftBox.setPreferredSize( new Dimension(200, 50) );
leftBox.setBackground( Color.BLACK );
left.add( leftBox );
JPanel center = new JPanel( new FlowLayout(FlowLayout.CENTER) );
JPanel centerBox = new JPanel();
centerBox.setPreferredSize( new Dimension(50, 50) );
centerBox.setBackground( Color.RED );
center.add( centerBox );
JPanel right = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
JPanel rightBox = new JPanel();
rightBox.setPreferredSize( new Dimension(50, 50) );
rightBox.setBackground( Color.BLACK );
right.add( rightBox );
setLayout( new RelativeLayout(RelativeLayout.X_AXIS, 5) );
add(left, new Float(1));
add(center);
add(right, new Float(1));
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
The one problem with the relative layout is that when you pack the frame the components will be dislayed too small since the preferred size is simply the sum of the components. So the left panel will be truncated.
In the example above you can add the following to get around this problem:
right.add( rightBox );
right.setPreferredSize( left.getPreferredSize() ); // added
Another option might be to use the OverlayLayout
which can be set up to display the red panel over top of a panel containing the two other components:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
JPanel left = new JPanel( new FlowLayout(FlowLayout.LEFT) );
JPanel leftBox = new JPanel();
leftBox.setPreferredSize( new Dimension(200, 50) );
leftBox.setBackground( Color.BLACK );
left.add( leftBox );
JPanel center = new JPanel( new FlowLayout(FlowLayout.CENTER) );
center.setOpaque(false);
JPanel centerBox = new JPanel();
centerBox.setPreferredSize( new Dimension(50, 50) );
centerBox.setBackground( Color.RED );
center.add( centerBox );
JPanel right = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
JPanel rightBox = new JPanel();
rightBox.setPreferredSize( new Dimension(50, 50) );
rightBox.setBackground( Color.BLACK );
right.add( rightBox );
JPanel main = new JPanel( new BorderLayout() );
main.add(left, BorderLayout.LINE_START);
main.add(right, BorderLayout.LINE_END);
setLayout( new OverlayLayout(this) );
add(center);
add(main);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}