SpringLayout считается очень мощным. Я попытался реализовать то, что я думал, было довольно простым макетом, используя SpringLayout, и я потерпел неудачу.
Уменьшено до минимума, я хочу 4 кнопки J на моем кадре, рядом:
*=====================*
| +--+ +--+ +--+ +--+ |
| |b1| |b2| |b3| |b4| |
| +--+ +--+ +--+ +--+ |
*=====================*
Я хочу, чтобы все 4 имели одинаковый размер независимо от текста.
Я хочу, чтобы самые внешние (b1 и b4) имели постоянное горизонтальное расстояние 5 пикселей от границ контейнера и 5 пикселей границы к северу и югу от кнопок, которые имеют одинаковую высоту.
Я хочу, чтобы промежутки между кнопками также составляли 5 пикселей.
Пока все просто. У меня есть больше ограничений:
Когда рамка становится шире (пользователь / мышь), я хочу, чтобы промежутки между кнопками (b1 / b2, b2 / b3, b3 / b4) расширялись, а не кнопки.
Если рамка становится меньше, я хочу, чтобы промежутки между кнопками сократились до 1 или, возможно, до 0, прежде чем другие вещи уступят место.
Я ожидаю, что pack()
на рамке даст мне окно правильного размера для кнопок с пропусками по умолчанию в 5 пикселей и рамкой вокруг них в 5 пикселей.
Я написал следующий довольно простой код, и результаты ужасны. Зазоры не уменьшаются, и расширение происходит исключительно для самой правой кнопки (b4).
Теперь, когда у меня есть пользовательские кнопки, которые заботятся о равномерном определении размера, я мог бы довольно легко удовлетворить эти требования с помощью GridBagLayout и, возможно, еще проще с MigLayout. Это не тот ответ, который я ищу. В частности, мой вопрос:
Можно ли сделать так, чтобы этот макет работал правильно с помощью SpringLayout? Как?
В макете даже игнорируются мои кнопки getMaximumSize()
. Я делаю что-то не так или SpringLayout прослушивается?
Большое спасибо.
public class SpringLayoutTest extends JFrame {
public SpringLayoutTest() {
setLocation(100,100);
setSize(400, 300);
Container cp = getContentPane();
SpringLayout layout = new SpringLayout();
cp.setLayout(layout);
SiblingButton b1, b2, b3, b4;
cp.add(b1 = new SiblingButton("..."));
cp.add(b2 = new SiblingButton("iii"));
cp.add(b3 = new SiblingButton("xxx"));
cp.add(b4 = new SiblingButton("WWW"));
layout.putConstraint(NORTH, b1, 5, NORTH, cp);
layout.putConstraint(SOUTH, b1, Spring.minus(Spring.constant(5)), SOUTH, cp);
layout.putConstraint(NORTH, b2, 5, NORTH, cp);
layout.putConstraint(SOUTH, b2, Spring.minus(Spring.constant(5)), SOUTH, cp);
layout.putConstraint(NORTH, b3, 5, NORTH, cp);
layout.putConstraint(SOUTH, b3, Spring.minus(Spring.constant(5)), SOUTH, cp);
layout.putConstraint(NORTH, b4, 5, NORTH, cp);
layout.putConstraint(SOUTH, b4, Spring.minus(Spring.constant(5)), SOUTH, cp);
layout.putConstraint(WEST, b1, 5, WEST, cp);
layout.putConstraint(WEST, b2, Spring.constant(1, 5, Integer.MAX_VALUE), EAST, b1);
layout.putConstraint(WEST, b3, Spring.constant(1, 5, Integer.MAX_VALUE), EAST, b2);
layout.putConstraint(WEST, b4, Spring.constant(1, 5, Integer.MAX_VALUE), EAST, b3);
layout.putConstraint(EAST, b4, Spring.minus(Spring.constant(5)), EAST, cp);
layout.putConstraint(WEST, cp, Spring.minus(Spring.constant(5)), WEST, b1);
}
public static void main(String[] args) {
(new SpringLayoutTest()).setVisible(true);
}
SiblingButton - довольно бесхитростная реализация. Пожалуйста, не обращайте внимания на недостатки дизайна, это только для демонстрационных целей.
class SiblingButton extends JButton {
static ArrayList<SiblingButton> siblings = new ArrayList<SiblingButton>();
public SiblingButton(String text) {
super(text);
siblings.add(this);
}
public Dimension getMaximumSize() {
return getPreferredSize();
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getPreferredSize() {
Dimension mx = new Dimension(0, 0);
for (SiblingButton sb : siblings) {
mx = new Dimension(Math.max(mx.width, sb.originalPreferredSize().width),
Math.max(mx.height, sb.originalPreferredSize().height));
}
return mx;
}
Dimension originalPreferredSize() {
return super.getPreferredSize();
}
}
ОБНОВЛЕНИЕ / Заключение
Прошло уже 24 часа, и ответ был подавляющим. Одинокий ответ (спасибо, Camickr!) Даже не пытается коснуться SpringLayout. Я не думаю, что это плохо отражается не на SO-сообществе, а на полезности SpringLayout!
У меня сложилось впечатление, что SpringLayout - рыжий пасынок менеджеров по макету, полезный в некоторых отношениях, но настолько мало используемый, что никто не имеет опыта работы с ним, и никто не потрудился сообщить об ошибках Sun.
Для меня оказалось, что GroupLayout делает все, что мне нужно, и позволил мне выполнить то, что я хотел, именно с разумным количеством кода. Приветственное изменение от GridBagLayout, шаги, которые мне нужно было предпринять для достижения намеченного макета, были понятны мне с самого начала, и мне просто нужно было сесть и написать код.
Для всех, кого это волнует, вот характеристики GroupLayout, которые сделали его настолько полезным для меня:
- Компоновка выполняется более или менее отдельно для горизонтального и вертикального направлений. Много гибкости и более простой код;
- Можно вкладывать сетки без необходимости вводить контейнеры только для хранения макета;
- Возможно вставить пробелы с указанными ограничениями;
- Возможно сформировать произвольные группы компонентов с общими спецификациями размеров, т. Е. Все компоненты имеют те же размеры, что и самые большие в группе; и
- Можно изменить размер компонента (например, MaximumSize = предпочитаемый размер) без необходимости подкласса компонента.