Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Портянкин И. Swing

.pdf
Скачиваний:
143
Добавлен:
07.10.2020
Размер:
4.63 Mб
Скачать

Искусство расположения

195

Кнопки расположены именно так, как мы и ожидали, а вот с текстовым полем возникла некоторая проблема. Оно не растянуто на всю оставшуюся ширину окна, несмотря на то, что мы подходящим образом задали поля gridwidth и fill, и все равно осталось предпочтительного размера (длиной в 10 символов ввода, что мы задали в конструкторе для поля JTextField). Более того, если вы сделаете окно меньше, вы увидите, что при нехватке пространства поле сжимается до минимального размера «прыжком», не уменьшая свои размеры плавно. Пример показывает нам, что по умолчанию менеджер GridBagLayout ведет себя следующим образом:

компоненты имеют предпочтительный размер и не более

компоненты располагаются в центре контейнера

при нехватке места компонент уменьшается до минимального размера (у кнопок он совпадает с обычным, и «прыжка» нет, а у текстового поля зависит и от текста, в нем содержащегося, попробуйте набрать в нем текст и снова поменять размер окна).

Как же заставить GridBagLayout делать компоненты больше их предпочтительного размера? Для этого есть пара несколько загадочных полей, определяющих так называемый «вес» ячейки.

weightx, weighty — дробные числа, которые указывают менеджеру, сколько свободного места из контейнера следует отдавать ячейке, если таковое имеется. Числа эти нормированные — менеджер GridBagLayout собирает все значения из всех ячеек и вычисляет процент от максимального значения. Как правило, в качестве максимального значения используется единица — это 100% отдача всего свободного пространства ячейке. Числа от нуля до единицы будут означать проценты от свободного пространства, которые отдаются ячейке. Ну а по умолчанию значения полей weightx и weighty равны нулям, а это значит, что ячейка никогда не станет больше предпочтительного размера своего компонента и отступов. Интересным свойством полей weightx и weighty является и то, что если в контейнере, управляемом GridBagLayout, содержится хотя бы одна ячейка, в которой значения этих полей отличны от нуля, GridBagLayout займет все место контейнера. В противном случае будет занято лишь то место, которого достаточно для предпочтительных размеров компонентов, причем все компоненты будут располагаться по центру контейнера, что мы уже имели возможность наблюдать в нашем первом примере.

Теперь, кажется, понятно, что же мы упустили. Если мы хотим чтобы текстовое поле занимало весь остаток места по горизонтали, нам нужно установить поле weightx в 100%, в зависимости от того, какое число вы используете в качестве максимума. Если принять за 100% единицу, то дополнительная строчка кода будет выглядеть так:

textFieldConstraints.weightx = 1.0f;

А результат будет таков:

196

ГЛАВА 7

Изменяя размеры окна, вы сможете убедиться в том, что текстовое поле занимает всю его ширину, и размер его больше не «прыгает» и не зависит от количества набранного в нем текста.

Идея GridBagLayout не так и сложна, и большинство расположений довольно легко поддаются ему. Однако основной проблемой является объект для описания ячеек GridBagConstraints. Названия его полей не всегда ясны (к примеру, gridwidth и weight довольно двусмысленны), а значения для них подстегивают к добавлению к коду цифр (уже упомянутые поля, плюс поле insets), и мы сталкиваемся с проблемой «волшебных чисел», когда цифры в коде не несут очевидной смысловой нагрузки. Огромное количество объектов GridBagConstraints и кода для их настройки, щедро перемешанные с инициализацией компонентов и деловой логикой программы, становятся настоящей головной болью. Поэтому, если есть возможность, всегда стоит отказываться от чистого, «без примесей» расположения GridBagLayout, в пользу описанного нами выше подхода из нескольких вложенных панелей с блочным расположением BoxLayout. Кода будет не больше, а его смысл и простота его чтения намного лучше.

Впрочем, менеджер GridBagLayout является стандартной частью JDK и навсегда там останется. Если вы пишете интерфейс не с нуля и вынуждены поддерживать существующий код с применением GridBagLayout, или не можете переключиться на подход с сложенными воедино «полосками», по крайней мере стоит упростить задачу и сделать чтение и поддержку кода проще, все же не отказываясь от GridBagLayout.

Основная проблема состоит в том, что уровень объекта GridBagConstraints слишком низок, и вместо очевидных операций (растянуть компонент, добавить промежуток между компонентами, выровнять его по левому краю), мы манипулируем полями, и эффект от этих действий не «прочитать» напрямую. Но можно создать вспомогательный объект для работы с GridBagConstraints, и вызывая его методы, намного улучшить и упростить нашу работу с менеджером GridBagLayout. Давайте попробуем:

//com/porty/swing/GridBagHelper.java

//Вспомогательный класс, позволяющий писать

//качественный код для расположения GridBagLayout package com.porty.swing;

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

public class GridBagHelper {

//координаты текущей ячейки private int gridx, gridy;

//настраиваемый объект GridBagConstraints private GridBagConstraints constraints;

//возвращает настроенный объект GridBagConstraints public GridBagConstraints get() {

return constraints;

}

//двигается на следующую ячейку

public GridBagHelper nextCell() { constraints = new GridBagConstraints();

Искусство расположения

197

constraints.gridx = gridx++; constraints.gridy = gridy;

// для удобства возвращаем себя return this;

}

//двигается на следующий ряд public GridBagHelper nextRow() {

gridy++; gridx = 0;

constraints.gridx = 0; constraints.gridy = gridy; return this;

}

//раздвигает ячейку до конца строки public GridBagHelper span() {

constraints.gridwidth = GridBagConstraints.REMAINDER; return this;

}

//заполняет ячейку по горизонтали

public GridBagHelper fillHorizontally() { constraints.fill = GridBagConstraints.HORIZONTAL; return this;

}

// вставляет распорку справа

public GridBagHelper gap(int size) { constraints.insets.right = size; return this;

}

… остальные вспомогательные методы

}

Класс GridBagHelper весьма прост. Он работает с объектом GridBagConstraints, настраивая его поля и скрывая некоторые не очень очевидные цифры и манипуляции с полями, вместо этого предоставляя нам весьма понятные методы, к примеру, nextRow() переходит на первую ячейку следующей строки таблицы, а gap() вставляет распорку справа от компонента. Для работы с этим объектом нужно создать его экземпляр, для каждой новой ячейки вызывать метод nextCell() (именно там создается новый объект GridBagConstraints), а в конце, когда настройка компонента проведена, получить результат методом get(). Для того чтобы вызывать методы было удобнее, каждый из них возвращает ссылку на объект GridBagHelper, поэтому методы можно вызывать «в ряд».

В качестве маленького примера можно привести надпись и текстовое поле, с распоркой в 5 пикселей между ними:

GridBagHelper helper = new GridBagHelper(); helper.nextCell().gap(5);

frame.add(new JLabel("Имя:"), helper.get());

198

ГЛАВА 7

helper.nextCell().span(); frame.add(new JTextField(20));

При запуске мы получим такой результат:

Мы получим и распорку, не работая со всеми четырьмя размерностями объекта Insets, и скажем полю занять все оставшиеся ячейки более понятным методом span(), и прозрачный способ перехода по ячейкам. В полной версии класса GridBagHelper, которую вы можете найти в исходных текстах программ книги, есть и много других полезных методов с простыми названиями. Такой код не только во много раз быстрее писать, но и легче читать и обновлять. В будущем, если вы решите применить на практике GridBagLayout, класс GridBagHelper или его эквиваленты будут весьма кстати, а применять напрямую запутанный класс GridBagConstraints вряд ли можно рекомендовать. Чуть позже в этой главе, когда мы разработаем диалоговое окно для входа в систему, мы еще раз применим новый класс.

Быстрый язык MigLayout

Сама идея расположения большинства объектов интерфейса по сетке, придавая им разное выравнивание, размеры, и, возможно, количество ячеек сетки, занимаемое ими, позволяет быстро набросать интерфейс, даже не имея никаких визуальных инструментов. Некогда, до достаточного развития таблиц стилей CSS, именно так разрабатывалось расположение содержимого многих Web-страниц.

Идея эта была реализована в Java с помощью GridBagLayout, однако способ указания всех атрибутов расположения компонентов в сетке неудачна, количество объектов огромно, и код уже через пять минут напоминает неудавшееся спагетти. Поддерживать подобный код крайне тяжело.

Однако сама идея неплоха, остается лишь более быстрым и удобным языком указывать менеджеру расположения, как и где должны располагаться компоненты в сетке. Мы уже создали вспомогательный класс, предлагающий удобными методами руководить действиями GridBagLayout. Также одним из удачных примеров реализации такого менеджера является бесплатно распространяемый менеджер MigLayout.

По сути, вспоминая наше рассмотрение табличного менеджера GridBagLayout и его основных концепций, можно сказать, что в целом мы представляем себе, как работает MigLayout. Другим способом осуществляется лишь описание ячеек таблицы — в виде строчек очень компактного, насыщенного смыслом текста, что без сомнения ускоряет процесс создания интерфейса. Вы добавляете компоненты примерно таким методом — add(компонент, “описание ячейки”). Более того, MigLayout обладает несравненно более широким набором функций, в сравнении со стандартными менеджерами Java. Дальнейшее знакомство мы проведем с помощью примера, тем более что язык MigLayout достаточно легко понять.

//MigLayoutStart.java

//Знакомство с MigLayout

Искусство расположения

199

import net.miginfocom.swing.MigLayout; import javax.swing.*;

public class MigLayoutStart extends JFrame { public MigLayoutStart() {

super("MigLayoutStart");

//выход при закрытии окна setDefaultCloseOperation(EXIT_ON_CLOSE);

//устанавливаем менеджер расположения setLayout(new MigLayout());

//добавляем компоненты с описанием ячеек add(new JLabel("Имя:"), "gap, sg 1"); add(new JTextField(10), "wrap");

add(new JLabel("Фамилия:"), "gap, sg 1"); add(new JTextField(10), "wrap");

//выведем окно на экран

pack();

setVisible(true);

}

public static void main(String[] args) { SwingUtilities.invokeLater(

new Runnable() {

public void run() { new MigLayoutStart(); } });

}

}

Мы создаем окно и устанавливаем для него расположение MigLayout. Далее в окно добавляется две надписи JLabel, описывающие текстовые поля для ввода данных, и сами текстовые поля — типичный пример простого интерфейса. Для гармонии надписи обычно делают одинаковых размеров. Обратите внимание, как описываются ячейки при добавлении компонентов: в виде простой строки, команды разделяются запятыми, параметры команд следуют через пробел. Запустив пример, мы без особых усилий получим желаемый результат. Конечно же, для запуска вам понадобится скачать библиотеки MigLayout и добавить их в свой путь CLASSPATH, их легко найти на официальном сайте продукта в Интернете.

Мало того что мы в мановение ока сделали размеры надписей одинаковыми, выровняли надписи и текстовые поля, так еще в качестве приятного сюрприза MigLayout на

200

ГЛАВА 7

основе каких-то своих внутренних алгоритмов задал подходящие размеры между компонентами, как по горизонтали, так и по вертикали. Ни один стандартный менеджер расположения таким простым способом этого сделать не может. Откуда менеджер MigLayout берет размеры между компонентами, мы вскоре узнаем, а пока составим краткую таблицу наиболее полезных команд при описании ячеек интерфейса:

Таблица 7.1. Основные команды менеджера MigLayout

Команда и параметры

Описание

gap [размеры]

Указывает, что после компонента необходимо вставить пустое простран-

 

ство указанного размера. Не указывая размер, мы предлагаем располо-

 

жению MigLayout самому определить этот размер наилучшим образом

 

(вскоре мы увидим, откуда он берется).

wrap

Указание перейти после данного компонента на следующую строку сет-

 

ки. По умолчанию вставляется пустой промежуток между строками.

sg [имя]

Указывает что компонент принадлежит группе компонентов с одина-

 

ковыми размерами, равными размеру самого большого компонента.

 

У группы может быть свое имя.

span [количество ячеек]

Указывает, что компонент должен занять больше чем одну ячейку

 

сетки

skip [количество ячеек]

Инструкцияпропуститьуказанноеколичествоячеек(оставитьихпустыми)

 

и поместить компонент в следующую за ними ячейку

grow[x|y] [вес]

Помечает, что компонент при наличии свободного места в контейнере

 

желает «расти» в размерах, по оси X или Y, или по обоим. У «желания

 

роста» есть весовой коэффициент, который работает аналогично тому,

 

как действует поле weight в стандартном менеджере GridBagLayout. Ин-

 

тересно, что по умолчанию контейнер с менеджером MigLayout не умеет

 

«расти», для этого необходимо задать специальный флаг в конструкторе

 

MigLayout.

Посмотрев на таблицу и сравнив ее с нашим примером, мы увидим, что создали сетку из двух столбцов и двух строк, а надписи находятся в группе с одинаковым размером. Расстояния между строками и столбцами были заданы автоматически, хотя всегда есть возможность задать их вручную, и не только в пикселах, но даже и в миллиметрах и других единицах.

Как мы видим, MigLayout может быть очень быстрым и невероятно продуктивным. Он обладаетогромнымколичествомкоманд,которыедостаточноочевидны,еслипринимать во внимание то, что расположение идет по гибкой сетке. Найдя сайт MigLayout в Интернете, вы сможете найти там удобную краткую сводку всех его команд и с успехом применить их на практике. Конечно, бывают случаи, когда расположение по сетке накладывает ограничения, но в таком случае всегда можно применить технику вложенных расположений.

Общий подход

Теперь, когда мы узнали, какие менеджеры расположения предоставляет язык Java и его библиотеки, и как ими пользоваться, осталось выработать общий подход, который позволил бы «расколоть» любой интерфейс, с блеском проведя его разработку.

Для этого рассмотрим пример, достаточно объемный, чтобы можно было пройти все этапы создания интерфейса полностью. Попытаемся создать диалоговое окно входа в систему — довольно часто используемый элемент графического интерфейса. Обычно в нем присутствует два текстовых поля для ввода имени пользователя и его пароля,

Искусство расположения

201

а также пара кнопок, чтобы пользователь мог указать, когда он будет готов к продолжению работы.

Прежде всего, необходимо набросать примерный внешний вид будущего интерфейса. Конечно, можно обойтись и без этого, но тогда легко увлечься и в процессе разработки обнаружить, что вы полностью потеряли контроль над тем, что делаете, особенно когда дело касается сложных вариантов расположения. По поводу способа дизайна пользовательских интерфейсов сломано немало копий, защищены докторские диссертации и написаны тысячи статей, но область эта по прежнему сродни искусству. На сайте книги ipsoftware.ru вы найдете ссылки на некоторые интересные статьи. Существуют даже отдельные компании, занимающиеся так называемым «usability» (с трудом переводимое слово, что-то вроде «удобство в использовании»), означающим создание интерфейса, максимально удобного и понятного пользователю. Компании дизайнеров предлагают различные варианты внешнего вида интерфейсов. Одна часто программисту самому приходится проектировать интерфейс.

Если вы точно не уверены, что вам нужно, хотя уже знаете, из каких элементов будет состоять диалоговое окно, то можете руководствоваться базовыми принципами разработки пользовательских интерфейсов, а именно их простотой, стандартными компонентами, к которыми привыкли все пользователи, и очевидностью действий, которые интерфейс позволяет (можно назвать все это принципом «не изумлять пользователя»). Идеально также опросить будущих пользователей приложения, если это возможно на этапе проектирования. Это не совет на все случаи жизни, но очень часто самый простенький интерфейс оказывается на удивление симпатичным и удобным в работе. Попытайтесь, встав на место пользователя, воспроизвести его цепочку размышлений (это, в частности, поможет выяснить, в каком порядке компоненты должны передавать друг другу фокус ввода), например, при входе в систему так и «тянет» ввести свое имя, затем вспомнить пароль, а после этого поискать глазами что-то для продолжения работы. Руководствуясь такими нехитрыми размышлениями, получаем набросок диалогового окна, представленный на рис. 7.4.

Вход в систему

Имя:

Пароль:

ОК Отмена

Рис. 7.4. Набросок диалогового окна для входа в систему

При создании пользовательского интерфейса можно пойти двумя путями. Можно самому быть «законодателем мод» в своем приложении, определяя, как и что будет в нем выглядеть и функционировать. Такой подход особенно хорош, если вы специально разработаете для своих приложений собственный внешний вид, однако это и долго, и дорого. А можно принять стандарт создателя Java — фирмы Sun (теперь уже Oracle), предложившей ряд рекомендаций относительно внешнего вида приложений. Команда Sun провела приличную исследовательскую работу, привлекла художников и дизайнеров, и нужно признать, что приложение, созданное в полном соответствии с этими рекомендациями, выглядит действительно гармонично. К тому же вы можете бесплатно за-

202

ГЛАВА 7

грузить достаточно обширный набор стандартной графики для меню, кнопок и панелей инструментов, что значительно повысит привлекательность вашего приложения, не увеличивая его стоимости и сроков разработки. Если вы решились, рассмотрим основные положения этих рекомендаций.

Рекомендации от Sun

Рекомендации по созданию интерфейса Java-приложений (Java Look & Feel Design Guidelines) — это довольно объемный труд, выпущенный компанией Sun/Oracle специально для разработчиков Java-приложений. Там содержится действительно много полезной информации, необходимой при создании промышленных приложений. Рекомендации от Sun, в том числе, касаются способов расположения компонентов на форме, и особенно интересной, на взгляд автора, является информация о пространстве между компонентами. Следуя этим рекомендациям, можно в результате получить действительно привлекательный внешний вид. Однако учтите, что все рекомендации касаются только внешнего вида Metal или производного от него, используемого в Swing по умолчанию, а в случае другого внешнего вида стоит обратить внимание на рекомендации его производителя.

Рисуя набросок будущего диалогового окна для нашего приложения, мы, сознательно или подсознательно, оставили некоторое пространство между компонентами и отступили от границ окна. Это неудивительно — такой подход диктуется логикой, и нам кажется вполне естественным более акцентировано отделять логически малосвязанные компоненты, чем тесно связанные. Другой вопрос — насколько именно нужно раздвинуть эти компоненты, чтобы получить наилучший результат? Можно проводить долгие эксперименты или нанять дизайнеров. Можно этого не и не делать. Почему? Это уже проделано командой Sun. Никто не утверждает, что это — идеальный вариант и ничего лучше уже придумать невозможно. Но, тем не менее, он дает более чем приемлемый результат. Итак.

Расстояние между логически тесно связанными компонентами. Чаще всего такими компонентами являются кнопки JButton, флажки JCheckBox и переключатели JRadioButton в группах, отвечающие за выбор пользователем одного из возможных вариантов (вряд ли вообще можно придумать более тесно связанные компоненты). Их следует отделять друг от друга на 5 пикселов (в некоторых случаях рекомендуется 6 пикселов, однако это уже чрезмерные тонкости, а на современных дисплеях

свысоким разрешением увидеть разницу в один пиксел можно, наверное, только

слупой). Наглядный пример в нашем случае — пара кнопок OK и Отмена.

Расстояние между группами компонентов. Здесь имеются в виду те же самые группы из флажков и переключателей. Обычно, если они присутствуют в интерфейсе, то не поодиночке (каждая группа отвечает за выбор определенного условия). Так вот, расстояние между ними должно быть 12 пикселов (здесь также есть вариант — 11 пикселов, связанный с неоднозначным восприятием человеком белых теней компонентов, но к нему вполне применим комментарий из предыдущего пункта). В нашем интерфейсе таких групп нет, но откройте любое диалоговое окно, предназначенное для настройки программы, и вы их увидите.

Пространство между границами окна и другими компонентами. Задавая такое расстояние, мы акцентируем внимание на интерфейсе и отделяем его от границ окна, служащих для других целей. Те же соображения относятся и к панелям с рамками, набор которых в Swing просто потрясает воображение. Такие панели помогают четко структурировать интерфейс, хотя ни в коем случае не следует ими злоупотреблять. От границ этих панелей компоненты также нужно отделять. Для таких ситуаций используйте значение в 12 пикселов.

Искусство расположения

203

Расстояние между «обычными» компонентами. Под обычными компонентами подразумеваются те, которые, как правило, не встретишь в логически связанных группах. К ним относятся текстовые поля JTextField, надписи к компонентам JLabel, индикаторы процесса JProgressBar, ползунки JSlider и т. д. И здесь следует использовать уже встретившееся нам значение в 12 пикселов.

Пространство между компонентами, выполняющими абсолютно разные функции. Такие компоненты нечасто можно встретить в интерфейсе. Но нам повезло — в нашем диалоговом окне они есть. Текстовые поля служат для сбора информации от пользователя, а кнопки — для получения от него команд. Их целесообразно разделить более явно, и для этого используется немаленькое расстояние в 17 пикселов. Обычно это — единственный вариант применения такого расстояния (отделение кнопок управления от «собирательной» части или информационной части интерфейса).

Внешний вид кнопок JButton. Вообще-то это уже совершенно особый случай, и о нем следовало бы упомянуть в главе, посвященной элементам управления вообще и кнопкам в частности, но раз в нашем диалоговом окне есть кнопки, скажем об этом сейчас. Необходимо отделять смысловое наполнение кнопок (обычно текст, иногда значки) от их границ слева и справа на четкое расстояние в те самые 12 пикселов. Когда вы просто создаете кнопку, в соответствие с внешним видом Metal расстояния получаются чуть большими, порядка 14 пикселов. Видимо, такое расстояние необходимо, чтобы выдержать общий «стиль» в 12 пикселов.

Это наиболее важные положения рекомендаций Sun, относящиеся к расположению компонентов (для интерфейса, который мы сейчас создаем, этого вполне достаточно). Но этими положениями рекомендации Sun не исчерпываются, в них вы можете найти множество полезной информации, касающейся того, как следует использовать прописные и строчные буквы в надписях компонентов, какой стиль письма подходит для пользовательских интерфейсов, какие должны быть значки для приложений с внешним видом Metal, как выглядит набор стандартных диалоговых окон и т. п. Также неплохо освещена сама философия пользовательского интерфейса. К сожалению, это не является темой данной книги (хотя кое-что их этих рекомендаций мы используем в главах, посвященных компонентам Swing, а за остальным можете обращаться на сайт java.sun. com). Аналогичные рекомендации вы сможете найти и для других известных внешних видов: Windows, Apple и остальных, если захотите создать свое Swing-приложение в похожем стиле.

Вернемся к нашему диалоговому окну. Как видно, выдержать стиль Java-приложения не так уж и трудно, по крайней мере, в отношении расстояния между компонентами и их расположения. Основным расстоянием везде служат 12 пикселов, ну а в особых случаях применяются 5 и 17 пикселов.

Рекомендации по расположению и класс LayoutStyle

Как мы уже сказали, расположение компонентов и сам пользовательский интерфейс часто создаются программистами, и времени на визуальный дизайн нет, а зачастую нет и навыков такого дизайна. Рекомендации, подобные тем, что мы только что рассмотрели для внешнего вида Metal, являются настоящим спасением. Чтобы еще более упростить процесс следования подобным рекомендациям при создании интерфейса, в JDK версии 1.6 в пакете javax.swing появился класс под названием LayoutStyle, который любезно сообщает, какие расстояния между компонентами следует использовать при создании интерфейса. Применяя его, вы можете отказаться от следования конкретным цифрам и таким образом сделать стиль интерфейса совершенно универсальным, не зависящим даже от его внешнего вида.

204

ГЛАВА 7

Класс LayoutStyle является некоторого рода «одиночкой» — всегда имеется только один его экземпляр, доступный всем желающим через статический метод getInstance(). Экземпляр можно поменять на свой собственный (обычно это делает новый внешний вид приложения, когда вы его устанавливаете). А теперь с помощью простейшего примера проверим, какие расстояния нам предлагает LayoutStyle для внешнего вида по умолчанию (Metal):

//LayoutStyleTest.java

//Автоматическое определение стиля интерфейса import javax.swing.*;

import static javax.swing.LayoutStyle.ComponentPlacement.*;

public class LayoutStyleTest {

public static void main(String[] args) { SwingUtilities.invokeLater(

new Runnable() { public void run() {

// компоненты

JPanel panel = new JPanel(); JTextField text = new JTextField(); JLabel label = new JLabel("Тест"); // отступ от границы контейнера

LayoutStyle style = LayoutStyle.getInstance(); System.out.println("" + style.getContainerGap(

text, SwingConstants.WEST, panel));

// расстояние между связанными компонентами

System.out.println("" + style.getPreferredGap(

label, text, RELATED, SwingConstants.EAST, panel));

} });

}

}

Запустив пример, мы получим две цифры 12, что совпадает с рекомендациями, которые мы недавно рассмотрели для внешнего вида Metal. Кстати, вспоминая автоматическое разделение компонентов менеджером MigLayout, становится ясно, что расстояния он берет именно из класса LayoutStyle. Таким же образом может работать и групповое расположение GroupLayout, что делает его очень удобным при визуальном расположении компонентов в редакторе NetBeans.

В итоге, при создании интерфейса вполне можно рекомендовать пользоваться услугами класса, если конечно у ваших дизайнеров нет особого мнения. Подобное решение позволяет приложению быть полностью готовым к «выходу в свет» в любом внешнем виде.

Реализация в коде: вложенные блоки

Попробуем реализовать наш набросок с помощью блоков BoxLayout. Прежде всего, нам необходимо перейти от чернового рисунка к конкретному плану действий, то есть определить, где, как и какие мы будем использовать менеджеры расположения.