Как установить минимальные размеры с GridBagLayout?

У меня есть простой графический интерфейс, используя GridBagLayout с панелью кнопок в верхней части и настраиваемым компонентом с изменяемым размером, занимающим оставшееся пространство, как показано на следующем рисунке:

Графический интерфейс при запуске

Пользовательский компонент (красный) имеет предпочтительный размер (400, 300) и минимальный размер (40, 30) и может быть изменен до любого размера больше этого. Однако я бы хотел, чтобы моя рамка соответствовала минимальному размеру панели кнопок и не позволяла изменять размеры рамки таким образом, чтобы ни одна из кнопок не отображалась полностью на экране. В настоящее время это не так, поскольку я могу изменить его размеры далеко за пределы этих границ, как показано здесь:

GUI изменен смехотворно маленьким

Мой текущий код выглядит следующим образом:

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

public class Example {
    public static void main(String[] args) {
        // Setup JFrame and GridBagLayout.
        JFrame frame = new JFrame("Example");
        Container contentPane = frame.getContentPane();
        GridBagLayout layout = new GridBagLayout();
        contentPane.setLayout(layout);
        layout.rowWeights = new double[] {0.0, 1.0};
        layout.columnWeights = new double[] {1.0};
        GridBagConstraints cons = new GridBagConstraints();

        // Add button panel with a BoxLayout.
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        panel.add(new JButton("Button 1"));
        panel.add(new JButton("Button 2"));
        panel.add(new JButton("Button 3"));
        cons.anchor = GridBagConstraints.NORTHWEST;
        cons.gridx = 0;
        cons.gridy = 0;
        layout.setConstraints(panel, cons);
        contentPane.add(panel);

        // Add custom component, resizable.
        JComponent custom = new JComponent() {
            public Dimension getPreferredSize() {
                return new Dimension(400, 300);
            }

            public Dimension getMinimumSize() {
                return new Dimension(40, 30);
            }

            public void paintComponent(Graphics g) {
                g.setColor(Color.RED);
                g.fillRect(0, 0, getWidth(), getHeight());
            }
        };
        cons.gridx = 0;
        cons.gridy = 1;
        cons.fill = GridBagConstraints.BOTH;
        layout.setConstraints(custom, cons);
        contentPane.add(custom);

        // Pack and show frame.
        frame.pack();
        frame.setVisible(true);
    }
}

Я проверил это на Mac OS X 10.8 (Java 6) и Ubuntu 3.2.8 (Java 6) и заметил то же самое.

Как я могу предотвратить изменение размера рамки, чтобы покрыть любую из кнопок? В целом, как я могу получить GridBagLayout на самом деле уважать минимальные размеры моих компонентов? Когда я распечатываю минимальный размер моего кадра, я получаю (291, 81)Это именно то, что я хочу, но когда я изменяю размер рамки, это выходит за рамки этого.

Примечание: я посмотрел на этот связанный вопрос, но он не отвечает на мой вопрос.

3 ответа

Решение

Я не уверен почему, но если я использую...

frame.setMinimumSize(frame.getMinimumSize());

После того, как пользовательский интерфейс был создан (очевидно), он работает.

Я "думаю", это как-то связано с ((WindowPeer)peer).updateMinimumSize(); в setMinimumSize размер метода Window...

Если на вашем кадре установлен минимальный размер, вы можете добавить ComponentListener на раму и реализовать componentResized метод.

Как этот пример

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Test {
    public static void main(String[] args) 
    {
        final JFrame frame = new JFrame("My Frame");
        frame.setMinimumSize(new Dimension(200,200));
        frame.addComponentListener( new ComponentAdapter()
        {
            public void componentResized(ComponentEvent evt)
            {
                Dimension size = frame.getSize();
                Dimension min = frame.getMinimumSize();
                if (size.getWidth() < min.getWidth())
                {
                    frame.setSize((int)min.getWidth() ,(int) size.getHeight());
                }
                if (size.getHeight() < min.getHeight())
                {
                    frame.setSize((int)size.getWidth() ,(int) min.getHeight());
                }
            }
        });
        frame.setSize(300,300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

У меня часто бывают такие проблемы с настройками по умолчанию GridBagConstraints: я давно привык задавать их (weightx, gridwidth и т. Д.) Все явно. Это обычно заставляет GridBagLayout соблюдать минимальные размеры для меня. Если кто-нибудь знает, какой стандарт я переопределяю для достижения этого, мне любопытно:-)

Другие вопросы по тегам