【问题标题】:Resizing of multiple JPanels to fit window调整多个 JPanel 的大小以适应窗口
【发布时间】:2021-07-30 16:23:58
【问题描述】:

我是 Java Swing 工具包的新手,我创建了一系列 JPanel,其中 JLabel 组件对应于每个面板的索引和值。但是,当窗口太小而无法一次调整所有面板的大小时,我似乎无法正确调整面板的大小。导致所有面板右侧有一个额外的红色边距(请参阅。Window)。

有没有办法让子面板/间隔面板以不允许额外边距的方式调整大小?或者设置一个更好的挥杆布局来处理这种大小调整?

代码演示:

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);
    }
}

【问题讨论】:

    标签: java swing jpanel layout-manager boxlayout


    【解决方案1】:

    如果您有 40 个组件并且您将框架大小调整了几个像素,则 BoxLayout 在将这些像素分配给每个组件时遇到问题。

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

    RelativeLayout 还允许您指定每个组件之间的间隙,因此您无需添加 SpacerPanel。

    但是,您需要修改“子面板”的逻辑。标签的高度需要固定,以便它们可以涂成黑色。所以我创建了一个“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.*;
    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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 2014-07-04
      • 2020-06-07
      • 1970-01-01
      • 2016-11-12
      • 2020-09-24
      • 2010-12-12
      相关资源
      最近更新 更多