I have a panel where I place several mini-panels, side by side, with different sizes and colors, and they should occupy the entire parent panel (horizontally).
For this, I use BorderLayout (for the parent panel) and BoxLayout for the sub-panel, where I place all the mini-panels (see code below). It really works and behaves correctly, increasing the size and that's it. However, as the number of mini-panels increases, a strange behavior occurs: an empty space appears at the end of the parent panel.

I think I discovered that this is a problem with shooting in layout managers, because in order to stretch the panels, the layout manager tries to add one pixel to each mini-panel. However, when the number of mini-panels is large, adding one pixel to each of them will add many pixels and go beyond the size of the parent. Thus, the layout manager ends up not adding any pixels to any mini-panel, which leads to empty space.
Here is my SSCCE: (try starting and stretching the window to understand the problem)
package com.myPackage; import java.awt.*; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JFrame; import javax.swing.JPanel; public class ColoredPanels extends JPanel { private Vector<Integer> partitions; private Vector<Color> colors; private JPanel contentHolder; private final int defaultHeight = 20; public ColoredPanels(Vector<Integer> partitions, Vector<Color> colors) { assert partitions != null; assert !partitions.isEmpty(); assert colors != null; assert !colors.isEmpty(); assert colors.size() == partitions.size(); this.partitions = partitions; this.colors = colors; setLayout(new BorderLayout()); contentHolder = new JPanel(); contentHolder.setLayout(new BoxLayout(contentHolder, BoxLayout.X_AXIS)); this.add(contentHolder, BorderLayout.NORTH); createPanels(); } private void createPanels() { assert partitions != null; assert !partitions.isEmpty(); assert colors != null; assert !colors.isEmpty(); assert colors.size() == partitions.size(); for (int i = 0; i < partitions.size(); i++) { JPanel newPanel = new JPanel(); newPanel.setBackground(colors.get(i)); newPanel.setPreferredSize(new Dimension(partitions.get(i), defaultHeight)); newPanel.setMinimumSize(new Dimension(1, defaultHeight)); contentHolder.add(newPanel); } } public static void main(String[] in) { Vector<Integer> sizes = new Vector<Integer>(); Vector<Color> cols = new Vector<Color>(); for (int i = 0; i < 100; i++) { int size = (int)Math.round(1 + Math.random() * 10); sizes.add(size); cols.add((i%2 == 0)? Color.red : Color.green); } ColoredPanels panels = new ColoredPanels(sizes, cols); panels.setBorder(BorderFactory.createLineBorder(Color.yellow, 1)); JFrame newFrame = new JFrame(); newFrame.getContentPane().add(panels); newFrame.pack(); newFrame.setVisible(true); } }
How to avoid this behavior? I want my panels to occupy the entire container.
EDIT: Mini-panels are designed to have (after it is allowed) a listener mouse. Thus, paint solutions, unfortunately, can be avoided.