Конспект лекций по курсу Выбранные вопросы информатики (часть 2) для специальности Информатика Графика
Вид материала | Конспект |
- Конспект лекций по курсу Выбранные вопросы информатики (часть 1) для специальности, 2228.49kb.
- Конспект лекций по курсу "Начертательная геометрия и инженерная графика" Кемерово 2002, 786.75kb.
- Вопросы к зачету по курсу лекций "Информатика" для студентов Iкурса кафедры аэту iсеместр., 18.81kb.
- Конспект лекций по курсу "Информатика и использование компьютерных технологий в образовании", 1797.24kb.
- Программа «Компьютерная графика» кружковая работа по дисциплине «информатика» для специальности, 186.22kb.
- Конспект лекций по дисциплине информатика для студентов заочного отделения, 649.48kb.
- Конспект лекций по курсу «бизнес-планирование в условиях рынка», 461.46kb.
- Конспект лекций для специальности «Прикладная информатика в экономике», 1468.57kb.
- Конспект лекций по дисциплине «Высокоуровневые методы информатики и программирования», 2453.58kb.
- Конспект лекций по курсу «Организация производства», 2034.84kb.
If your browser recognized the applet tag, you would see an applet here.
Описание исходного текста
Приведем краткое описание полей и методов, определенных в аплете FormDemo.
Поля главного класса
В главном классе нашего аплета мы определили несколько полей.
Поле btReady хранит ссылку на кнопку с надписью Ready:
Button btReady;
В полях chbox1 и chbox2 записаны ссылки на переключатели с независимой фиксацией, которые используются для активизации однострочных текстовых полей:
Checkbox chbox1;
Checkbox chbox2;
Поле grRadio хранит ссылку на группу переключателей с зависимой фиксацией, определяющих режимы работы Mode 1, Mode 2 и Mode 3:
CheckboxGroup grRadio;
Ссылки на эти переключатели находятся в следующих трех полях:
Checkbox rd1;
Checkbox rd2;
Checkbox rd3;
В поле ch1 хранится ссылка на список, предназначенный для выбора цвета:
Choice ch1;
Слева от однострочных полей редактирования в нашем окне имеются подписи, реализованные как объекты класса Label. Ссылки на эти объекты находятся в полях lbFirstName и lbSecondName:
Label lbFirstName;
Label lbSecondName;
Ссылки на однострочные поля редактирования записаны в поля с именами txtFirstName и txtSecondName:
TextField txtFirstName;
TextField txtSecondName;
И, наконец, ссылка на многострочное текстовое поле хранится в поле с именем txta:
TextArea txta;
Метод init
Метод init занимается созданием компонент и добавлением их в окно алпета. Кроме того, этот метод изменяет цвет фона окна аплета и окон добавляемых компонент.
Прежде всего метод init создает два переключателя с независимой фиксацией, два объекта класса Label и два однострочных поля редактирования текста:
chbox1 = new Checkbox("First");
add(chbox1);
lbFirstName = new Label("Enter your first name:");
add(lbFirstName);
txtFirstName = new TextField(" ", 30);
add(txtFirstName);
chbox2 = new Checkbox("Second");
add(chbox2);
lbSecondName = new Label("Enter your second name:");
add(lbSecondName);
txtSecondName = new TextField(" ", 30);
add(txtSecondName);
Поля создаются при помощи конструкторов, а добавляются в окно аплета методом add. Согласно схемы расположения компонент, установленой по умолчанию, добавляемые компоненты размещаются сверху вниз и слева направо.
Для группы переключателей с зависимой фиксацией мы создаем объект класса CheckboxGroup:
grRadio = new CheckboxGroup();
Ссылка на этот объект затем передается в качестве второго параметра конструкторам, создающим переключатели:
rd1 = new Checkbox("Mode 1", grRadio, true);
rd2 = new Checkbox("Mode 2", grRadio, false);
rd3 = new Checkbox("Mode 3", grRadio, false);
Переключатели добавляются в окно аплета при помощи метода add:
add(rd1);
add(rd2);
add(rd3);
Список цветов создается как объект класса Choice:
ch1 = new Choice();
После создания списка мы добавляем в него три элемента, вызывая для этого метод addItem:
ch1.addItem("White");
ch1.addItem("Green");
ch1.addItem("Yellow");
Вслед за этим мы добавляем сформированный список в окно аплета:
add(ch1);
Для установки цвета фона мы вызываем метод setBackground без указания объекта:
setBackground(Color.yellow);
В этом случае метод вызывается для текущего объекта, то есть для нашего аплета. Чтобы установить цвет фона в окнах компонент, мы вызываем метод setBackground для соответствующих объектов, как это показано ниже:
lbFirstName.setBackground(Color.yellow);
lbSecondName.setBackground(Color.yellow);
rd1.setBackground(Color.yellow);
rd2.setBackground(Color.yellow);
rd3.setBackground(Color.yellow);
chbox1.setBackground(Color.yellow);
chbox2.setBackground(Color.yellow);
Многострочное текстовое поле создается как объект класса TextArea. В нем 6 строк и 45 столбцов:
txta = new TextArea("", 6, 45);
add(txta);
Первоначальный цвет фона многострочного текстового поля устанавливается тем же способом, чтомы использовали для других компонент:
txta.setBackground(Color.white);
Этот цвет в дальнейшем будет изменяться обработчиком событий, создаваемых списком цветов.
И, наконец, последнее что делает метод init перед тем как вернуть управление, - создает кнопку с надписью Ready и добавляет ее в окно аплета:
btReady = new Button("Ready");
add(btReady);
Метод action
В методе action мы определили рабочие поля btn, str1 и str2:
Button btn;
String str1, str2;
В начале своей работы метод action определяет, какой компонент вызвал событие. Для этого анализируется поле evt.target:
if(evt.target instanceof Button)
{
. . .
return true;
}
else if(evt.target instanceof Choice)
{
. . .
return true;
}
return false;
Наш метод action обрабатывает события, вызываемые объектами классов Button и Choice. Если событие вызвано компонентом, относящимся к какому-либо другому классу, метод возвращает значение false. Этим он сигнализирует, что обработка события не выполнялась.
В случае успешной обработки события метод action возвращает значение true.
Если событие вызвано кнопкой, наш метод action проверяет, какой именно. Обработка выполняется только в том случае, если через поле evt.target передается ссылка на кнопку btReady:
if(evt.target.equals(btReady))
{
. . .
}
else
{
return false;
}
return true;
В противном случае метод action возвращает значение false, отказываясь от обработки события.
Что делает обработчик события, создаваемого кнопкой?
Прежде всего, он сохраняет ссылку на кнопку в рабочей переменной (просто для того чтобы показать, как это делается):
btn = (Button)evt.target;
Далее наш обработчик события извлекает текстовые строки из однострочных текстовых полей, вызывая для этого метод getText. Эти строки записываются в рабочие переменные str1 и str2:
str1 = txtFirstName.getText();
str2 = txtSecondName.getText();
Затемметод action проверяет состояние переключателей с независимой фиксацией chbox1 и chbox2. Если они включены, содержимое соответствующих временных переменных добавляется в многострочное текстовое поле txta:
if(chbox1.getState())
txta.append(str1);
if(chbox2.getState())
txta.append(str2);
Для добавления мы вызываем метод append.
Аналогичным образом преверяется состояние переключателей с зависимой фиксацией:
if(rd1.getState())
txta.append("\nMode 1\n");
if(rd2.getState())
txta.append("\nMode 2\n");
if(rd3.getState())
txta.append("\nMode 3\n");
Если событие вызвано списокм цветов ch1, то метод action определяет, какая строка списка стала выделенной и устанавливает в многострочном поле редактирования соответствующий цвет фона. Для определения выделенной строки применяется метод getSelectedIndex:
if(evt.target.equals(ch1))
{
if(ch1.getSelectedIndex() == 0)
txta.setBackground(Color.white);
if(ch1.getSelectedIndex() == 1)
txta.setBackground(Color.green);
if(ch1.getSelectedIndex() == 2)
txta.setBackground(Color.yellow);
}
Работу остальных методов приложения FormDemo вы сможете разобрать самостоятельно.
Работа с системой Layout Manager
В предыдущей статье мы рассказали вам о том, как создавать компоненты и размещать их в контейнере. Однако предложенный способ размещения компонент в окне контейнера едва ли можно назвать удобным, так как заранее трудно предугадать, на каком месте окажется тот или иной орган управления.
К счастью, имеются способы, позволяющие контролировать размещение отдельных компонент в окне контейнера. И хотя эти способы не позволяют задавать конкретные координаты и размеры органов управления, использовнные схемы размещения компонент будут правильно работать на любой аппаратной платформе (не забывайте, что Java создавалась как средство разработки приложений, способных выполняться на любой платформе).
В чем трудность создания пользовательского интерфейса для мультиплатформных систем?
В том, что разработчик приложения никогда не знает характеристики устройства отображения, установленные у пользователя. Он, в частности, не может заранее знать разрешение монитора, размер системного шрифта и другие характеристики, необходимые для компоновки диалоговых панелей в терминах абсолютных координат.
Средства пользовательского интерфейса AWT способны динамически измнять размеры компонент, подгоняя их "по месту" в системе пользователя. В результате значительно повышается вероятность того что внешний вид диалоговой панели, в каком она предстанет перед пользователем, будет похож на то, что ожидал разработчик.
Режимы системы Layout Manager
Прежде чем мы рассмотрим различные режимы компоновки системы Layout Manager, вспомним, как происходит наследование класса Applet (рис. 1).
Рис. 1. Наследование класса Applet
Класс Applet наследуется от класса Panel, который, в свою очередь, наследуется от класса Container и Component. Класс Container пользуется интерфейсом LayoutManager, что позволяет выбирать для контейнеров один из нескольких режимов размещения компонент в окне контейнера.
Что же касается класса Panel, то для него по умолчанию выбирается режим размещения компонент с названием Flow Layout. Разумеется, вы можете выбрать другой режим размещения, указав его явным образом.
Ниже мы перечислили все возможные режимы системы Layout Manager:
Режим размещения компонент | Описание |
FlowLayout | Компоненты заполняют окно контейнера "потоком" по мере их добавления методом add. Они размещаются слева направо и сверху вниз |
GridLayout | Компоненты размещаются в виде таблицы по мере добавления слева направо и сверху вниз. Для этой таблицы можно указать количество столбцов и строк |
GridBagLayout | Аналогично предыдущему, однако при добавлении компонент в таблицу можно указать координаты ячейки, в которую помещается компонента |
BorderLayout | При размещении компоненты указывается одно из нескольких направлений: юг, север, запад, восток, центр. Направление определяется относительно центра окна контейнера |
CardLayout | Размещение компонент друг над другом в одном окне. Этот режим позволяет организовать набор диалоговых панелей в виде блокнота |
Каждому режиму соответсвует одноименный класс, методы и конструкторы которого позволяют выбирать различные компоновки.
Далее на примере конкретного приложения мы рассмотрим использование перечисленных выше режимов системы Layout Manager.
Режим FlowLayout
В этом режиме мы добавляли компоненты во всех примерах аплетов, приведенных ранее, так как по умолчанию для аплетов используется именно режим FlowLayout.
Класс FlowLayout
Ниже мы привели краткое описание класса FlowLayout:
Поля
Следующие три поля задают способы выравнивания:
- CENTER
Центрирование
public final static int CENTER;
- LEFT
По левой границе
public final static int LEFT;
- RIGHT
По правой границе
public final static int RIGHT;
Конструкторы
Без указания выравнивания и зазора между компонентами
public FlowLayout();
С указанием выравнивания
public FlowLayout(int align);
С указанием выравнивания и зазора между компонентами по вертикали и горизонтали
public FlowLayout(int align,
int hgap, int vgap);
Обычно приложения не вызывают методы класса FlowLayout, устанавливая варианты компоновки при помощи конструкторов.
Первый конструктор класса FlowLayout не имеет параметров. Он устанавливает по умолчанию режим центрирования компонент и зазор между компонентами по вертикали и горизонтали, равный 5 пикселам. Именно этот режим и использовался раньше во всех наших аплетах, так как именно он применяется по умолчанию объектами класса Panel, от которого наследуется класс Applet.
С помощью второго конструктора вы можете выбрать режим размещения с заданным выравниванием компонент в окне контейнера по горизонтали. В качестве параметров этому конструктору необходимо передавать значения FlowLayout.LEFT, FlowLayout.RIGHT, или FlowLayout.CENTER. Зазор между компонентами будет при этом равен по умолчанию 5 пикселам.
И, наконец, третий конструктор допускает раздельное указание режима выравнивания, а также зазоров между компонентами по вертикали и горизонтали в пикселах.
Методы
- addLayoutComponent
Не используется
public void addLayoutComponent(String name, Component comp);
- layoutContainer
Предназначен для того чтобы компоненты могли установить для себя предпочтительный размер
public void layoutContainer(Container target);
- minimumLayoutSize
Определение минимального размера окна контейнера, необходимого для размещения всех компонент
public Dimension minimumLayoutSize(Container target);
- preferredLayoutSize
Определение предпочтительного размера окна контейнера, необходимого для размещения всех компонент
public Dimension preferredLayoutSize(Container target);
- removeLayoutComponent
Удаление компоненты из контейнера
public void removeLayoutComponent(Component comp);
- toString
Получение строки названия метода компоновки
public String toString();
Режим GridLayout
В режиме GridLayout компоненты размещаются в ячейках таблицы, параметры которой можно задать с помощью конструкторов класса GridLayout.
При размещении компонент внутри ячеек таблицы все они получают одинаковые размеры. Если один из параметров, задающих размерность таблицы, равен нулю, это означает, что соответствующий столбец или строка может содержать любое количество элементов.
Заметим, что оба параметра rows и cols не могут быть равны нулю одновременно.
Приведем описание конструкторов класса GridLayout.
Конструкторы
Создание таблицы с заданным количеством строк и столбцов
public GridLayout(int rows, int cols);
Создание таблицы с заданным количеством строк и столбцов и с заданным зазором между компонентами
public GridLayout(int rows, int cols, int hgap, int vgap);
Методы
Методы класса GridLayout используются редко, поэтому мы их только перечислим.
public void addLayoutComponent(String name,Component comp);
public void layoutContainer(Container target);
public Dimension minimumLayoutSize(Container target);
public Dimension preferredLayoutSize(Container target);
public void removeLayoutComponent(Component comp);
public String toString();
Режим BorderLayout
При использовании режима BorderLayout окно контейнера разделяется на рамку и центральную часть. При размещении компонент указывается направление от центра окна, в котором слудует размещать компоненты.
Конструкторы класса BorderLayout
Ниже приведено краткое описание конструкторов класса BorderLayout.
public BorderLayout();
public BorderLayout(int hgap, int vgap);
Эти конструкторы предназначены для создания схемы размещения, без зазора между компонентами и с зазором заданной величины,соответственно.
Методы класса BorderLayout
Перечислим также методы класса BorderLayout:
public void addLayoutComponent(String name, Component comp);
public void layoutContainer(Container target);
public Dimension minimumLayoutSize(Container target);
public Dimension preferredLayoutSize(Container target);
public void removeLayoutComponent(Component comp);
public String toString();
Применение класса BorderLayout
Добавляя компоненты к контейнеру, вы должны использовать метод add с двумя параметрами, первый из которых указывает направление размещения, а второй - ссылку на добавляемый объект:
add("North", btn1);
add("East", btn2);
add("West", btn3);
add("South", btn4);
add("Center", btn5);
Режим CardLayout
Режим CardLayout предназначен для создания набора диалоговых панелей, которые можно показывать по очереди в одном окне прямоугольной формы. Обычно для управления процессом перебора диалоговых панелей в режиме CardLayout используются отдельные органы управления, расположенные в другой панели или даже в другом аплете на той же самой странице сервера Web.
Класс CardLayout содержит два конструктора и несколько методов.
Конструкторы класса CardLayout
Режим без зазоров
public CardLayout();
Режим с зазорами по вертикали и горизонтали между компонентами и окном контейнера
public CardLayout(int hgap, int vgap);
Методы класса CardLayout
- addLayoutComponent
Добавление компоненты с указанием имени
public void addLayoutComponent(String name, Component comp);
- first
Отображение первой страницы блокнота
public void first(Container target);
- last
Отображение последней страницы блокнота
public void last(Container target);
- next
Отображение следующей страницы блокнота
public void next(Container target);
- previous
Отображение предыдущей страницы блокнота
public void previous(Container target);
- layoutContainer
Выполнение размещения компонент
public void layoutContainer(Container target);
- minimumLayoutSize
Определение минимальных размеров окна, необходимых для размещения компонент
public Dimension minimumLayoutSize(Container target);
- preferredLayoutSize
Определение предпочтительных размеров окна, необходимых для размещения компонент
public Dimension preferredLayoutSize(Container target);
- removeLayoutComponent
Удаление заданной компоненты
public void removeLayoutComponent(Component comp);
- show
Отображение произвольной страницы блокнота по ее имени
public void show(Container target, String name);
- toString
Получение текстовой строки названия режима размещения
public String toString();
Использование режима размещения CardLayout
Как пользоваться режимом размещения CardLayout?
Обычно в окне аплета создается две панели, одна из которых предназначена для показа страниц блокнота в режиме размещения CardLayout, а вторая содержит органы управления перелистыванием страниц, например, кнопки.
Такие методы, как first, last, next и previous позволяют отображать, соответственно, первую, последнюю, следующую и предыдущую страницу блокнота. Если вызвать метод next при отображении последней страницы, в окне появится первая страница. Аналогично, при вызове метода previous для первой страницы блокнота вы увидите последнюю страницу.
А как отобразить произвольную страницу, не перебирая их по одной методами next и previous?
Для этого существует метод show. Учтите, что этот метод позволяет отображать только такие страницы, при добавлении которых методом add было указано имя, например:
pCardPanel.add("BackgroundColor", pBackgroundColor);
pCardPanel.add("ForegroundColor", pForegroundColor);
pCardPanel.add("Font", pFont);
Здесь в панель pCardPanel добавляются панели pBackgroundColor, pForegroundColor и pFont, имеющие имена, соответственно, "BackgroundColor", "ForegroundColor" и "Font".
Режим GridBagLayout
Режим GridBagLayout намного сложнее только что описанного режима GridLayout. Он позволяет размещать компоненты разного размера в таблице, задавая при этом для отдельных компонент размеры отступов и количество занимаемых ячеек.
Сейчас мы не будем рассматривать этот режим, так как сходные результаты могут быть достигнуты другими, менее сложными способами. Например, вы можете создать в контейнере несколько панелей, использовав внутри каждой свой метод размещения компонент.
Если вы создаете аплеты для размещения в документах HTML, никто не заставляет вас ограничиваться только одним аплетом для одного документа HTML - вы можете разместить там произвольное количество аплетов, организовав взаимодействие с одной стороны, между отдельными аплетами, а с другой - между аплетами и расширениями сервера Web.
В интегрированной системе разработки приложений Java WorkShop версии 2.0 имеется встроенная система визуального проектирования пользовательского интерфейса, в результате работы которой создаются исходные тексты классов. Размещение органов управления при этом выполняется интерактивными средствами.
Аплет FormLayout
В окне аплета FormLayout (рис. 2) мы расположили те же самые органы управления, которые были использованы в предыдущем аплете FormDemo. Однако для указания способа размещения компонент мы выполнили настройку системы Layout Manager, выбрав режим GridLayout.
Рис. 2. Окно аплета FormLayout
И хотя пока еще внешний вид нашей формы оставляет желать лучшего, расположение отдельных компонент не изменяется при изменении размеров окна аплета.
Проблема заключается в том, что в режиме GridLayout не удается управлять размерами компонент. Для устранения этого недостатка следует использовать режим GridBagLayout. Так как этот режим сложен для использования без визуального проектирования, мы отложим дальнейшее совершенстовование нашей формы до тех пор, пока не займемся изучением соответствующих средств Java WorkShop.
Исходный текст аплета FormLayout
Исходный текст аплета FormLayout практически повторяет исходный текст аплета FormDemo, рассмотренный в нашей предыдущей статье. Единственное отличие заключается в том, что в методе init мы выполнили настройку системы Layout Manager, установив режим GridLayout:
public void init()
{
setLayout(new GridLayout(4, 3));
. . .
}
Здесь для размещения компонент в окне аплета создается таблица из четырех строк и трех столбцов.
Полный исходный текст аплета FormLayout вы найдете в листинге 1.
Листинг 1. Файл FormLayout.java
import java.applet.Applet;
import java.awt.*;
import java.util.*;
public class FormLayout extends Applet
{
Button btReady;
Checkbox chbox1;
Checkbox chbox2;
CheckboxGroup grRadio;
Checkbox rd1;
Checkbox rd2;
Checkbox rd3;
Choice ch1;
Label lbFirstName;
Label lbSecondName;
TextField txtFirstName;
TextField txtSecondName;
TextArea txta;
public void init()
{
setLayout(new GridLayout(4, 3));
chbox1 = new Checkbox("First");
add(chbox1);
lbFirstName = new Label("Enter your first name:");
add(lbFirstName);
txtFirstName = new TextField(" ", 30);
add(txtFirstName);
chbox2 = new Checkbox("Second");
add(chbox2);
lbSecondName = new Label("Enter your second name:");
add(lbSecondName);
txtSecondName = new TextField(" ", 30);
add(txtSecondName);
grRadio = new CheckboxGroup();
rd1 = new Checkbox("Mode 1", grRadio, true);
rd2 = new Checkbox("Mode 2", grRadio, false);
rd3 = new Checkbox("Mode 3", grRadio, false);
add(rd1);
add(rd2);
add(rd3);
ch1 = new Choice();
ch1.addItem("White");
ch1.addItem("Green");
ch1.addItem("Yellow");
add(ch1);
setBackground(Color.yellow);
lbFirstName.setBackground(Color.yellow);
lbSecondName.setBackground(Color.yellow);
rd1.setBackground(Color.yellow);
rd2.setBackground(Color.yellow);
rd3.setBackground(Color.yellow);
chbox1.setBackground(Color.yellow);
chbox2.setBackground(Color.yellow);
txta = new TextArea("", 6, 45);
add(txta);
txta.setBackground(Color.white);
btReady = new Button("Ready");
add(btReady);
}
public String getAppletInfo()
{
return "Name: FormDemo";
}
public void paint(Graphics g)
{
Dimension dimAppWndDimension = getSize();
g.setColor(Color.black);
g.drawRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
}
public boolean action(Event evt, Object obj)
{
Button btn;
String str1, str2;
if(evt.target instanceof Button)
{
if(evt.target.equals(btReady))
{
btn = (Button)evt.target;
str1 = txtFirstName.getText();
str2 = txtSecondName.getText();
if(chbox1.getState())
txta.append(str1);
if(chbox2.getState())
txta.append(str2);
if(rd1.getState())
txta.append("\nMode 1\n");
if(rd2.getState())
txta.append("\nMode 2\n");
if(rd3.getState())
txta.append("\nMode 3\n");
}
else
{
return false;
}
return true;
}
else if(evt.target instanceof Choice)
{
if(evt.target.equals(ch1))
{
if(ch1.getSelectedIndex() == 0)
txta.setBackground(Color.white);
if(ch1.getSelectedIndex() == 1)
txta.setBackground(Color.green);
if(ch1.getSelectedIndex() == 2)
txta.setBackground(Color.yellow);
}
}
return false;
}
}
Исходный текст документа HTML, созданный для нашего аплета системой Java WorkShop, представлен в листинге 2.
Листинг 2. Файл FormLayout.tmp.phpl
name="FormLayout" code="FormLayout" codebase="file:/e:/sun/articles/vol7/src/FormLayout"
width="500" height="600" align="Top" alt="If you had a java-enabled browser, you would see an applet here.">
Работа с панелями
Панели, создаваемые на базе класса Panel, являются мощным средством организации диалогового интерфейса. Так как класс Panel произошел от класса Container, панель может содержать компоненты и другие панели. Для каждой панели можно определить режим размещения компонент, что позволяет создавать достаточно сложный пользовательский интерфейс.
В окне аплета вы можете создать несколько панелей, разделяющих его на части. В свою очередь, пространство, занимаемое панелями, также может быть разделено с использованием одного из описанных выше режимов размещения (рис. 1).
Рис. 1. Размещение нескольких панелей в окне аплета
Отдельные панели могут содержать в себе такие компоненты, как кнопки, переключатели, списки, текстовые поля и так далее.
Создание панелей
Панель создается очень просто. Прежде всего необходимо выбрать для окна аплета схему размещения компонент, соответствующую требуему расположению панелей. Например, для создания в окне аплета двух панелей, разделяющих его по горизонтали, следует выбрать режим GridLayout:
setLayout(new GridLayout(2, 1));
Панели будут размещаться в ячейках таблицы, состоящей из одного столбца и двух строк.
Далее нужно создать объекты класса Panel:
Panel pTopPanel;
pTopPanel = new Panel();
Panel pBottomPanel;
pBottomPanel = new Panel();
Ссылка на панель, которая будет располагаться сверху, записывается в переменную pTopPanel, а на ту, что будет располагаться снизу - в переменную pBottomPanel.
Добавление панелей
Создав панели, вы можете добавить их в окно аплета, вызвав метод add, как это показано ниже:
add(pTopPanel);
add(pBottomPanel);
Заметим, что вы можете добавлять панели в панели, указывая, для какой панели нужно вызывать метод add:
Panel pLeft;
Panel pRight;
pLeft = new Panel();
pRight = new Panel();
pTopPanel.setLayout(new GridLayout(1, 2));
pTopPanel.add(pLeft);
pTopPanel.add(pRight);
Здесь мы создали две панели pLeft и pRight, которые по нашему замыслу должны разделить пространство панели pTopPanel на две части по вертикали. Для обеспечения вертикального размещения панелей pLeft и pRight в панели pTopPanel мы вызвали для панели pTopPanel метод setLayout. При этом мы указали, что компоненты, добавляемые в эту панель, должны размещаться в таблице, состоящей из односй строки и двух столбцов.
Затем панели pLeft и pRight были добавлены в панель pTopPanel методом add.
Добавление компонент в панели
Для добавления компонент в панель вы должны указать, для какой панели вызывается метод add, например:
Botton btn1;
Botton btn2;
btn1 = new Button();
btn2 = new Button();
pBottomPanel.add(btn1);
pBottomPanel.add(btn2);
Рисование в окне панели
Как вы знаете, для того чтобы что-нибудь нарисовать, необходимо вначале получить контекст отображения. Методу paint передается контекст отображения, связанный с окном аплета. Если в окне имеются панели, то для рисования внутри них необходимо получить контекст отображения окон панелей.
Проще всего это сделать с помощью метода getGraphics, вызвав его для объекта класса Panel:
Graphics gpDraw;
gpDraw = pDraw.getGraphics();
Здесь в переменную gpDraw мы записали ссылку на контекст отображения для панели pDraw.
Получив контекст отображения, можно приступить к рисованию. Вот, например, как можно нарисовать вокруг панели тонкую рамку:
Dimension dimAppWndDimension = pDraw.size();
gpDraw.drawRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
В этом фрагменте кода мы вначале определили размеры панели, вызвав для нее метод size, а затем при помощи метода drawRect, вызванного для контекста отображения gpDraw, нарисовали рамку.
Для установки шрифта и рисования текста в окне панели вы также должны указывать ссылку на контекст отображения вашей панели:
gpDraw.setFont(new Font("Courier", Font.PLAIN, 12));
gpDraw.drawString("Текст внутри окна панели", 10, 50);
Другой способ основан на создании собственного класса на базе класса Panel и переопределения в этом классе метода paint.
Создание нового класса на базе класса Panel
Если ваш аплет создает много панелей, техника рисования в окнах этих панелей, описанная выше, может привести к усложнению исходного текста приложения. Так как рисование в окнах панелей выполняется в методе paint класса аплета, вам придется получать контекст отображения для каждой панели.
Намного проще создать несколько дочерних классов от класса Panel, переопределив в каждом из них метод paint. В этом случае для каждой панели вы можете создать свой метода paint, которому будет автоматически передаваться контекст отображения, связанный с окном соответствующей панели.
В аплете Options, который мы рассмотрим ниже, использована именно такая методика работы с панелями.
Аплет Options
Аплет Options демонстрирует методики работы с панелями, а также с различными режимами системы Layout Manager.
В окне аплета Options мы создали три панели (рис. 2).
Рис. 2. Окно аплета Options
В верхней панели отображается текстовая строка First panel. Цвет и шрифт этой строки, а также цвет фона можно задавать при помощи второй панели, расположенной в центре окна нашего аплета.
Вторая панель представляет собой блокнот, на страницах которого находятся списки цвета фона, текста и шрифтов. С помощью кнопок нижней панели вы можете перелистывать страницы этого блокнота. На рис. 3 и 4 мы показали страницы, предназначенные для выбора цвета фона и цвета текста, соответственно.
Рис. 3. Выбор цвета фона
Рис. 4. Выбор цвета текста
Нажимая кнопки Background Color, Foreground Color и Set Font, вы можете отображать нужные вам страницы блокнота. С помощью кнопок Next и Prev можно перебирать страницы блокнота в прямом или обратном направлении, соответственно.
Исходный текст аплета Options
Исходный текст аплета Options представлен в листинге 1.
Листинг 1. Файл Options.java
import java.applet.*;
import java.awt.*;
public class Options extends Applet
{
FirstPanel pPanel1;
CardPanel pCard;
ControlPanel pControl;
public String getAppletInfo()
{
return "Name: Options";
}
public void init()
{
setLayout(new GridLayout(3, 1));
pPanel1 = new FirstPanel();
add(pPanel1);
pCard = new CardPanel(pPanel1);
add(pCard);
pControl = new ControlPanel(pCard);
add(pControl);
pPanel1.setBackground(Color.yellow);
pPanel1.setForeground(Color.black);
repaint();
}
}
class FirstPanel extends Panel
{
String szFontName = "TimesRoman";
public void paint(Graphics g)
{
Dimension dimAppWndDimension = getSize();
g.drawRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
g.setFont(new Font(szFontName, Font.PLAIN, 24));
g.drawString("First panel", 10, 50);
super.paint(g);
}
}
class CardPanel extends Panel
{
Panel pBgColor;
Panel pFgColor;
Panel pFont;
Panel pControlled;
Choice chBgColor;
Choice chFgColor;
Choice chFont;
Label lbBgColor;
Label lbFgColor;
Label lbFont;
public CardPanel(Panel pControlledPanel)
{
pControlled = pControlledPanel;
setLayout(new CardLayout(5, 5));
pBgColor = new Panel();
pFgColor = new Panel();
pFont = new Panel();
add("BgColor", pBgColor);
add("FgColor", pFgColor);
add("Font", pFont);
chBgColor = new Choice();
chFgColor = new Choice();
chFont = new Choice();
chBgColor.add("Yellow");
chBgColor.add("Green");
chBgColor.add("White");
chFgColor.add("Black");
chFgColor.add("Red");
chFgColor.add("Green");
chFont.add("TimesRoman");
chFont.add("Helvetica");
chFont.add("Courier");
lbBgColor = new Label("Background color");
lbFgColor = new Label("Foreground color");
lbFont = new Label("Font");
pBgColor.add(lbBgColor);
pBgColor.add(chBgColor);
pFgColor.add(lbFgColor);
pFgColor.add(chFgColor);
pFont.add(lbFont);
pFont.add(chFont);
}
public void paint(Graphics g)
{
Dimension dimAppWndDimension = getSize();
g.drawRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
super.paint(g);
}
public boolean action(Event evt, Object obj)
{
Choice ch;
if(evt.target instanceof Choice)
{
ch = (Choice)evt.target;
if(evt.target.equals(chBgColor))
{
if(ch.getSelectedIndex() == 0)
pControlled.setBackground(
Color.yellow);
else if(ch.getSelectedIndex() == 1)
pControlled.setBackground(
Color.green);
else if(ch.getSelectedIndex() == 2)
pControlled.setBackground(Color.white);
}
else if(evt.target.equals(chFgColor))
{
if(ch.getSelectedIndex() == 0)
pControlled.setForeground(Color.black);
else if(ch.getSelectedIndex() == 1)
pControlled.setForeground(Color.red);
else if(ch.getSelectedIndex() == 2)
pControlled.setForeground(Color.green);
}
else if(evt.target.equals(chFont))
{
if(ch.getSelectedIndex() == 0)
((FirstPanel)pControlled).szFontName = "TimesRoman";
else if(ch.getSelectedIndex() == 1)
((FirstPanel)pControlled).szFontName = "Helvetica";
else if(ch.getSelectedIndex() == 2)
((FirstPanel)pControlled).szFontName = "Courier";
}
else
{
return false;
}
pControlled.repaint();
return true;
}
return false;
}
}
class ControlPanel extends Panel
{
Button btNext;
Button btPrev;
Button btBgColor;
Button btFgColor;
Button btFont;
Panel pCard;
public ControlPanel(Panel pCardPanel)
{
pCard = pCardPanel;
setLayout(new GridLayout(2,3));
btBgColor = new Button("Background Color");
btFgColor = new Button("Foreground Color");
btFont = new Button("Set Font");
btNext = new Button("Next");
btPrev = new Button("Prev");
add(btBgColor);
add(btFgColor);
add(btFont);
add(btNext);
add(btPrev);
}
public boolean action(Event evt, Object obj)
{
if(evt.target instanceof Button)
{
if(evt.target.equals(btBgColor))
{
((CardLayout)pCard.getLayout()).show(pCard, "BgColor");
}
else if(evt.target.equals(btFgColor))
{
((CardLayout)pCard.getLayout()).show(pCard, "FgColor");
}
else if(evt.target.equals(btFont))
{
((CardLayout)pCard.getLayout()).show(pCard, "Font");
}
else if(evt.target.equals(btNext))
{
((CardLayout)pCard.getLayout()).next(pCard);
}
else if(evt.target.equals(btPrev))
{
((CardLayout)pCard.getLayout()).previous(pCard);
}
else
{
return false;
}
return true;
}
return false;
}
}
Исходный текст документа HTML, созданный для аплета Options системой Java WorkShop, представлен в листинге 2.
Листинг 2. Файл Options.tmp.phpl