So I have a splitPane with 2 sides which contain 2 panels. One of the panel is a checked one (splitted into squares) BUT it has unexpected margins around it. Here is a screenshot of what I mean http://prntscr.com/pxwfsk . How can I get rid of those margins , because for my program it is crucial. Thank in advance. Here is a part of the code which is responsible for creating splitPane and JPanels:
public static void workingFrame() throws InterruptedException {
String frameName = "Bot World";
World world = new World(); // creating right side with world for bots
WorkFrame workF = new WorkFrame(0, 0, frameName);
wfFrame = workF.newFrame();
wfFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
wfFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JSplitPane splitPane = new JSplitPane();
splitPane.setSize(width, height);
// splitPane.setDividerSize(1);
// splitPane.setDividerLocation(149);
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
JPanel panelLeft = createLftPanel();
JPanel panelRight = world.createRightPanel();
splitPane.setLeftComponent(panelLeft);
splitPane.setRightComponent(panelRight);
wfFrame.add(splitPane);
wfFrame.revalidate();
wfFrame.setVisible(true);
// WE NEED THIS HERE because otherwise PC is not fast enough to establish all the JPanles inside the main panel
// and thus later on we cannot use method GetComponent();
Thread.sleep(1000);
// create bots on random location on panels
for (int i = 0; i < 1; i++) {
world.createBots();
// add counter to start counting bots on a map
}
for (int i = 0; i < 1; i++) {
// create food in this world
world.createFood();
}
wfFrame.revalidate();
while (world.bots.size() > 0) {
for (Bot bot : world.bots) {
if (bot.isAlive) {
bot.seePathInDirection(panelRight);
Thread.sleep(500);
wfFrame.revalidate();
}
Thread.sleep(500);
wfFrame.revalidate();
}
}
}
}
and createRightPanel method:
public static JPanel createRightPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(ROWS, COLS));
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
JPanel pane = new JPanel();
pane.setBackground(Color.WHITE);
pane.setBorder(BorderFactory.createLineBorder(Color.black));
panel.add(pane);
}
}
botWorld = panel;
return panel;
}
There are some "problems" with your code. First, do not use setSize
(nor setPreferredSize
) method of a component. Let the layout manager calculate its size and position.
Do not use Thread.sleep()
in the Event Dispatch Thread. It will freeze the whole GUI. Since the thread sleeps, events cannot take place. Consider using a Swing Timer or a Swing Worker.
Because grid layout will give equal size to all of its components. It is actually kind of hard to get it, so I will try to explain it with an example.
Consider a panel with grid layout, with only 1 row and 10 columns. You try to add 10 components to it. This panel's width is equals to 100. Grid layout will give 10 width to each component, so 10x10 = 100.
Now, consider this panels width to be 102. How is gridlayout going to share it equally? It can't. So it will let 1 pixel empty from left, and 1 pixel from right. That's exactly you are facing. Since the GridLayout cannot share the width (and height) equally, it will let it empty. If you make the window bigger, at one moment the space will be enough to fit them equally:
See this .gif:
At the time when width is equals to 795-801, grid layout can not share the space equally to the 20 components a row has. When it goes 802, the margin that annoys you go away. That's because 20 components in row / 800 = 40 width for each component. +2 the left and right border (the green one).
The code that produces this behavior:
public class Example extends JFrame implements ComponentListener {
private static final int ROWS = 20;
private static final int COLUMNS = 20;
private JLabel widthLabel;
private JPanel greenPanel;
public Example() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JPanel redPanel = new JPanel();
redPanel.setBorder(BorderFactory.createLineBorder(Color.RED, 1));
widthLabel = new JLabel();
redPanel.add(widthLabel);
greenPanel = new JPanel(new GridLayout(ROWS, COLUMNS));
greenPanel.setBorder(BorderFactory.createLineBorder(Color.GREEN, 1));
greenPanel.addComponentListener(this);
for (int i = 0; i < ROWS * COLUMNS; i++) {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
greenPanel.add(panel);
}
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, redPanel, greenPanel);
add(splitPane);
setLocationByPlatform(true);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Example().setVisible(true);
});
}
@Override
public void componentResized(ComponentEvent e) {
widthLabel.setText("Green panel's width: " + greenPanel.getWidth());
}
@Override
public void componentMoved(ComponentEvent e) {
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentHidden(ComponentEvent e) {
}
}
And to answer your comment, no. It is irrelevant what kind of component is inside grid layout. So JPanels or not, it plays no role.