Сделайте так, чтобы ячейки BoxLayout сохраняли размер и только меняли размер клея в Java - PullRequest
1 голос
/ 25 марта 2019

Я пытаюсь создать панель настроек и хочу видеть, какие настройки принадлежат какому тексту. Поэтому я помещаю каждый 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));
        }
    }
}


EDIT

Я применил ответ Камикра, и это был результат enter image description here Как вы можете видеть, jspinners и jcheckboxes больше не находятся в очереди и выглядят немного грязно, но способ, которым он изменяет размеры, - это функциональность, которую я хочу. Вот обновленный 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));
        }
    }
}

1 Ответ

1 голос
/ 25 марта 2019

Я хочу, чтобы красные области были статичными

Используйте Box.createRigidArea(...) вместо "клея".

См. Раздел из учебника по Swing на Использование невидимых компонентов в качестве наполнителя для получения дополнительной информации.

Редактировать:

Перепутано с деталями используемых вами менеджеров компоновки.

Проблема в настройке панели.Вы используете горизонтальный 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());

Тебе действительно нужен клей?Выше приведено фиксированное расстояние между каждой панелью.

...