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. Прежде всего, нам необходимо перейти от чернового рисунка к конкретному плану действий, то есть определить, где, как и какие мы будем использовать менеджеры расположения.