Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых
[Назад]

Библиотека примеров приложений Java

Оглавление
Режим FlowLayout
Режим GridLayout
Режим BorderLayout
Режим CardLayout
GridBagLayout -  пример 1
GridBagLayout - заполнение формы
Инструментальная линейка
Панели
Точное размещение компонент
Прилипчивая кнопка

Назад Вперед

5.6. Режим GridBagLayout - заполнение формы

Пример демонстрирует использование режима размещения GridBagLayout системы Layout Manager для размещения в окне аплета несложной формы.

Исходный текст примера

Архив проекта для Java WorkShop 2.0

Демонстрация
(ваш браузер должен уметь работать с аплетами Java JDK 1.1)

Немного теории

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

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

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

Описание примера

В окне нашего аплета находится форма для регистрации посетителей сервера, в которой нужно заполнить несколько стандартных полей (рис. 1).

pic1.gif (4218 bytes)

Рис. 1. Форма для регистрации посетителей

Если заполнить форму и нажать кнопку OK, на экране появится диалоговая панель, отображающая введенные значения в окне многострочного редактора (рис. 2). Кнопка Cancel очищает введенную информацию.

pic2.gif (3823 bytes)

Рис. 2. Отображение введенной информации

Как в окне основного аплета, так и в окне диалоговой панели мы установили режим размещения компонент GridBagLayout.

Перейдем к рассмотрению исходного текста аплета.

Главный класс аплета GridBag2

Главный класс аплета GridBag2 создан на базе класса Applet и реализует интерфейс ActionListener:

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class GridBag2 extends Applet
  implements ActionListener
{
  . . .
}

Данный интерфейс необходим для обработки событий от кнопок.

В главном классе мы определили несколько полей, предназначенных для хранения ссылок на компоненты - текстовые поля, метки класса Label и кнопки:

TextField tfFirstName;
Label lbFirstName;
  
TextField tfMiddleName;
Label lbMiddleName;
  
TextField tfLastName;
Label lbLastName;
  
TextField tfZip;
Label lbZip;
  
TextField tfCountry;
Label lbCountry;
  
Button btnOK;
Button btnCancel;
Метод init

Этот метод получает управление при инициализации аплета. Он создает и размещает все компоненты в окне аплета, а затем регистрирует обработчики событий от кнопок.

Компоненты создаются обычным образом при помощи соответствующих конструкторов:

tfFirstName = new TextField(20);
lbFirstName = new Label("First name");
    
tfMiddleName = new TextField(20);
lbMiddleName = new Label("Middle name");
    
tfLastName = new TextField(20);
lbLastName = new Label("Last name");
    
tfZip = new TextField(10);
lbZip = new Label("ZIP code");
    
tfCountry = new TextField(8);
lbCountry = new Label("Country");
    
btnOK = new Button("OK");
btnCancel = new Button("Cancel");

Далее мы устанавливаем режим размещения GridBagLayout и создаем объект класса GridBagConstraints, необходимый для задания параметров размещения отдельных компонент:

GridBagLayout gbl = new GridBagLayout();
GridBagConstraints c = 
  new GridBagConstraints();
    
setLayout(gbl);

Ниже мы расскажем о выборе этих параметров.

Поле First name

Заполнение параметров и размещение этого поля выполняется следующим образом:

c.anchor = GridBagConstraints.NORTHWEST; 
c.fill   = GridBagConstraints.NONE;  
c.gridheight = 1;
c.gridwidth  = 1;
c.gridx = GridBagConstraints.RELATIVE; 
c.gridy = GridBagConstraints.RELATIVE; 
c.insets = new Insets(10, 10, 0, 0);
    
gbl.setConstraints(tfFirstName, c);
add(tfFirstName);

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

Параметр fill имеет значение GridBagConstraints.NONE, поэтому при изменении размеров контейнера размеры поля изменяться не будут.

Так как значение полей gridheight и gridwidth равно единице, поле занимает одну ячейку таблицы.

Поля gridx и gridy содержат значение GridBagConstraints.RELATIVE, поэтому добавление поля будет выполняться в направлении слева направо и сверху вниз.

И, наконец, поле insets задает отступы сверху и слева, равные 10 пикселам.

Метка для поля First name

Для этой метки мы используем те же параметры, что и для самого поля:

gbl.setConstraints(lbFirstName, c);
add(lbFirstName);

В результате метка будет расположена справа от поля First name.

Кнопка OK

Вот как заполняются параметры размещения для кнопки OK:

c.gridwidth  = GridBagConstraints.REMAINDER; 
c.ipadx = 32;
 
gbl.setConstraints(btnOK, c);
add(btnOK);

Как видите, параметр gridwidth имеет значение, равное GridBagConstraints.REMAINDER. В результате кнопка будет последним компонентом в первой строке. Ее размеры останутся неизменными при изменении размеров контейнера, так как поле fill имеет значение GridBagConstraints.NONE.

Чтобы несколько увеличить размеры кнопки OK по горизонтали, мы задали в поле ipadx значение, равное 32 пикселам.

Поле Middle name и метка этого поля

Перед добавлением поля и его метки мы восстанавливаем параметры ipadx и gridwidth, измененные на предыдущем шаге:

c.ipadx = 0;
c.gridwidth  = 1; 
 
gbl.setConstraints(tfMiddleName, c);
add(tfMiddleName);
    
gbl.setConstraints(lbMiddleName, c);
add(lbMiddleName);

В результате поле Middle name будет размещено в первой ячейки второй строки.

Кнопка Cancel

Эта кнопка размещается так:

c.gridwidth  = GridBagConstraints.REMAINDER; 
c.ipadx = 10;
c.weightx = 1.0;
    
gbl.setConstraints(btnCancel, c);
add(btnCancel);

Здесь в поле gridwidth мы указали значение GridBagConstraints.REMAINDER, поэтому кнопка Cancel будет последней во второй строке.

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

Поле Last name

Это поле добавляется в начало третьей строки:

c.ipadx = 0;
c.gridwidth  = 1; 
c.weightx = 0.0;
    
gbl.setConstraints(tfLastName, c);
add(tfLastName);

Здесь мы просто восстанавливаем параметры, аналогичные параметрам поля Middle name, расположенного в начале второй строки.

Метка поля Last name

Эта метка занимает всю оставшуюся часть третьей строки, так как в поле gridwidth мы задали значение GridBagConstraints.REMAINDER:

c.gridwidth  = GridBagConstraints.REMAINDER; 
 
gbl.setConstraints(lbLastName, c);
add(lbLastName);
Поле ZIP

При размещении этого поля мы восстанавливаем значение параметра gridwidth, измененное на предыдущем шаге:

c.gridwidth  = 1; 
    
gbl.setConstraints(tfZip, c);
add(tfZip);
Метка поля ZIP

Для этого компонента мы выделяем всю оставшуюся часть строки, задавая в поле gridwidth значение GridBagConstraints.REMAINDER:

c.gridwidth  = GridBagConstraints.REMAINDER; 
    
gbl.setConstraints(lbZip, c);
add(lbZip);
Поле Country

Это поле занимает одну ячейку последней строки, поэтому в поле gridwidth мы записали значение 1:

c.gridwidth  = 1; 
    
gbl.setConstraints(tfCountry, c);
add(tfCountry);
Метка поля Country

Для этой метки мы установили следующие параметры:

c.weighty = 1.0;
c.gridwidth  = GridBagConstraints.REMAINDER; 
    
gbl.setConstraints(lbCountry, c);
add(lbCountry);

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

Перед завершением работы метод init регистрирует обработчики событий от кнопок:

btnOK.addActionListener(this);
btnCancel.addActionListener(this);
Метод actionPerformed

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

Если была нажата кнопка OK, метод actionPerformed получает строки из полей нашей формы и записывает их в текстовую переменную с именем s:

String s = "<Personal information>";
    
s = "First name: " + 
  tfFirstName.getText() + 
  "\nMiddle name: " + 
  tfMiddleName.getText() +
  "\nLast name: " + 
  tfLastName.getText() +
  "\nZIP code: " + tfZip.getText() +
  "\nCountry: " + tfCountry.getText();

Далее метод создает диалоговую панель класса AppletMsgBox (определенный в нашем приложении), передавая строку s соответствующему конструктору:

AppletMsgBox amsgbox;
amsgbox = new AppletMsgBox(s, "Information");
amsgbox.show();

Панель затем отображается методом show.

В том случае если была нажата кнопка Cancel, поля формы очищаются:

tfFirstName.setText("");
tfMiddleName.setText("");
tfLastName.setText("");
tfZip.setText("");
tfCountry.setText("");

Класс AppletMsgBox

Этот класс мы создали для отображения диалоговой панели с сообщением и кнопкой OK. Он образован на базе класса Frame и реализует интерфейс ActionListener:

class AppletMsgBox extends Frame
  implements ActionListener
{
  . . .
}

В классе AppletMsgBox определено два поля:

Button btnOK;
TextArea ta;

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

Конструктор класса AppletMsgBox

Конструктору класса AppletMsgBox передаются два параметра - строка сообщения и строка заголовка:

public AppletMsgBox(String msg, String title)
{
  . . .
}

Первым делом конструктор класса AppletMsgBox вызывает конструктор базового класса Frame, передавая ему строку заголовка title, и устанавливает размеры окна панели:

super(title);
setSize(400, 200);

Кнопка и редактор текста создаются обычным образом:

btnOK = new Button("OK");
ta = new TextArea(msg, 5, 40);
ta.setEditable(false);

Так как поле ta будет использоваться только для отображения сообщений, мы отменяем функцию редактирования, вызывая метод setEditable.

Далее мы устанавливаем режим размещения компонент GridBagLayout:

GridBagLayout gbl = new GridBagLayout();
GridBagConstraints c = 
  new GridBagConstraints();
    
setLayout(gbl);

Параметры размещения текстового поля выбираются следующим образом:

c.anchor = GridBagConstraints.CENTER; 
c.fill   = GridBagConstraints.BOTH;  
c.gridheight = 1;
c.gridwidth  = GridBagConstraints.REMAINDER; 
c.gridx = GridBagConstraints.RELATIVE; 
c.gridy = GridBagConstraints.RELATIVE; 
c.insets = new Insets(10, 0, 0, 0);
    
gbl.setConstraints(ta, c);
add(ta);

Задавая в поле anchor значение GridBagConstraints.CENTER, мы добиваемся центрирования редактора внутри выделенного ему пространства.

Так как поле fill имеет значение GridBagConstraints.BOTH, размеры окна редактора изменяются таким образом, чтобы он занимал всю поверхность выделенной ему ячейки таблицы.

Мы разместили окно редактора в одной ячейке (значение поля gridheight равно единице), причем оно занимает всю первую строку (в поле gridwidth мы записали значение GridBagConstraints.REMAINDER).

Что же касается кнопки, то ее размеры останутся постоянными при изменении размеров контейнера:

c.fill   = GridBagConstraints.NONE;  
c.ipadx = 35;
gbl.setConstraints(btnOK, c);
add(btnOK);

Заметим, что мы не задали значения в полях weightx и weighty. В результате при изменении размеров окна диалоговой панели и редактор, и кнопка будут находится в его центре.

Перед завершением своей работы конструктор регистрирует обработчик событий для кнопки btnOK:

btnOK.addActionListener(this);
Метод actionPerformed

Этот метод скрывает окно диалоговой панели, когда пользователь нажимает на кнопку OK:

public void actionPerformed(ActionEvent e)
{
  if(e.getSource().equals(btnOK))
  {
    setVisible(false);
  }
}

Назад Вперед

[Назад]