Java JPanels don';t完全伸展以占据可用空间

Java JPanels don';t完全伸展以占据可用空间,java,swing,awt,jpanel,border-layout,Java,Swing,Awt,Jpanel,Border Layout,我有一个面板,我将几个小面板并排放置,大小和颜色不同,它们应该占据整个父面板(水平) 为此,我使用BorderLayout(用于父面板)和BoxLayout(用于放置所有迷你面板的子面板)(请参见下面的代码)。它在调整大小和所有方面都能正常工作和工作。但是,随着迷你面板数量的增加,会出现一种奇怪的行为:在父面板的末尾会出现空白 我想我发现这是布局管理器中的一个拉伸缺陷,因为为了拉伸面板,布局管理器尝试向每个迷你面板添加一个像素。但是,当迷你面板的数量较大时,向每个面板添加一个像素将导致添加许多

我有一个面板,我将几个小面板并排放置,大小和颜色不同,它们应该占据整个父面板(水平)

为此,我使用BorderLayout(用于父面板)和BoxLayout(用于放置所有迷你面板的子面板)(请参见下面的代码)。它在调整大小和所有方面都能正常工作和工作。但是,随着迷你面板数量的增加,会出现一种奇怪的行为:在父面板的末尾会出现空白

我想我发现这是布局管理器中的一个拉伸缺陷,因为为了拉伸面板,布局管理器尝试向每个迷你面板添加一个像素。但是,当迷你面板的数量较大时,向每个面板添加一个像素将导致添加许多像素并超出父面板的大小。因此,布局管理器最终不会向任何小面板添加任何像素,从而导致空间变空

这是我的SSCCE: (试着跑一跑,打开窗户,了解问题所在)

package com.myPackage;
导入java.awt.*;
导入java.util.Vector;
导入javax.swing.BorderFactory;
导入javax.swing.BoxLayout;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类彩色面板扩展了JPanel
{
/*内容信息*/
私有向量划分;
私有向量颜色;
/*内容面板将要放置的面板*/
私人JPanel内容持有者;
私人最终int默认高度=20;
公共彩色面板(矢量分区、矢量颜色)
{
断言分区!=null;
assert!partitions.isEmpty();
断言颜色!=null;
断言!colors.isEmpty();
断言colors.size()==partitions.size();
this.partitions=分区;
这个。颜色=颜色;
/*设置布局管理器*/
setLayout(新的BorderLayout());
/*创建内容持有者*/
contentHolder=newjpanel();
setLayout(新的BoxLayout(contentHolder,BoxLayout.X_轴));
添加(contentHolder,BorderLayout.NORTH);
/*用彩色面板填充内容架*/
createPanels();
}
私有void createPanels()
{
断言分区!=null;
assert!partitions.isEmpty();
断言颜色!=null;
断言!colors.isEmpty();
断言colors.size()==partitions.size();
对于(int i=0;i
我如何避免这种行为?我希望我的面板占据整个容器

编辑:
迷你面板旨在(解决此问题后)具有鼠标侦听器。因此,油漆解决方案是不可避免的。

我可以想到两种选择:

  • 有一个自定义组件,该组件有一个绘制所有区域的
    paintComponent(…)
    方法,当窗口调整大小时,它将重新绘制区域,同时根据新的宽度信息缩放它们

  • 在图像上绘制彩色区域一次,然后绘制该图像,当窗口调整大小时,重新缩放图像以适应


  • 我曾经在为棋盘使用GridLayout时遇到过这个问题。我的解决方案是扩展GridLayout并用浮点精度计算布局。

    布局问题通过。。。LayoutManager:-)如果一个人不知道你想要它做什么,那么就实施你想要的行为

    因此,如果core BoxLayout由于舍入错误而忽略了像素,那么就创建子类并使其根据需要分布这些像素。一个非常简单的例子:

    public static class XBoxLayout extends BoxLayout {
    
        enum Strategy {
            NONE,
            STRETCH_LAST,
            DISTRUBUTE
        }
    
        private Strategy strategy;
    
        public XBoxLayout(Container target, int axis, Strategy strategy) {
            super(target, axis);
            this.strategy = strategy;
        }
    
    
        @Override
        public void layoutContainer(Container target) {
            super.layoutContainer(target);
            if (Strategy.NONE == strategy) return;
            Insets targetInsets = target.getInsets();
            int targetSize = target.getWidth() - targetInsets.left - targetInsets.right;
            int childSum = 0;
            for (Component child : target.getComponents()) {
                childSum += child.getWidth();
            }
            if (targetSize > childSum) {
                int excess = targetSize - childSum;
                distribute(target, excess);
            }
        }
    
    
        private void distribute(Container target, int excess) {
            System.out.println("childCount/rounding excess " + target.getComponentCount() + "/" + excess);
            if (Strategy.STRETCH_LAST == strategy) {
                Component lastChild = target.getComponent(target
                        .getComponentCount() - 1);
                lastChild.setSize(lastChild.getWidth() + excess,
                        lastChild.getHeight());
            } else {
                int firstToDistribute = target.getComponentCount() - excess;
                int summedOffset = 0;
                for(int index = firstToDistribute; index < target.getComponentCount(); index++) {
                    Component child = target.getComponent(index);
                    Rectangle bounds = child.getBounds();
                    bounds.x += summedOffset++;
                    bounds.width += 1;
                    child.setBounds(bounds);
                }
            }
        }
    
    }
    
    公共静态类XBoxLayout扩展了BoxLayout{
    枚举策略{
    没有一个
    最后一个,
    怀疑
    }
    私人战略;
    公共XBoxLayout(容器目标、int轴、策略){
    超级(目标、轴);
    这个。策略=策略;
    }
    @凌驾
    公共void布局容器(容器目标){
    超级.布局容器(目标);
    如果(Strategy.NONE==策略)返回;
    Insets targetSets=target.getInsets();
    int targetSize=target.getWidth()-targetSets.left-targetSets.right;
    int childSum=0;
    for(组件子级:target.getComponents()){
    childSum+=child.getWidth();
    }
    如果(targetSize>childSum){
    int excess=targetSize-childSum;
    分配(目标、超额);
    }
    }
    私有void分发(容器目标,整数过量){
    System.out.println(“childCount/舍入超额”+target.getComponentCount()+“/”+超额);
    if(Strategy.STRETCH_LAST==策略){
    Component lastChild=target.getComponent(目标
    .getComponentCount()-1);
    lastChild.setSize(lastChild.getWidth()+多余,
    lastChild.getHeight());
    }否则{
    
    public static class XBoxLayout extends BoxLayout {
    
        enum Strategy {
            NONE,
            STRETCH_LAST,
            DISTRUBUTE
        }
    
        private Strategy strategy;
    
        public XBoxLayout(Container target, int axis, Strategy strategy) {
            super(target, axis);
            this.strategy = strategy;
        }
    
    
        @Override
        public void layoutContainer(Container target) {
            super.layoutContainer(target);
            if (Strategy.NONE == strategy) return;
            Insets targetInsets = target.getInsets();
            int targetSize = target.getWidth() - targetInsets.left - targetInsets.right;
            int childSum = 0;
            for (Component child : target.getComponents()) {
                childSum += child.getWidth();
            }
            if (targetSize > childSum) {
                int excess = targetSize - childSum;
                distribute(target, excess);
            }
        }
    
    
        private void distribute(Container target, int excess) {
            System.out.println("childCount/rounding excess " + target.getComponentCount() + "/" + excess);
            if (Strategy.STRETCH_LAST == strategy) {
                Component lastChild = target.getComponent(target
                        .getComponentCount() - 1);
                lastChild.setSize(lastChild.getWidth() + excess,
                        lastChild.getHeight());
            } else {
                int firstToDistribute = target.getComponentCount() - excess;
                int summedOffset = 0;
                for(int index = firstToDistribute; index < target.getComponentCount(); index++) {
                    Component child = target.getComponent(index);
                    Rectangle bounds = child.getBounds();
                    bounds.x += summedOffset++;
                    bounds.width += 1;
                    child.setBounds(bounds);
                }
            }
        }
    
    }