Обновление высоты компонента также меняет его ширину - PullRequest
0 голосов
/ 12 мая 2019

У меня есть графический интерфейс с одним основным JPanel и внутри него несколькими строками, каждая строка является другой JPanel.Каждая строка (типа JPanel) состоит из 4 меньших JPanel с, и каждая панель из этих 4 имеет компонент внутри.Конечный результат представляет собой интерфейс в виде сетки.

Главная панель имеет BoxLayout, а панели, являющиеся частями строки, имеют FlowLayout.

Когда я обновляю высоту некоторого компонента (из строки), используя некоторый слушатель, вся строка становитсявыше, который работает, как ожидалось.Но происходит то, что изменяется не только высота, но и ширина компонентов (внутри ряда).Я понимаю, что BoxLayout пытается расположить компоненты, используя maxSize и minSize, которые я могу установить на одно и то же значение, и это сработало, но затем, когда я изменяю размер окна, другие строки расширяются, а строки с такими же minSize и maxSize нет, и структура сетки становится испорченной.

Чего я хочу добиться, так это обновлять только высоту строки.И когда я изменяю размер окна, вся строка расширяется, а структура сетки остается сеткой.Вот краткое, самостоятельное, правильное (компилируемое), пример:

Main класс:

public class Main {

public static void main(String args[]) {

        SwingUtilities.invokeLater(() -> {

                new MainFrame(450,150);

            });

    }

}

MainFrame класс:

public class MainFrame extends JFrame{

    public MainFrame(int width, int height) {

        super("Title");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(width, height);
        setVisible(true);

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
        JScrollPane scrollPane = new JScrollPane(mainPanel);

        add(scrollPane);


        for(int i=0; i<50; i++) {

            JPanel panel1 = new JPanel();
            panel1.setLayout(new FlowLayout(FlowLayout.LEFT));
            panel1.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 1, Color.black));
            panel1.setPreferredSize(new Dimension(70,35));

            JPanel panel2 = new JPanel();
            panel2.setLayout(new FlowLayout(FlowLayout.LEFT));
            panel2.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
            panel2.setPreferredSize(new Dimension(70,35));

            JPanel panel3 = new JPanel();
            panel3.setLayout(new FlowLayout(FlowLayout.LEFT));
            panel3.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
            panel3.setPreferredSize(new Dimension(70,35));

            JTextArea area1 = new JTextArea("hello " + i);
            area1.setPreferredSize(new Dimension(70,25));
            panel1.add(area1);

            JTextArea area2 = new JTextArea("hello " + i);
            area2.setPreferredSize(new Dimension(70,25));
            panel2.add(area2);

            JTextArea area3 = new JTextArea("hello " + i);
            area3.setPreferredSize(new Dimension(70,25));
            panel3.add(area3);

            JPanel row = new JPanel();
            row.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.black));
            row.setLayout(new BoxLayout(row, BoxLayout.X_AXIS));

            row.add(panel1);
            row.add(panel2);
            row.add(panel3);

            JButton button = new JButton("Click me");
            JPanel buttonPanel = new JPanel();
            buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
            buttonPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
            buttonPanel.setPreferredSize(new Dimension(70,35));
            buttonPanel.add(button);

            button.addActionListener(event -> {

                panel1.setPreferredSize(new Dimension(panel1.getWidth(), panel1.getHeight() + 30));
                area1.setPreferredSize(new Dimension(area1.getWidth(), area1.getHeight() + 30));
                area1.updateUI();
            });

            row.add(buttonPanel);
            mainPanel.add(row);
        }

    }

}

ЕслиВы запускаете этот код и нажимаете кнопку, он обновляет не только высоту строки, но также ширину строки и сетку, которая больше не выравнивается.

1 Ответ

1 голос
/ 12 мая 2019

Вы устанавливаете «предпочтительный размер» на основе «размера» компонента.Они могут быть разными.

Ваш код должен выглядеть примерно так:

//panel1.setPreferredSize(new Dimension(panel1.getWidth(), panel1.getHeight() + 30));
Dimension d = panel1.getPreferredSize();
panel1.setPreferredSize(new Dimension(d.width, d.height + 30));

Кроме того, вы не должны использовать updateUI().Это метод, используемый внутри Swing при изменении LAF.

Вместо этого, когда вы хотите вызвать менеджер макета, вы вызываете revalidate () для компонента верхнего уровня, который был изменен:

//area1.updateUI();
panel1.revalidate();
...