如何使用 BoxLayout Manager 设置特定面板的宽度

How to set width of specific panel with BoxLayout Manager

下面的代码将 3 个 JPanel 放在一个 JFrame 中。我希望蓝色面板的宽度为 300(假设封闭框架的宽度大于 300)。其他两个面板的宽度应该是余数。我该怎么做?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PanelTest extends JFrame { 
    private JPanel leftpanel;

    public PanelTest() {
        getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.X_AXIS));
        this.leftpanel = new JPanel() {         
            @Override
            public Dimension getMaximumSize() {
                return new Dimension(300, 9999);
            }
            
            @Override
            public Dimension getMinimumSize() {
                return new Dimension(300, 0);
            }   
        };
        this.leftpanel.setBackground(Color.blue);
        getContentPane().add(leftpanel);

        JPanel rightpanel = new JPanel();
        getContentPane().add(rightpanel);
        rightpanel.setLayout(new BoxLayout(rightpanel, BoxLayout.Y_AXIS));
        
        JPanel upperpanel = new JPanel();
        upperpanel.setBackground(Color.red);
        rightpanel.add(upperpanel);
        
        JPanel lowerpanel = new JPanel();
        lowerpanel.setBackground(Color.yellow);
        rightpanel.add(lowerpanel);
        pack();
        setVisible(true);
        setExtendedState(Frame.MAXIMIZED_BOTH);
    }
    
    public static void main(String[] args) {
        new PanelTest();
    }
}

我根据@camickr 关于使用 BorderLayout 的建议稍微更新了上面的代码。宽度现在是所需的。谢谢@camickr。

我仍然认为 BoxLayout 应该遵守最小和最大尺寸。考虑到这些,它应该将宽度设置为 500。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PanelTest extends JFrame { 
    public PanelTest() {
        getContentPane().setLayout(new BorderLayout());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel leftpanel = new JPanel();
        int width = 500;
        leftpanel.setPreferredSize(new Dimension(width, 1));
        leftpanel.setBackground(Color.blue);
        getContentPane().add(leftpanel, BorderLayout.LINE_START);

        JPanel rightpanel = new JPanel();
        getContentPane().add(rightpanel, BorderLayout.CENTER);
        rightpanel.setLayout(new BoxLayout(rightpanel, BoxLayout.Y_AXIS));
        
        JPanel upperpanel = new JPanel();
        upperpanel.setBackground(Color.red);
        rightpanel.add(upperpanel);
        
        JPanel lowerpanel = new JPanel();
        lowerpanel.setBackground(Color.yellow);
        rightpanel.add(lowerpanel);
        pack();
        setVisible(true);
        setExtendedState(Frame.MAXIMIZED_BOTH);
    }
    
    public static void main(String[] args) {
        new PanelTest();
    }
}

组件最重要的尺寸是首选尺寸。大多数布局管理器将首先使用此尺寸,然后可能使用 minimum/maximum 尺寸,具体取决于可用的 space。

如果您没有指定面板的首选大小,它将是 (10, 10),因为这是在未添加任何组件时使用 FlowLayout 的面板的默认大小。

此大小超出了您的 minimum/maximum 值的范围,因此 BoxLayout 会根据每个面板的最大大小按一定比例为每个组件分配 space。蓝色面板的大小为 300,另一个面板的大小为 Integer.MAX_VALUE,因此更多的 space 被分配给另一个面板。

一种解决方案是添加:

leftpanel.setPreferredSize(new Dimension(300, 1));

I want the blue colored panel to have a width of 300

我不会将内容窗格更改为使用 BoxLayout,而只是使用框架的默认 BorderLayout。那么你:

  1. 将蓝色面板添加到 BorderLayout.LINE_START
  2. 将包含 red/yellow 组件的面板添加到 BorderLayout.CENTER

BorderLayout 将遵守蓝色面板的宽度,并将剩余的 space 分配给中心的组件。

使用此方法无需覆盖蓝色面板的 minimum/maximum 值。

当然,您仍然需要设置蓝色面板的首选大小。