Материал: Портянкин И. Swing

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

170

ГЛАВА 7

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

public class FlowLayoutSample extends JFrame { public FlowLayoutSample() {

super("FlowLayoutSample"); setSize(400, 200);

setDefaultCloseOperation( EXIT_ON_CLOSE );

//устанавливаем последовательное расположение с

//выравниванием компонентов по центру setLayout( new FlowLayout( FlowLayout.CENTER ));

//добавляем компоненты

add( new JButton("Один")); add( new JButton("Два")); add( new JButton("Три")); // выводим окно на экран setVisible(true);

}

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

new Runnable() {

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

}

}

Конструктор класса FlowLayout имеет три перегруженные версии: без параметров, с параметрами выравнивания компонентов, с параметрами выравнивания компонентов и расстояний между ними. В примере использована вторая версия, устанавливающая последовательное расположение по центру.

Запустите программу с примером, и вы увидите, как работает менеджер последовательного расположения.

Если места для всех компонентов достаточно, они размещаются горизонтально в одну строку. Уменьшите горизонтальный размер окна — как только места в одной строке всем компонентам станет мало, лишние перейдут на строку ниже (расстояние между строками и компонентами можно указать в конструкторе). Теперь уменьшайте размер

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

171

окна по вертикали — вы увидите, что компоненты, не помещающиеся в окно, просто исчезают из поля зрения! Это не какой-то недостаток последовательного расположения, как может показаться на первый взгляд, а только следствие его главного свойства: при последовательном расположении всегда сохраняется предпочтительный размер компонентов. Менеджер FlowLayout неизменно работает по такому правилу, и если места в контейнере становится мало, то он просто прячет «лишние» компоненты, а не уменьшает их размеры. Вторым по важности свойством менеджера расположения FlowLayout следует признать то, что при вызове метода preferredLayoutSize() или minimumLayoutSize(), позволяющего узнать предпочтительный и минимальный размеры контейнера, в котором этот менеджер действует, метод возвращает размер, соответствующей ситуации расположения всех компонентов в одну строку. Это особенно важно при совмещении последовательного расположения с другими вариантами расположения. Вследствие этого свойства менеджеры других вариантов расположения будут стараться найти достаточно места для размещения компонентов в одну строку. Вскоре мы увидим совмещение в действии.

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

Табличное расположение GridLayout

Как нетрудно догадаться по названию, менеджер расположения GridLayout разделяет контейнер на таблицу с ячейками одинакового размера Количество строк и столбцов можно указать в конструкторе, причем существует возможность задать произвольное количество либо строк, либо столбцов (но не одновременно). Все ячейки имеют одинаковый размер, маленькие компоненты растягиваются по всем направлениям, большие компоненты сжимаются. Табличное расположение идеально подходит для ситуаций, где нужно разбить контейнер на несколько одинаковых частей с примерно одинаковым по размеру содержимым. В качестве первого примера рассмотрим окно с кнопками различных размеров:

//GridLayoutSample.java

//Табличное расположение import java.awt.*;

import javax.swing.*;

public class GridLayoutSample extends JFrame { public GridLayoutSample() {

super("GridLayoutSample"); setSize(300, 200); setLocation(100, 100);

setDefaultCloseOperation( EXIT_ON_CLOSE );

//вспомогательная панель

JPanel grid = new JPanel();

//первые два параметра конструктора GridLayout -

//количество строк и столбцов в таблице

//вторые два — расстояние между ячейками по X и Y GridLayout gl = new GridLayout(2, 0, 5, 12); grid.setLayout(gl);

172 ГЛАВА 7

// создаем 8 кнопок

for (int i=0; i<8; i++) {

grid.add(new JButton("Кнопка " + i));

}

//помещаем нашу панель в центр окна add(grid);

//устанавливаем оптимальный размер pack();

//показываем окно

setVisible(true);

}

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

new Runnable() {

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

}

}

Обратите внимание на то, как в примере задается произвольное количество столбцов — для этого в конструкторе вместо конкретного числа столбцов указывается ноль. Аналогично можно задать и произвольное количество строк в таблице. Главное, чтобы оба числа не были нулями. В нашем примере GridLayout разделит компоненты так, чтобы они помещались в два ряда, неважно, как много столбцов для этого придется создать.

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

Все компоненты имеют одинаковый размер. Доступное пространство контейнера с табличным расположением разбивается на одинаковое количество ячеек, в каждую из которых помещается компонент.

Все компоненты всегда выводятся на экран, как бы ни было велико или малодоступно пространство.

Чаще всего мы не хотим, чтобы компоненты были слишком велики или слишком малы, поэтому почти всегда имеет смысл размещать панель с табличным расположением

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

173

GridLayout в дополнительной панели с последовательным расположением FlowLayout, которое наоборот, никогда не делает содержащиеся в нем компоненты больше их предпочтительного размера, или использовать другое расположение с такими же свойствами (GridBagLayout). Чтобы проиллюстрировать сказанное, создадим элемент пользовательского интерфейса, встречающийся практически в любом диалоговом окне, а именно строку кнопок (обычно это кнопки OK и Отмена). Табличное расположение придаст кнопкам одинаковый размер, а последовательное расположение не даст им «расплыться» и заодно выровняет их по правому краю:

//CommandButtons.java

//Создание панели командных кнопок import javax.swing.*;

import java.awt.*;

public class CommandButtons extends JFrame { public CommandButtons() {

super("CommandButtons"); setSize(350, 250); setLocation(150, 100);

setDefaultCloseOperation( EXIT_ON_CLOSE );

//создаем панель с табличным расположением для

//выравнивания размеров кнопок

JPanel grid = new JPanel(

new GridLayout(1, 2, 5, 0) );

//добавляем компоненты grid.add( new JButton("OK")); grid.add( new JButton("Отмена"));

//помещаем полученное в панель с последовательным

//расположением, выравненным по правому краю

JPanel flow = new JPanel(

new FlowLayout( FlowLayout.RIGHT )); flow.add(grid);

//помещаем строку кнопок вниз окна

add(flow, BorderLayout.SOUTH ); // выводим окно на экран setVisible(true);

}

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

new Runnable() {

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

}

}

174

ГЛАВА 7

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

В дальнейшем при создании различных диалоговых окон мы не раз будем использовать этот пример.

Динамические вкладки и CardLayout

Хотя менеджер расположения CardLayout поддерживается в пакетах JDK с самых первых версий, при создании пользовательского интерфейса им практически не пользуются. Менеджер CardLayout до появления библиотеки Swing использовался для создания так называемых вкладок (tabs), выбирая которые, можно было поочередно открывать доступ к панелям, занимающие одно и то же место. В библиотеке Swing имеется специальный класс JTabbedPane, который берет все заботы по организации вкладок на себя, а вам остается лишь добавлять их. Мы его вскоре изучим.

Вариантом применения CardLayout остается динамический интерфейс, которому не нужны визуальные вкладки, которые предоставляет JTabbedPane, но нужна возможность динамически, во время работы программы, менять одни панели на другие. Но такая возможность легко реализуется и без CardLayout — необходимо убрать из контейнера старую панель методом remove(), добавить новую панель, и провести проверку корректности контейнера методом revalidate(). Таким образом, область применения менеджера CardLayout весьма ограничена и мы даже не станем рассматривать его на примере.

Менеджер расположения SpringLayout

В пакете разработки JDK имеется универсальный менеджер расположения, способный помочь добиться любого, даже самого сложного расположения компонентов. Это менеджер расположения SpringLayout из пакета javax.swing. Однако несмотря на универсальность, действие его весьма специфично и не похоже на действие ни одного из уже знакомых нам менеджеров расположения. С каждым компонентом ассоциируется особый информационный объект Spring, который позволяет задать расстояние (в пикселах) между парой границ различных компонентов. Границ у компонента четыре — это его северная, восточная, западная и южная сторона. Можно задавать расстояние и между границами одного и того же компонента: например, задав расстояние между северной и южной сторонами одного компонента, вы укажете его высоту. По умолча-

Источник: https://studfile.net/preview/15935977/