Библиотека Swing появилась примерно 15 лет назад и все эти 15 лет КАЖДЫЙ кто начинает программировать на Java задаёт один и тот же вопрос:
— Почему я не могу просто добавить кнопки с полями на форму без изучения всех этих LayoutManager'ов?
В стандарной JRE содержится больше десятка классов для компоновки элементов (FlowLayout, GroupLayout и т.п.), постоянно появляются новые компоновщики типа MigLayout но ситуация не улучшается.
Рассмотрим варианты создания форм типа этой:
На скриншоте видно что некоторые поля меняют ширину в зависимости от размера формы, кнопки привязаны к границам окна т.е. компоновка не является тривиальным выставлением константных размеров/положения компонентов.
Пример формы:
Рассмотрим код сгенерированный рисовалкой:
Код ужасен. Абсолютно невозможно разобраться что где находится и как что-то поменять руками. И это всего лишь несколько полей с одной кнопкой. А если нужно динамически подстраивать расположение/размер компонентов под размеры формы то количество кода увеличится в разы.
Можно просто отключить компоновщик контейнера методом setLayout(null) и выставить размеры контролов вручную, через setSize и setLocation примерно как в старом добром Visual Basic'е.
Способ топорный но иногда это проще чем тратить время на полуавтоматическую компоновку.
Я опубликовал библиотеку для простого и наглядного рисования форм руками. Исходный код и пример использования можно скачать на https://code.google.com/p/layout-less/
Проект использует binding из библиотеки описанной в статье на http://habrahabr.ru/blogs/java/127076/
Код формы из первого скриншота выглядит так:
— описание компоновки полей вполне читабельно.
Дополнительно:
— размеры и положение полей могут быть динамически привязаны к границам контейнера или другим переменным
— компоненты могут накладываться друг на друга (см. картинку с ключами)
— Почему я не могу просто добавить кнопки с полями на форму без изучения всех этих LayoutManager'ов?
В стандарной JRE содержится больше десятка классов для компоновки элементов (FlowLayout, GroupLayout и т.п.), постоянно появляются новые компоновщики типа MigLayout но ситуация не улучшается.
Рассмотрим варианты создания форм типа этой:
На скриншоте видно что некоторые поля меняют ширину в зависимости от размера формы, кнопки привязаны к границам окна т.е. компоновка не является тривиальным выставлением константных размеров/положения компонентов.
Использование визуального редактора типа Netbeans Matisse
Пример формы:
Рассмотрим код сгенерированный рисовалкой:
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 126, Short.MAX_VALUE)
.addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jButton1)
.addComponent(jPasswordField1)
.addComponent(jTextField2)
.addComponent(jTextField1))
.addContainerGap(149, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel2))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jPasswordField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel3))
.addGap(18, 18, 18)
.addComponent(jButton1)
.addContainerGap(166, Short.MAX_VALUE))
);
pack();
Код ужасен. Абсолютно невозможно разобраться что где находится и как что-то поменять руками. И это всего лишь несколько полей с одной кнопкой. А если нужно динамически подстраивать расположение/размер компонентов под размеры формы то количество кода увеличится в разы.
Вариант без layout'ов
Можно просто отключить компоновщик контейнера методом setLayout(null) и выставить размеры контролов вручную, через setSize и setLocation примерно как в старом добром Visual Basic'е.
Способ топорный но иногда это проще чем тратить время на полуавтоматическую компоновку.
Мой собственный вариант
Я опубликовал библиотеку для простого и наглядного рисования форм руками. Исходный код и пример использования можно скачать на https://code.google.com/p/layout-less/
Проект использует binding из библиотеки описанной в статье на http://habrahabr.ru/blogs/java/127076/
Код формы из первого скриншота выглядит так:
layoutless = new Layoutless();
int labelsWidth=150;
layoutless
.item(new ComponentBox()
.component(jLabel1)
.width(labelsWidth)
.height(22)
.x(0)
.y(8+25*0)
)
.item(new ComponentBox()
.component(jTextField1)
.width(layoutless.width().minus(labelsWidth).minus(16).minus(50))
.height(22)
.x(labelsWidth+8)
.y(8+25*0)
)
.item(new ComponentBox()
.component(jButton2)
.width(49)
.height(21)
.x(layoutless.width().minus(58))
.y(8+25*0)
)
.item(new ComponentBox()
.component(jLabel2)
.width(labelsWidth)
.height(22)
.x(0)
.y(8+25*1)
)
.item(new ComponentBox()
.component(jTextField2)
.width(layoutless.width().minus(labelsWidth).minus(16))
.height(22)
.x(labelsWidth+8)
.y(8+25*1)
)
.item(new ComponentBox()
.component(jLabel3)
.width(labelsWidth)
.height(22)
.x(0)
.y(8+25*2)
)
.item(new ComponentBox()
.component(jPasswordField1)
.width(layoutless.width().minus(labelsWidth).minus(16))
.height(22)
.x(labelsWidth+8)
.y(8+25*2)
)
.item(new ComponentBox()
.component(jButton1)
.width(90)
.height(27)
.x(labelsWidth+8)
.y(layoutless.height().minus(40))
)
.item(new ComponentBox()
.component(iconLabel)
.width(128)
.height(128)
.x(0)
.y(layoutless.height().minus(140))
)
;
this.add(layoutless, BorderLayout.CENTER);
— описание компоновки полей вполне читабельно.
Дополнительно:
— размеры и положение полей могут быть динамически привязаны к границам контейнера или другим переменным
— компоненты могут накладываться друг на друга (см. картинку с ключами)