RowLayout, GridLayout, FormLayot

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

Библиотека SWT позволяет применить свой менеджер расположения и предлагает несколько стандартных классов layout'ов :

  • FillLayout - визуальные компоненты размещаются в один ряд или колонку, размеры всех виджетов одинаковые;
  • RowLayout - компоненты размещаются в один или несколько рядов; можно устанавливать разные размеры компонентов и зазоры между компонентами;
  • GridLayout - компоненты размещаются в виде таблицы (сетки);
  • FormLayout - компоненты размещаются путем создания приложения для каждой стороны компонента;
  • Пример SashForm и GridLayout для интерфейса типа Explorer.

Для использования в приложении стандартных классов Layout необходимо импортировать соответствующий пакет SWT. Чтобы подключить layout к контейнеру компонентов надо вызвать метод setLayout(Layout). В следующем коде оболочка окна Shell (дочерний класс от Composite) подключает менеджер расположения RowLayout для позиционирования компонентов :

import org.eclipse.swt.layout.*;
...
Shell shell = new Shell();
shell.setLayout(new RowLayout());

Менеджеру Layout соответствует класс, содержащий данные для конкретных компонентов. В соответствии с соглашениями, наименование класса данных layout'а состоит из двух частей : название Layout'а и «Data». Например для стандартного RowLayout класс с данными будет называться RowData, для GridLayout наименование класса данных должно быть GridData, и для FormLayout это будет FormData. Пример использования класса данных :

Button button = new Button(shell, SWT.PUSH); 
button.setLayoutData(new RowData(50, 40));

Параметры менеджера расположения Layout

На следующем рисунке представлен компонент TabFolder, играющий роль контейнера Composite и нанесены метки с обозначениями, определяющие наиболее важные термины, используемые при описании layout'ов.

Контейнер Composite имеет :

  • location - расположение;
  • clientArea - клиентскую область;
  • trim - кромка.

Размер контейнера Composite определяется размером клиентской области и размером кромки. Класс Layout позволяет установить размер и позицию этих дочерних компонентов, задать spacing (промежуток) между компонентами, и margin (зазор) между компонентами и границей Layout. Размер Layout совпадает с размером клиентской области Composite.

Предпочтительный размер, preferred size

При размещении компонентов в окне используется понятие предпочтительный размер (preferred size) визуального компонента (widget), который определяет минимальный размер, необходимый для отображения содержимого. Для Composite предпочтительный размер определяет минимальный прямоугольник, в котором размещаются компоненты. Если расположением компонентов управляет ormLayout, то Composite рассчитывает свой preferred size согласно размерам и позициям компонентов. Если Composite использует менеджер расположения, то размер клиентской области определяется классом Layout и к полученному значению clientArea добавляет кромку trim, т.е. таким образом высчитывается предпочтительный размер.

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

Самый простой менеджер расположения представлен классом FillLayout. Данный Layout размещает все компоненты в один ряд или колонку и определяет для всех один размер. По умолчанию выбираются максимальная длина и ширина, которые будут использоваться для всех компонентов. FillLayout определяет одинаковое расстояние между компонентами. Данный Layout можно использовать в панели инструментов, в списке объединенных в группу checkbox'ов. FillLayout также может быть использован для Composite, содержащего только один компонент, например группу (Group), заполняющую всю область Shell.

Конструкторы FillLayout

// import org.eclipse.swt.layout.FillLayout;

FillLayout()
FillLayout(int type) 

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

Параметры FillLayout

// отступ от верхнего и нижнего края в пикселях 
int marginHeight 

// отступ от левого и правого края в пикселях 
int marginWidth 

// расстояние между ячейками соседних компонентов (по умолчанию 0)
int spacing 

// ориентация компонентов [HORIZONTAL | VERTICAL] - по умолчанию HORIZONTAL
int type 

ПРИМЕЧАНИЕ : при отрицательном значении spacing компоненты могут «накладываться» друг на друга.

Листинг примера использования FillLayout

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.layout.FillLayout;

public class FillLayoutExample
{
    public static void main (String [] args)
    {
        Display display = new Display ();
        final Shell shell = new Shell (display);
        shell.setText("Пример использования FillLayout");
        FillLayout fillLayout = new FillLayout();
//      fillLayout.type = SWT.VERTICAL;
        fillLayout.type = SWT.HORIZONTAL;
        fillLayout.marginWidth  = 10;
        fillLayout.marginHeight = 10;
        shell.setLayout(fillLayout);

        new Button(shell, SWT.PUSH).setText("Ясли");
        new Button(shell, SWT.PUSH).setText("Высшее учебное заведение");
        new Button(shell, SWT.PUSH).setText("Музыкальная школа");

        shell.pack ();
        shell.open ();

        while (!shell.isDisposed ()) {
            if (!display.readAndDispatch ()) display.sleep ();
        }
        display.dispose ();
    }
}

В примере использования FillLayout устанавливается вертикальное или горизонтальное расположение компонентов в shell и определяется отступ в 10 пикселей по горизонтали (слева и справа) и вертикали (вверху и внизу). В интерфейсе Shell размещаются 3 кнопки с разной длиной текстовой строки. FillLayout определяет одинаковые размеры для кнопок и заполняет ими все пространство Shell. На следующих скриншотах представлены интерфейсы примера для двух расположений.

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

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

Менджер расположения RowLayout обладает возможностью более детальной настройки размещения компонентов по сравнению с FillLayout, позволяя определить разные расстояния от компонента до края клиентской области. Кроме этого, при использовании RowLayout для каждого компонента могут быть заданы свои значения ширины и высоты. Эти значения задаются с определением RowData компонента и вызовом метода setLayoutData.

Конструкторы RowLayout

// import org.eclipse.swt.layout.RowLayout;

RowLayout()
RowLayout(int type) 

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

Параметры RowLayout

// флаг центрирования компонентов в ячейках
boolean center 

// флаг определения одинакового размера (длина, ширина) компонента
boolean fill 

// отступ от верхнего и нижнего края в пикселях 
int marginHeight 

// отступ от левого и правого края в пикселях 
int marginWidth 

// отступ от нижнего края в пикселях
int marginBottom 

// отступ от левого края в пикселях
int marginLeft 

// отступ от правого края в пикселях
int marginRight 

// отступ от верхнего края в пикселях
int marginTop 

// расстояние между ячейками соседних компонентов (по умолчанию 0)
int spacing 

// ориентация компонентов [HORIZONTAL | VERTICAL] - по умолчанию HORIZONTAL
int type 

// флаг определения предпочтительного размера preferred size компонентов
boolean pack 

// флаг распределения компонентов на доступном месте слева на направо
boolean justify 

// флаг переноса компонентов в следующий ряд при недостаточном ппространстве
boolean wrap 

Если значение pack равно true, то размер компонентов определяется текстом; при значении false компоненты заполняют все доступное пространство по аналогии с компонентами менеджера FillLayout. По умолчанию pack равно true.

При justify равным true компоненты распределятся на доступном месте слева на направо. Если Composite становится шире, то свободное место равномерно распределится между компонентами.

Если значения полей pack и justify истина (true), то компоненты отрисовываются с естественными размерами и свободное место распределяется равномерно между всеми компонентами.

ПРИМЕЧАНИЕ : при отрицательном значении spacing компоненты могут «накладываться» друг на друга.

Листинг примера использования RowLayout

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.layout.RowLayout;

public class RowLayoutExample
{
    public static void main (String [] args) 
    {
        Display display = new Display ();
        final Shell shell = new Shell (display);
        shell.setText("Пример RowLayout");
        RowLayout rowLayout = new RowLayout();
        rowLayout.type = SWT.VERTICAL;
        rowLayout.type = SWT.HORIZONTAL;
        rowLayout.marginTop    = 5;
        rowLayout.marginRight  = 15;
        rowLayout.marginBottom = 15;
        rowLayout.marginLeft   = 5;
        rowLayout.spacing      = 0;

        rowLayout.wrap = true;
        rowLayout.pack = true;
        rowLayout.justify = true;

        shell.setLayout(rowLayout);

        new Button(shell, SWT.PUSH).setText("Дошкольное учреждение");
        new Button(shell, SWT.PUSH).setText("Школа");
        new Button(shell, SWT.PUSH).setText("Институт");

        shell.pack ();
        shell.open ();

        while (!shell.isDisposed ()) {
            if (!display.readAndDispatch ()) display.sleep ();
        }
        display.dispose ();
    }
}

На следующем скриншоте представлен интерфейс примера для нормального и уменьшенного размера shell при wrap = true, pack = true, justify = true и отступах top = 5, right = 15, bottom = 15, left = 5.

После изменения значений параметров wrap = false, pack = false картинка изменится - все кнопки имеют одинаковый размер и не переносятся на следующую строку при недостаточном пространстве.

При значениях pack = true, justify = true свободное пространство равномерно распределяется между ячейками.

Использование RowData с RowLayout

Определим индивидуальные размеры для каждой из кнопок с использованием класса RowData. Для этого слегка изменим код примера.

Button button1 = new Button(shell, SWT.PUSH);
button1.setText("Дошкольное учреждение");
button1.setLayoutData(new RowData(180, 30));
		
Button button2 = new Button(shell, SWT.PUSH);
button2.setText("Школа");
button2.setLayoutData(new RowData(60, 35));

Button button3 = new Button(shell, SWT.PUSH);
button3.setText("Институт");
button3.setLayoutData(new RowData(80, 40));

Интерфейс окна представлен на следующем скриншоте. Кнопки имеют разный размер по высоте.

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

С помощью менеджера GridLayout можно разместить widget'ы в ячейках таблицы (на сетке). GridLayout позволяет устанавливать одинаковый размер ячеек по колонкам и индивидуально настраивать каждую ячейку таблицы с использованием класса GridData.

Конструкторы GridLayout

// import org.eclipse.swt.layout.GridLayout;

GridLayout() 
GridLayout(int numColumns, boolean makeColumnsEqualWidth) 

Первый конструктор создает менеджер расположения с одной колонкой. Второй конструктор в качестве параметров принимает параметры, определяющие количество колонок numColumns и флаг определения одинакового размера колонок makeColumnsEqualWidth.

Параметры GridLayout

// расстояние между соседними ячейками по горизонтали в пикселях
int horizontalSpacing 

// расстояние между соседними ячейками по вертикали в пикселях
int verticalSpacing 

// флаг определения одинакового размера колонок (по умолчанию false)
boolean makeColumnsEqualWidth 

// отступ от нижнего края в пикселях
int marginBottom 

// отступ от верхнего и нижнего края в пикселях 
int marginHeight 

// отступ от левого края в пикселях
int marginLeft 

// отступ от правого края в пикселях
int marginRight 

// отступ от верхнего края в пикселях
int marginTop 

// отступ от левого и правого края в пикселях 
int marginWidth 

// количество колонок в GridLayout 
int numColumns 

Листинг примера использования GridLayout

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;

// import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;

public class GridLayoutExample
{
    public static void main (String [] args) 
    {
        Display display = new Display ();
        final Shell shell = new Shell (display);
        shell.setText("Пример GridLayout");
        GridLayout gridLayout = new GridLayout();

        gridLayout.marginLeft  = 10;
        gridLayout.marginRight = 5;
        gridLayout.numColumns  = 2;
        shell.setLayout(gridLayout);
        new Button(shell, SWT.PUSH).setText("Ясли");
        new Button(shell, SWT.PUSH).setText("Институт");
        new Button(shell, SWT.PUSH).setText("Детский садик");
        new Button(shell, SWT.PUSH).setText("Школа");
        shell.setLayout(gridLayout);

        shell.pack ();
        shell.open ();

        while (!shell.isDisposed ()) {
            if (!display.readAndDispatch ()) 
                display.sleep ();
        }
        display.dispose ();
    }
}

На следующих скриншотах представлен интерфейс примера для numColumns = 3 и numColumns = 2. Для наглядности порядок расположения кнопок, т.е. сочетание кнопок с длиным и коротким текстом, меняется.

Если значение поля makeColumnsEqualWidth установить в true, то все колонки будут одинаковой ширины. Обратите внимание, что по умолчанию компоненты к колонках выровнены по левой стороне.

Поля marginWidth, marginHeight, horizontalSpacing и verticalSpacing в GridLayout работают также, как и в RowLayout. Поля marginLeft и marginRight объединены в marginWidth, а marginTop и marginBottom объединены в marginHeight. Кроме этого, GridLayout позволяет независимо задать horizontalSpacing и verticalSpacing в отличии от RowLayout, где используется только одно из двух значений в зависимости от текущего типа RowLayout.

Класс GridData

Объект GridData определяет данные Layout, ассоциированные с GridLayout. Чтобы передать компоненту GridData, используется метод setLayoutData(GridData). Конструкторы GridData :

GridData() 
GridData(int style) 
GridData(int width, int height) 
GridData(int horizontalAlignment, int verticalAlignment, 
         boolean grabExcessHorizontalSpace, 
         boolean grabExcessVerticalSpace) 
GridData(int horizontalAlignment, int verticalAlignment, 
         boolean grabExcessHorizontalSpace,
         boolean grabExcessVerticalSpace, 
         int horizontalSpan, 
         int verticalSpan) 

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

Замечание : не используйте объекты GridData повторно. Каждый управляемый менеджером GridLayout компонент должен иметь свой уникальный GridData с данными. Если во время представления в интерфейсе у компонента нет данных, для него будет создан уникальный объект GridData.

Наиболее значимые поля класса GridData

Наименование поляОписание
horizontalAlignment, verticalAlignment Выравнивание компонентов в ячейке. Возможные значения SWT.BEGINNING (по левому краю), SWT.CENTER (в центре), SWT.END (по правому краю), SWT.FILL (установить размер компонента согласно размеру ячейки в колонке)
horizontalIndent Смещение компонента вправо на заданное количество пикселей (имеет смысл использования при horizontalAlignment = SWT.BEGINNING)
horizontalSpan, verticalSpan Размещение компонента более чем в одной ячейки сетки. Эти поля часто используются совместно с выравниванием SWT.FILL
grabExcessHorizontalSpace, grabExcessVerticalSpace Флаг разрешения заполнения свободного пространства при увеличении Composite. Обычно данные параметры используются для больших компонентов типа Text, List или Canvas. Компоненты, получившие больше места при расширении окна, будут первыми уменьшены при уменьшении окна
widthHint, heightHint Определение ширины и высоты компонента в пикселях, полагая, что они не противоречат с другими требованиями GridLayout

Пример сложного GridLayout

Интерфейс более сложного примера использования GridLayout библиотеки SWT представлен на следующем скриншоте.

В примере DogShowRegistration.java используются такие свойства GridData, как horizontalSpan, horizontalIndent, verticalSpan, grabExcessHorizontalSpace и т.д. Исходный код примера не приводится на странице, но его можно скачать вместе с остальными примерами.

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

Менеджер FormLayout позволяет указать индивидуальное положение каждого компонента окна с привязкой либо к родительскому Composite, либо к соседнему. Для этого используется класс FormAttachment («привязка формы»).

Конструкторы FormLayout

Менеджер расположения имеет всего один конструктор.

// import org.eclipse.swt.layout.FormLayout;

FormLayout() 

Параметры менеджера расположения FormLayout

// расстояние между соседними компонентами в пикселях
int spacing 

// отступ от нижнего края в пикселях
int marginBottom 

// отступ от верхнего и нижнего края в пикселях 
int marginHeight 

// отступ от левого края в пикселях
int marginLeft 

// отступ от правого края в пикселях
int marginRight 

// отступ от верхнего края в пикселях
int marginTop 

// отступ от левого и правого края в пикселях 
int marginWidth 

Поля marginWidth и MarginHeight в FormLayout аналогичны одноименным полям в GridLayout. Левый и правый отступы определяются marginWidth, верхний и нижний - marginHeight. По умолчанию отступы в FormLayout равны нулю.

В следующем листинге создается окно с менеджером расположения FormLayout, и в окне shell размещается кнопка с привязкой к правому нижнему углу.

Display display = new Display ();
Shell shell = new Shell (display);

shell.setLayout (new FormLayout());

Button btnCancel = new Button (parent, SWT.PUSH);
btnCancel.setText ("&Cancel");

FormData fdCancel = new FormData (75, 24);
fdCancel.right    = new FormAttachment (100,-10);
fdCancel.bottom   = new FormAttachment (100, -5);
btnCancel.setLayoutData (fdCancel);

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

Для привязки кнопки к правому нижнему углу используется класс данных FormData. При создании объекта FormData определяются размеры кнопки.

Класс FormData

FormData имеет два конструктора. Конструктор без параметров использует значения по умолчанию. Второй конструктор в качестве параметров принимает значения ширины и высоты компонента.

// import org.eclipse.swt.layout.FormData;

FormData() 
 
FormData(int width, int height) 

Значение полей left, right, top и bottom объекта FormData определяются объектом FormAttachment, который ассоциируются с левой, правой, верхней и нижней стороной компонента. Дополнительно помимо конструктора можно использовать width и height.

Если привязывать поля компонента по горизонтали (left, right) и/или по вертикали (top и bottom), то компонент будет растягиваться или сжиматься в соответствующем направлении при изменении размера родительского окна.

Листинг примера FormLayoutExample

В примере создается простенькая форма авторизации с использованием менеджера FormLayout.

import org.eclipse.swt.SWT;

import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.FormAttachment;

public class FormLayoutExample 
{
    /**
     * Создание кнопок управления с привязкой к правому нижнему углу окна
     * @param parent
     */
    private static void createButtons(Shell parent)
    {
        Button btnOk = new Button (parent, SWT.PUSH);
        btnOk.setText ("OK");

        FormData fdOk = new FormData (60, 24);
        fdOk.right    = new FormAttachment (100, -70);
        fdOk.bottom   = new FormAttachment (100,-5);
        btnOk.setLayoutData (fdOk);

        Button btnCancel = new Button (parent, SWT.PUSH);
        btnCancel.setText ("Отмена");
        // Кнопка btnCancel привязывается к btnOk по вертикали сверху
        FormData fdCancel = new FormData (60, 24);
        fdCancel.right    = new FormAttachment (100, -10);
        fdCancel.top      = new FormAttachment (btnOk, 0, SWT.TOP);
        btnCancel.setLayoutData (fdCancel);
    }
    /**
     * Создание компонентов с привязкой к левому верхнему углу окна
     * @param parent
     */
    private static void createGUI(Shell parent)
    {
        // Логин пользователя
        Label lblLogin = new Label (parent, SWT.NONE);
        lblLogin.setText ("Логин");

        FormData formData = new FormData (60, 20);
        formData.top      = new FormAttachment (0, 10);
        formData.left     = new FormAttachment (0, 10);
        lblLogin.setLayoutData (formData);

        Text txtLogin = new Text (parent, SWT.BORDER);

        formData = new FormData (SWT.DEFAULT, SWT.DEFAULT);
        formData.top      = new FormAttachment (0, 10);
        formData.left     = new FormAttachment (lblLogin, 10);
        formData.right    = new FormAttachment (100     ,-10);
        formData.height   = 16;
        txtLogin.setLayoutData (formData);

        // Пароль пользователя
        Label lblPassword = new Label (parent, SWT.NONE);
        lblPassword.setText ("Пароль");

        formData = new FormData (60, 20);
        formData.top      = new FormAttachment (lblLogin, 10);
        formData.left     = new FormAttachment (0, 10);
        lblPassword.setLayoutData (formData);

        Text txtPassword = new Text (parent, SWT.BORDER);
        txtPassword.setEchoChar('*');

        formData = new FormData (SWT.DEFAULT, SWT.DEFAULT);
        formData.top      = new FormAttachment (txtLogin, 10);
        formData.left     = new FormAttachment (lblLogin, 10);
        formData.right    = new FormAttachment (100     ,-10);
        formData.height   = 16;
        txtPassword.setLayoutData (formData);

        createButtons(parent);
    }
    public static void main (String [] args) 
    {
        Display display = new Display ();
        Shell shell = new Shell (display);

        shell.setText("Пример FormLayout");

        shell.setLayout (new FormLayout());
        
        createGUI(shell);
        
        shell.setSize(280, 180);
        shell.open ();
        
        while (!shell.isDisposed ()) {
            if (!display.readAndDispatch ()) 
                display.sleep ();
        }
        display.dispose ();
    }
}

В примере к левому верхнему углу окна привязана метка Логин, к которой привязаны метка «Пароль» и поля ввода. Кнопки «ОК» и «Отмена» привязаны к правому нижнему углу. Поскольку поля ввода txtLogin и txtPassword привязаны левой и правой сторонами к окну, то при изменении его размеров по горизонтали они будут это отслеживать, т.е. будут рястягиваться/сжиматься.

Интерфейс примера использования FormLayout библиотеки SWT представлен на следующем скриншоте.

Объекты привязки FormAttachment

Объект FormAttachment определяет привязывание одной из сторон компонента. Не обязательно использовать этот объект для всех четырех сторон компонента. Можно определить размеры компонента и привязать один из углов.


// Примеры привязки с использованием конструктора

FormAttachment(Control control, int offset) 

//-------------------------------------------------------------------

// Привязка к верхней стороне со смещением 10 пикселей
FormData formData = new FormData(60, 24);
formData.top = new FormAttachment(0,10);
button.setLayoutData(formData);

// Привязка к верхней стороне окна на расстоянии 50% от его высоты
// с отслеживанием изменении размера окна по вертикали
formData.top = new FormAttachment(50,0);
button.setLayoutData(formData);

// Привязка к правой стороне окна с отступом 10 пикселей
formData.right = new FormAttachment(100, -10);
button.setLayoutData(formData);

// Привязка к метке "label" сверху с отсупом 10 пикселей
formData.top = new FormAttachment(label, 10);
button.setLayoutData(formData);

Чтобы привязать сторону компонента к краю родительского Composite, установите значение равное 0 или 100. Значение 0 расценивается как верхний/левый край, а 100 как правый/нижний.

Рассмотрим еще один конструктор класса FormAttachment.

FormAttachment(Control control, int offset, int alignment) 

Этот конструктор позволяет привязаться к компоненту control со смещением offset и с выравниванием alignment. В рассмотренном выше примере авторизации для кнопки btnCancel как раз используется данный конструктор для привязки к кнопке btnOk. В качестве значений alignment можно использовать SWT.TOP, SWT.RIGHT, SWT.BOTTOM, SWT.LEFT, SWT.CENTER.

Пример SashForm и GridLayout для интерфейса типа Explorer

Рассмотрим простой пример LayoutExample.java создания интерфейса типа проводника, включающего заголовочную панель header, рабочую область body и панель кнопок управления pnlButtons. Рабочую область разделим на левую и правую панели; правую панель разделим на верхнюю и нижнюю панели. При определении интерфейса рабочей области будем использовать компонент SashForm, позволяющий гибко распределять пространство между двумя связанными областями.

Интерфейс примера SashForm и GridLayout представлен на следующем скриншоте.

Структурно пример включает конструктор и процедуры формирования интерфейса разных областей окна : createPanelTop заголовочная панель, creatPanelCenter центральная панель, createPanelControls. В конструкторе к окну подключен менеджер расположения GridLayout с определением расположения в одну колонку numColumns = 1. Данный подход к структурированию класса по формированию интерфейса окна позволяет создать базовый класс, который можно наследовать при разработке разных форм с похожим интерфейсом.

Листинг примера LayoutExample

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;

import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.FillLayout;

import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Composite;

public class LayoutExample
{
    private  Composite  header     = null;
    private  Composite  body       = null;
    private  Composite  pnlButtons = null;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Конструктор класса
     * @param shell основное окно приложения
     */
    public LayoutExample(final Shell shell)
    {
        // Менеджер расположения главной формы
        GridLayout gridLayout      = new GridLayout();
        gridLayout.numColumns      = 1;
        gridLayout.marginHeight    = 1;
        gridLayout.marginWidth     = 1;
        gridLayout.verticalSpacing = 2;
        shell.setLayout(gridLayout);

        // Верхняя панель
        createPanelTop(shell);

        // Центральная панель
        creatPanelCenter(shell);

        // Панель кнопок управления
        createPanelControls(shell);
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    private void createPanelTop(Composite parent)
    {
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.heightHint = 30;

        header = new Composite (parent, SWT.BORDER);
        header.setLayoutData(gridData);
        header.setLayout(new FillLayout());
        new Label(header, SWT.CENTER).setText("Верхняя панель");
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    private void createPanelControls(Composite parent)
    {
        // Панель кнопок управления
        pnlButtons = new Composite(parent, SWT.BORDER);

        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.heightHint = 36;
        pnlButtons.setLayoutData(gridData);

        // Размещение кнопки в панели pnlButtons
        pnlButtons.setLayout(new FillLayout());
        new Label(pnlButtons, SWT.CENTER)
                                   .setText("Панель кнопок управления");
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    private void creatPanelCenter(Composite parent)
    {
        // Центральная панель
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL | 
                                         GridData.FILL_VERTICAL);
        gridData.grabExcessVerticalSpace = true;
        body = new Composite (parent, SWT.NONE);
        body.setLayoutData(gridData);

        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns   = 2;
        gridLayout.marginHeight = 0; 
        gridLayout.marginWidth  = 0;
        body.setLayout(gridLayout);

        SashForm sashForm = new SashForm(body, SWT.NONE);
        sashForm.setOrientation(SWT.HORIZONTAL);
        gridData = new GridData(GridData.FILL_HORIZONTAL | 
                                GridData.FILL_VERTICAL);
        gridData.horizontalSpan = 3;
        sashForm.setLayoutData(gridData);
        // Формирование интерфейса центральной панели 
        createBodyLeft (sashForm);
        createBodyRight(sashForm);
        // Определение положения разделителя
        sashForm.setWeights(new int[] { 2, 5 });
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    private void createBodyLeft(Composite parent)
    {
        Composite composite = new Composite(parent, SWT.BORDER);
        composite.setLayout(new FillLayout());

        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        composite.setLayoutData(gridData);

        composite.setLayout(new FillLayout());
        Label labelA = new Label(composite, SWT.CENTER);
        labelA.setText("Левая панель");
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    private void createBodyRight(Composite parent)
    {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new FillLayout());

        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        composite.setLayoutData(gridData);

        SashForm sashForm2 = new SashForm(composite, SWT.VERTICAL);

        Composite comp2_top = new Composite(sashForm2, SWT.BORDER);
        Composite comp2_bot = new Composite(sashForm2, SWT.BORDER);
        comp2_top.setLayout(new FillLayout());
        comp2_bot.setLayout(new FillLayout());
        
        Label labelA = new Label(comp2_top, SWT.CENTER);
        labelA.setText("Правая верхняя панель");
        Label labelB = new Label(comp2_bot, SWT.CENTER);
        labelB.setText("Правая нижняя панель");
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public static void main(String[] args)
    {
        Display display = new Display();
        Shell   shell = new Shell (display);
        shell.setText("Пример использования gridLayout");
        new LayoutExample(shell);

        shell.open ();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch ())
                display.sleep ();
        }
        display.dispose ();
    }
}

Использование в интерфейсе компонента SashForm позволяет пользователю гибко настраивать интерфейс перераспределением пространства.

Скачать примеры менеджеров расположения SWT Layout

Исходные коды рассмотренных примеров менеджеров расположения SWT в виде проекта Eclipse можно скачать здесь (4.72 Мб).

  Рейтинг@Mail.ru