使BoxLayout的单元格保持大小,只在java中调整胶水大小

问题描述 投票:1回答:1

我正在尝试制作一个设置面板,我希望能够继续看到哪个设置属于哪个文本。因此,我将每个jlabel与jcheckbox或jspinner放在一个jpanel中,然后我将它们添加到列jpanels。我有4个列jpanels彼此相邻。在附加的图像中,您可以看到2种不同的宽度尺寸。我希望红色区域是静态的,蓝色区域要调整大小,因为这样你可以看到jlabel属于什么设置。 enter image description hereenter image description here

我在这里有一个SSCCE

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

public class SSCCE {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                e.printStackTrace();
            }
            JFrame jFrame = new JFrame();
            jFrame.setMinimumSize(new Dimension(580, 113));
            jFrame.add(new SettingsPanel());
            jFrame.pack();
            jFrame.setLocationRelativeTo(null);
            jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            jFrame.setVisible(true);
        });
    }

    public static class Setting extends JPanel {
        public String name;
        public JComponent component;

        public Setting(String name, JComponent component) {
            this.name = name;
            this.component = component;
            setLayout(new BorderLayout());
            add(new JLabel(name), BorderLayout.LINE_START);
            add(component, BorderLayout.LINE_END);
        }
    }

    private static class SettingsPanel extends JPanel {

        public SettingsPanel() {
            setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));

            JPanel subPanel = new JPanel(new GridLayout(0, 1));
            subPanel.add(new Setting("Amount of faces", new JSpinner()));
            subPanel.add(new Setting("Amount of vertices", new JSpinner()));
            subPanel.add(new Setting("Amount of textured faces", new JSpinner()));
            add(subPanel);

            add(Box.createHorizontalGlue());

            subPanel = new JPanel(new GridLayout(0, 1));
            subPanel.add(new Setting("Textures", new JCheckBox()));
            subPanel.add(new Setting("Priorities", new JCheckBox()));
            subPanel.add(new Setting("Alpha", new JCheckBox()));
            add(subPanel);

            add(Box.createHorizontalGlue());

            subPanel = new JPanel(new GridLayout(0, 1));
            subPanel.add(new Setting("TSkins", new JCheckBox()));
            subPanel.add(new Setting("VSkins", new JCheckBox()));
            subPanel.add(new Setting("X data", new JSpinner()));
            add(subPanel);

            add(Box.createHorizontalGlue());

            subPanel = new JPanel(new GridLayout(0, 1));
            subPanel.add(new Setting("Y data", new JSpinner()));
            subPanel.add(new Setting("Z data", new JSpinner()));
            subPanel.add(new Setting("Triangle data", new JSpinner()));
            add(subPanel);

            setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.BLACK));
        }
    }
}


编辑

我应用了Camickr的答案,这就是结果enter image description here正如你所看到的那样,jspinners和jcheckbox现在不再一致了,它看起来有点乱,但它调整大小的方式就是我想要的功能。这是更新的SSCCE与Camickr的答案

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

public class SSCCE {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                e.printStackTrace();
            }
            JFrame jFrame = new JFrame();
            jFrame.setMinimumSize(new Dimension(580, 113));
            jFrame.add(new SettingsPanel());
            jFrame.pack();
            jFrame.setLocationRelativeTo(null);
            jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            jFrame.setVisible(true);
        });
    }

    public static class Setting extends JPanel {
        public String name;
        public JComponent component;

        public Setting(String name, JComponent component) {
            this.name = name;
            this.component = component;
            setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
            add(new JLabel(name), BorderLayout.LINE_START);
            add(Box.createRigidArea(new Dimension(50, 0)));
            add(component, BorderLayout.LINE_END);
        }
    }

    private static class SettingsPanel extends JPanel {

        public SettingsPanel() {
            setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));

            JPanel subPanel = new JPanel(new GridLayout(0, 1));
            subPanel.add(new Setting("Amount of faces", new JSpinner()));
            subPanel.add(new Setting("Amount of vertices", new JSpinner()));
            subPanel.add(new Setting("Amount of textured faces", new JSpinner()));
            add(subPanel);

            add(Box.createHorizontalGlue());

            subPanel = new JPanel(new GridLayout(0, 1));
            subPanel.add(new Setting("Textures", new JCheckBox()));
            subPanel.add(new Setting("Priorities", new JCheckBox()));
            subPanel.add(new Setting("Alpha", new JCheckBox()));
            add(subPanel);

            add(Box.createHorizontalGlue());

            subPanel = new JPanel(new GridLayout(0, 1));
            subPanel.add(new Setting("TSkins", new JCheckBox()));
            subPanel.add(new Setting("VSkins", new JCheckBox()));
            subPanel.add(new Setting("X data", new JSpinner()));
            add(subPanel);

            add(Box.createHorizontalGlue());

            subPanel = new JPanel(new GridLayout(0, 1));
            subPanel.add(new Setting("Y data", new JSpinner()));
            subPanel.add(new Setting("Z data", new JSpinner()));
            subPanel.add(new Setting("Triangle data", new JSpinner()));
            add(subPanel);

            setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.BLACK));
        }
    }
}

java swing layout-manager boxlayout
1个回答
1
投票

我希望红色区域是静态的

使用Box.createRigidArea(...)而不是“胶水”。

有关更多信息,请参阅Using Invisible Components as Filler上Swing教程中的部分。

编辑:

搞清楚您正在使用的布局管理器的详细信息。

问题是SettingPanel。您正在使用水平BoxLayout。 BoxLayout尊重添加到其中的任何组件的最大大小。您正在添加没有最大大小的JPanel,因此每个面板的大小会增加,这会导致GridLayout也增加,从而导致BorderLayout组件中的间隙。

您希望防止面板尺寸增加。简单的更改来证明这个概念是在添加所有面板时添加以下内容:

subPanel.setMaximumSize( subPanel.getPreferredSize() );
add(subPanel);

更好的解决方案是扩展JPanel并覆盖getMaximumSize()方法以返回getPreferredSize(),以允许动态更改面板首选大小。

实施此建议后,我建议您删除:

jFrame.setMinimumSize(new Dimension(580, 113)); 

使用随机数永远不是一个好主意。让布局管理器确定大小。

当你这样做时,你会看到所有组件聚集在一起所以我建议你改变:

//setLayout(new BorderLayout());
setLayout(new BorderLayout(10, 0));

这将在每个标签/组件之间留出空间。

然后我会补充:

add(Box.createRigidArea(new Dimension(50, 0)));
//add(Box.createHorizontalGlue());

你真的需要胶水吗?以上将给出每个面板之间的固定间距。

© www.soinside.com 2019 - 2024. All rights reserved.