Как установить минимальные размеры с GridBagLayout?
У меня есть простой графический интерфейс, используя GridBagLayout
с панелью кнопок в верхней части и настраиваемым компонентом с изменяемым размером, занимающим оставшееся пространство, как показано на следующем рисунке:
Пользовательский компонент (красный) имеет предпочтительный размер (400, 300) и минимальный размер (40, 30) и может быть изменен до любого размера больше этого. Однако я бы хотел, чтобы моя рамка соответствовала минимальному размеру панели кнопок и не позволяла изменять размеры рамки таким образом, чтобы ни одна из кнопок не отображалась полностью на экране. В настоящее время это не так, поскольку я могу изменить его размеры далеко за пределы этих границ, как показано здесь:
Мой текущий код выглядит следующим образом:
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 соблюдать минимальные размеры для меня. Если кто-нибудь знает, какой стандарт я переопределяю для достижения этого, мне любопытно:-)