Reputation: 1437
When using a GridLayout, it diveds its container's space evenly between its row and column elements. However when calcuating the cell width wouldn't turn out in an integer, the exceeding space is put between the container's edges and its content in a way, that the container's content is centered by the GridLayout.
In this picture you can see exceeding space (colored green):
Since the frame's size is dragged to 233x233 the LayoutManager would offer each component floor(233 / 20) = 11 pixels height and width. Thus 233 % 20 = 13 pixels exceed and are put at the edges.
That's the code to generate the frame in the picture:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridLayout layout = new GridLayout(20, 0);
layout.setHgap(0);
layout.setVgap(0);
frame.setLayout(layout);
for (int j = 0; j < 20; j++) {
for (int i = 0; i < 20; i++) {
JPanel panel = new JPanel();
panel.setBackground((i + j) % 2 == 0 ? Color.BLACK : Color.WHITE);
frame.add(panel);
}
}
frame.pack();
frame.getContentPane().setBackground(Color.GREEN);
frame.setVisible(true);
So I wonder if there's an easy way to make the container 'clip' or align in a way, that this exceeding space doesn't show up, but instead the container is resized to fit its content perfectly.
Upvotes: 0
Views: 1033
Reputation: 324167
That's right but I want to keep the advantage of a GridLayout offering every cell the same size,
Yes well you can't have it both ways.
If you want every cell to be the same size, then you will see the background. One option would be to make the panel non-opaque, so you don't see the background of the panel.
If you want to completely fill the area available with the components, then some components will need to be a different size by one pixel.
For implementing point 2, maybe this example will be easy enough for you to use:
import java.awt.*;
import javax.swing.*;
public class BoardTest
{
private static void createAndShowGUI()
{
Float constraint = new Float(1);
RelativeLayout boardLayout = new RelativeLayout(RelativeLayout.Y_AXIS);
boardLayout.setRoundingPolicy( RelativeLayout.EQUAL );
boardLayout.setFill(true);
JPanel board = new JPanel(boardLayout);
board.setBackground(Color.GREEN);
RelativeLayout rowLayout = new RelativeLayout(RelativeLayout.X_AXIS);
rowLayout.setRoundingPolicy( RelativeLayout.EQUAL );
rowLayout.setFill(true);
for (int j = 0; j < 20; j++)
{
JPanel row = new JPanel( rowLayout );
for (int i = 0; i < 20; i++)
{
JPanel square = new JPanel();
square.setBackground((i + j) % 2 == 0 ? Color.BLACK : Color.WHITE);
row.add(square, constraint);
}
board.add(row, constraint);
}
JFrame frame = new JFrame("BoardTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(board);
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
It uses the Relative Layout class which allows you to control how the extra pixels are allocated to each of the components.
Upvotes: 1