Java 调整多个JPanel的大小以适应窗口

Java 调整多个JPanel的大小以适应窗口,java,swing,jpanel,layout-manager,boxlayout,Java,Swing,Jpanel,Layout Manager,Boxlayout,我对JavaSwing工具包非常陌生,已经创建了一系列JPanel,其中JLabel组件对应于每个面板的索引和值。但是,当窗口太小,无法同时调整所有面板的大小时,我似乎无法正确调整面板的大小。导致在所有面板的右侧有一个额外的红色边距(参见) 是否有办法使子面板/间隔面板的大小调整为不允许额外的余量?或者设置更好的swing布局来处理这种大小调整 代码演示: import java.awt.*; import javax.swing.JFrame; import javax.swing.JLabe

我对JavaSwing工具包非常陌生,已经创建了一系列
JPanel
,其中
JLabel
组件对应于每个面板的索引和值。但是,当窗口太小,无法同时调整所有面板的大小时,我似乎无法正确调整面板的大小。导致在所有面板的右侧有一个额外的红色边距(参见)

是否有办法使子面板/间隔面板的大小调整为不允许额外的余量?或者设置更好的swing布局来处理这种大小调整

代码演示:

import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import javax.swing.BoxLayout;

public class Frame extends JFrame {
    private int numBox = 20;

    public class SubPanel extends JPanel {
        public SubPanel(int i) {
            setMinimumSize(new Dimension(20, 20));
            setMaximumSize(new Dimension(1000, i*30));
            setBackground(Color.BLACK);
            setLayout(new BorderLayout());
            setAlignmentY(Component.BOTTOM_ALIGNMENT);

            JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
            labelValue.setForeground(Color.WHITE);
            add(labelValue, BorderLayout.NORTH);

            JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
            labelIndex.setForeground(Color.WHITE);
            add(labelIndex, BorderLayout.SOUTH);
        }
    }

    public class SpacerPanel extends JPanel {
        public SpacerPanel() {
            setBackground(Color.WHITE);
            setMaximumSize(new Dimension(3, 10000));
            setMinimumSize(new Dimension(3, 0));
        }
    }

    public Frame(String title) {
        super(title);

        JPanel mainPanel = new JPanel();
        mainPanel.setBackground(Color.RED);
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));

        for (int i = 1; i < numBox + 1; i++) {
            mainPanel.add(new SpacerPanel());
            mainPanel.add(new SubPanel(i));
        }
        mainPanel.add(new SpacerPanel());

        add(mainPanel);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Frame("Frame").setSize(1200, 700);
    }
}
import java.awt.*;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.BoxLayout;
公共类框架扩展了JFrame{
私有int numBox=20;
公共类子面板扩展了JPanel{
公共子面板(int i){
设置最小尺寸(新尺寸(20,20));
设置最大尺寸(新尺寸(1000,i*30));
挫折背景(颜色:黑色);
setLayout(新的BorderLayout());
setAlignmentY(组件底部对齐);
JLabel labelValue=新的JLabel(String.valueOf(30*i),JLabel.CENTER);
标签值。设置前景(颜色。白色);
添加(labelValue,BorderLayout.NORTH);
JLabel labelIndex=新的JLabel(字符串.valueOf(i),JLabel.CENTER);
标签索引设置前景(颜色白色);
添加(labelIndex,BorderLayout.SOUTH);
}
}
公共类面板扩展了JPanel{
公共事务委员会(){
挫折地面(颜色:白色);
setMaximumSize(新尺寸(31000));
setMinimumSize(新尺寸(3,0));
}
}
公共框架(字符串标题){
超级(标题);
JPanel mainPanel=新的JPanel();
主面板。立根背景(颜色。红色);
mainPanel.setLayout(新的BoxLayout(mainPanel,BoxLayout.LINE_轴));
对于(int i=1;i
如果您有40个组件,并且将框架大小调整了几个像素,则BoxLayout在将这些像素分配给每个组件时会出现问题

相反,您可以使用,它允许您指定如何分配这些像素

RelativeLayout
还允许您指定每个组件之间的间隙,因此无需添加间隔器面板

但是,您需要修改“子面板”的逻辑。标签的高度需要固定,以便将其涂成黑色。所以我创建了一个“labelPanel”来保存标签

使用
RelativeLayout
重新构造的代码将是:

import java.awt.*;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;

import javax.swing.BoxLayout;

public class Frame extends JFrame {
    private int numBox = 20;

    public class SubPanel extends JPanel {
        public SubPanel(int i) {
//            setMinimumSize(new Dimension(20, 20));
//            setMaximumSize(new Dimension(1000, i*30));
//            setPreferredSize(new Dimension(20, i*30));
            setBackground(Color.RED);
            setLayout(new BorderLayout());
//            setAlignmentY(Component.BOTTOM_ALIGNMENT);

            JPanel labelPanel = new JPanel( new BorderLayout() );
            labelPanel.setBackground( Color.BLACK );
            labelPanel.setPreferredSize(new Dimension(20, i*30));
            add(labelPanel, BorderLayout.PAGE_END);

            JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
            labelValue.setForeground(Color.WHITE);
            labelPanel.add(labelValue, BorderLayout.NORTH);

            JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
            labelIndex.setForeground(Color.WHITE);
            labelPanel.add(labelIndex, BorderLayout.SOUTH);
        }
    }

    public class SpacerPanel extends JPanel {
        public SpacerPanel() {
            setBackground(Color.WHITE);
            setMaximumSize(new Dimension(3, 10000));
            setMinimumSize(new Dimension(3, 0));
        }
    }

    public Frame(String title) {
        super(title);

        JPanel mainPanel = new JPanel();
//        mainPanel.setBackground(Color.RED);
        mainPanel.setBackground(Color.WHITE);

//        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
        RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS, 5);
        rl.setFill( true );
        rl.setRoundingPolicy(RelativeLayout.EQUAL);
        rl.setAlignment(RelativeLayout.TRAILING);
        mainPanel.setLayout( rl );
        Float constraint = new Float(1);

        for (int i = 1; i < numBox + 1; i++) {
//            mainPanel.add(new SpacerPanel());
//            mainPanel.add(new SubPanel(i));
            mainPanel.add(new SubPanel(i), constraint);
        }
//        mainPanel.add(new SpacerPanel());

        add(mainPanel);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Frame("Frame").setSize(1200, 700);
    }
}
import java.awt.*;
导入javax.swing.*;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.BoxLayout;
公共类框架扩展了JFrame{
私有int numBox=20;
公共类子面板扩展了JPanel{
公共子面板(int i){
//设置最小尺寸(新尺寸(20,20));
//设置最大尺寸(新尺寸(1000,i*30));
//设置首选尺寸(新尺寸(20,i*30));
挫折地面(颜色:红色);
setLayout(新的BorderLayout());
//setAlignmentY(组件底部对齐);
JPanel labelPanel=newjpanel(newborderlayout());
labelPanel.setBackground(颜色:黑色);
labelPanel.setPreferredSize(新尺寸(20,i*30));
添加(labelPanel,BorderLayout.PAGE_END);
JLabel labelValue=新的JLabel(String.valueOf(30*i),JLabel.CENTER);
标签值。设置前景(颜色。白色);
添加(labelValue,BorderLayout.NORTH);
JLabel labelIndex=新的JLabel(字符串.valueOf(i),JLabel.CENTER);
标签索引设置前景(颜色白色);
添加(labelIndex,BorderLayout.SOUTH);
}
}
公共类面板扩展了JPanel{
公共事务委员会(){
挫折地面(颜色:白色);
setMaximumSize(新尺寸(31000));
setMinimumSize(新尺寸(3,0));
}
}
公共框架(字符串标题){
超级(标题);
JPanel mainPanel=新的JPanel();
//主面板。立根背景(颜色。红色);
主面板。立根背景(颜色。白色);
//mainPanel.setLayout(新的BoxLayout(mainPanel,BoxLayout.LINE_轴));
RelativeLayout rl=新的RelativeLayout(RelativeLayout.X_轴,5);
rl.setFill(真);
rl.setRoundingPolicy(相对长度相等);
rl.设置对齐(相对尾随);
主面板设置布局(rl);
浮动约束=新浮动(1);
对于(int i=1;i
或者这种方法更接近于你最初的发帖方式。它仍然使用垫片,并且随着框架高度的降低,黑色柱的高度将收缩:

import java.awt.*;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;

import javax.swing.BoxLayout;

public class Frame2 extends JFrame {
    private int numBox = 20;

    public class SubPanel extends JPanel {
        public SubPanel(int i) {
//            setMinimumSize(new Dimension(20, 20));
//            setMaximumSize(new Dimension(1000, i*30));
//            setBackground(Color.BLACK);
            setBackground(Color.RED);
//            setLayout(new BorderLayout());
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            add(Box.createVerticalGlue());
//            setAlignmentY(Component.BOTTOM_ALIGNMENT);

            JPanel labelPanel = new JPanel();
            labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.Y_AXIS));
            labelPanel.setBackground( Color.BLACK );
            labelPanel.setPreferredSize(new Dimension(50, i*30));
            labelPanel.setMaximumSize(new Dimension(1000, labelPanel.getPreferredSize().height));
            add(labelPanel, BorderLayout.CENTER);

            JLabel labelValue = new JLabel(String.valueOf(30 * i), JLabel.CENTER);
            labelValue.setForeground(Color.WHITE);
            labelValue.setAlignmentX(JLabel.CENTER_ALIGNMENT);
//            add(labelValue, BorderLayout.NORTH);
            labelPanel.add(labelValue);

            labelPanel.add(Box.createVerticalGlue());

            JLabel labelIndex = new JLabel(String.valueOf(i), JLabel.CENTER);
            labelIndex.setForeground(Color.WHITE);
            labelIndex.setAlignmentX(JLabel.CENTER_ALIGNMENT);
//            add(labelIndex, BorderLayout.SOUTH);
            labelPanel.add(labelIndex);
        }
    }

    public class SpacerPanel extends JPanel {
        public SpacerPanel() {
            setBackground(Color.WHITE);
            setMaximumSize(new Dimension(3, 10000));
            setMinimumSize(new Dimension(3, 0));
        }
    }

    public Frame2(String title) {
        super(title);

        JPanel mainPanel = new JPanel();
        mainPanel.setBackground(Color.RED);
//        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
        RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS, 0);
        rl.setFill( true );
        rl.setRoundingPolicy(RelativeLayout.EQUAL);
        rl.setAlignment(RelativeLayout.TRAILING);
        mainPanel.setLayout( rl );
        Float constraint = new Float(1);

        for (int i = 1; i < numBox + 1; i++) {
            mainPanel.add(new SpacerPanel());
//            mainPanel.add(new SubPanel(i));
            mainPanel.add(new SubPanel(i), constraint);
        }
        mainPanel.add(new SpacerPanel());

        add(mainPanel);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        new Frame2("Frame").setSize(1200, 700);
    }
}
import java.awt.*;
导入javax.swing.*;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.BoxLayout;
公共类Frame2扩展了JFrame{
私有int numBox=20;
公共类子面板扩展了JPanel{
公共子面板(int i){
//设置最小尺寸(新尺寸)