JPanels don не растягивается полностью, чтобы занять доступное пространство

у меня есть панель, на которой я размещаю несколько мини-панелей рядом друг с другом, с разными размерами и цветами, и они должны занимать всю родительскую панель (по горизонтали).

Для этого я использую BorderLayout (для родительской панели) и BoxLayout для вспомогательной панели, куда я помещаю все мини-панели (см. Код ниже). Он действительно работает и ведет себя правильно после изменения размера и всего остального. Однако, как количество мини-панелей увеличивается, возникает странное поведение: в конце родительской панели появляется пустое место.

enter image description here

Думаю, я обнаружил, что это ошибка растягивания в менеджерах компоновки, потому что для растягивания панелей менеджер компоновки пытается добавить один пиксель к каждой мини-панели. Однако, когда количество мини-панелей велико, добавление одного пикселя к каждой приведет к добавлению большого количества пикселей и выходу за пределы размера родительского элемента. Таким образом, менеджер компоновки не добавляет пиксели ни на одну мини-панель, что приводит к пустому пространству.

Вот мой SSCCE: (попробуйте запустить и растянуть окно, чтобы понять проблему)

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
{
    /* Content information. */
    private Vector<Integer> partitions;
    private Vector<Color> colors;

    /* Panel where the content panels will go. */
    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;

        /* Set layout manager. */
        setLayout(new BorderLayout());

        /* Create the content holder. */
        contentHolder = new JPanel();
        contentHolder.setLayout(new BoxLayout(contentHolder, BoxLayout.X_AXIS));
        this.add(contentHolder, BorderLayout.NORTH);

        /* Fill content holder with colored panels. */
        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>();

        /* Make 100 random sizes, and use two colors. */
        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);
    }
}

Как мне избежать такого поведения? Я хочу, чтобы мои панели занимали весь контейнер.

РЕДАКТИРОВАТЬ: Мини-панели предназначены для (как только эта проблема будет разрешена) иметь слушателей мыши. Таким образом, покрасочных растворов, к сожалению, можно избежать.

6
задан mKorbel 13 February 2012 в 15:08
поделиться