Многоугольники
Для рисования многоугольников в классе Graphics предусмотрено четыре метода, два из которых рисуют незаполненные многоугольники, а два - заполненные.
Первый метод рисует незаполненный многоугольник, заданный массивами координат по осям X и Y:
public abstract void
drawPolygon(int xPoints[], int yPoints[], int nPoints);
Через параметры xPoints и yPoints передаются, соответственно, ссылки на массивы координат по оис X и Y. Параметр nPoints задает количество точек в массивах.
На рис. 3.6 показан многоугольник, нарисованный методом drawPolygon.
Рис. 3.6. Многоугольник, нарисованный методом drawPolygon
В этом многоугольнике шесть вершин с координатами от (x0,y0) до (x5, y5), причем для того чтобы он стал замкнутым,координаты первой и последней вершины совпадают.
Второй метод также рисует незаполненный многоугольник, однако в качетсве параметра методу передается ссылка на объект Polygon:
public void drawPolygon(Polygon p);
Класс Polygon достаточно прост, поэтому мы приведем его описание полностью:
public class java.awt.Polygon
extends java.lang.Object
{
// -----------------------------------------------------
// Поля класса
// -----------------------------------------------------
public int npoints; // количество вершин
public int xpoints[]; // массив координат по оси X
public int ypoints[]; // массив координат по оси Y
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
public Polygon();
public Polygon(int xpoints[], int ypoints[], int npoints);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Добавление вершины
public void addPoint(int x, int y);
// Получение координат охватывающего прямоугольника
public Rectangle getBoundingBox();
// Проверка, находится ли точка внутри многоугольника
public boolean inside(int x, int y);
}
Ниже мы показали фрагмент кода, в котором создается многоугольник, а затем в него добавляется несколько точек. Многоугольник рисуется методом drawPolygon:
Polygon p = new Polygon();
p.addPoint(270, 239);
p.addPoint(350, 230);
p.addPoint(360, 180);
p.addPoint(390, 160);
p.addPoint(340, 130);
p.addPoint(270, 239);
g.drawPolygon(p);
Если вам нужно нарисовать заполненный многоугольник (рис. 3.7), то для этого вы можете воспользоваться методами, приведенными ниже:
public abstract void
fillPolygon(int xPoints[], int yPoints[], int nPoints);
public void fillPolygon(Polygon p);
Первый из этих методов рисует многоугольник, координаты вершин которого заданы в массивах, второй - получая объект класса Polygon в качестве параметра.
Рис. 3.6. Многоугольник, нарисованный методом drawPolygon
Мобильность Java
В свое время вы слышали, что язык программирования С является мобильным в том смысле, что имеется принципиальная возможность переноса программ, составленных на этом языке, на различные платформы.
Однако следует отметить, что создание действительно многоплатформных приложений - непростая задача. К сожалению, дело не ограничивается необходимостью перекомпиляции исходного текста программы для работы в другой среде. Много проблем возникает с несовместимостью программных интерфейсов различных операционных систем и графических оболочек, реализующих пользовательский интерфейс.
Вспомните хотя бы проблемы, связанные с переносом 16-разрядных приложений Windows в 32-разрядную среду Microsoft Windows 95 и Microsoft Windows NT. Даже если вы тщательно следовали всем рекомендациям Microsoft, разрабатывая приложения так, чтобы они могли работать в будующих версиях Windows, едва ли вам удасться просто перекомпилировать исходные тексты, не изменив в них ни строчки. Ситуация еще больше ухудшается, если вам нужно, например, перенести исходные тексты приложения Windows в среду операционной системы IBM OS/2 или в оболочку X-Windows операционной системы UNIX. А ведь есть еще компьютеры Apple, рабочие станции с процессором RISC и другие!
Как нетрудно заметить, даже если стандартизовать язык программирования для всех платформ, проблемы совместимости с программным интерфейсом операционной системы значительно усложняют перенос программ на различные платформы. И, конечно, вы не можете мечтать о том, чтобы загрузочный модуль одной и той же программы мог работать без изменений в среде различных операционных систем и на различных платформах. Если программа подготовлена для процессора Intel, она ни за что не согласится работать на процессоре Alpha или каком-либо другом.
В результате создавая приложение, способное работать на различных платформах, вы вынуждены фактически создавать несколько различных приложений и сопровождать их по отдельности.
На рис. 1.1 мы показали, как приложение, изначально разработанное для Microsoft Windows NT, переносится на платформу Apple Macintosh.
Рис. 1.1. Перенос приложения с платформы Windows NT на платформу Apple Macintosh
Вначале программист готовит исходные тексты приложения для платформы Microsoft Windows NT и отлаживает их там. Для получения загрузочного модуля исходные тексты компилируются и редактируются. Полученный в результате загрузочный модуль может работать на процессоре фирмы Intel в среде операционной системы Microsoft Windows NT.
Для того чтобы перенести приложение в среду операционной системы компьютера Apple Macintosh, программист вносит необходимые изменения в исходные тексты приложения. Эти изменения необходимы из-за различий в программном интерфейсе операционной системы Microsoft Windows NT и операционной системы, установленной в Apple Macintosh. Далее эти исходные тексты транслируются и редактируются, в результате чего получается загрузочный модуль, способный работать в среде Apple Macintosh, но не способный работать в среде Microsoft Windows NT.
Программа на языке Java компилируется в двоичный модуль, состоящий из команд виртуального процессора Java. На настоящий момент созданы только первые модели физического процессора, способного выполнять эти двоичные команды, однако интерпретаторы Java имеются на всех основных компьютерных платформах. Разумеется, на каждой платформе используется свой интерпретатор, или, точнее говоря, свой виртуальный процессор Java.
Если ваше приложение Java (или аплет) должно работать на нескольких платформах, нет необходимости компилировать его исходные тексты несколько раз. Вы можете откомпилировать и отладить приложение Java на одной, наиболее удобной для вас платформе. В результате вы получите двоичный модуль, пригодный для любой платформы, где есть виртуальный процессор Java.
Сказанное иллюстрируется на рис. 1.2.
Рис. 1.2. Подготовка приложения Java для работы на разных платформах
Таким образом, приложение Java компилируется и отлаживается только один раз, что уже значительно лучше. Остается, правда, вопрос - как быть с программным интерфейсом операционной системы, который отличается для разных платформ?
Здесь разработчиками Java предлагается достаточно неплохое решение. Приложение Java не обращается напрямую к интерфейсу операционной системы. Вместо этого оно пользуется готовыми стандартными библиотеками классов, содержащими все необходимое для организации пользовательского интерфейса, обращения к файлам, для работы в сети и так далее.
Внутренняя реализация библиотек классов, разумеется, зависит от платформы. Однако все загрузочные модули, реализующие возможности этих библиотек, поставляются в готовом виде вместе с виртуальной машиной Java, поэтому программисту не нужно об этом заботиться. Для операционной системы Microsoft Windows, например, поставляются библиотеки динамической загрузки DLL, внутри которых запрятана вся функциональность стандартных классов Java.
Абстрагируясь от аппаратуры на уровне библиотек классов, программисты могут больше не заботиться о различиях в реализации программного интерфейса конкретных операционных систем. Это позволяет создавать по-настоящему мобильные приложения, не требующие при переносе на различные платформы перетрансляции и изменения исходного текста.
Еще одна проблема, возникающая при переносе программ, составленных на языке программирования С, заключается в том, что размер области памяти, занимаемой переменными стандартных типов, различный на разных платформах. Например, в среде операционной системы Microsoft Windows версии 3.1 переменная типа int в программе, составленной на С, занимает 16 бит. В среде Microsoft Windows NT этот размер составляет 32 бита.
Очевидно, что трудно составлять программу, не зная точно, сколько имеется бит в слове или в байте. При переносе программ на платформы с иной разрядностью могут возникать ошибки, которые трудно обнаружить.
В языке Java все базовые типы данных имеют фиксированную разрядность, которая не зависит от платформы. Поэтому программисты всегда знают размеры переменных в своей программе.
Наследование
С помощью ключевого слова extends вы можете унаследовать один класс (дочерний) от другого (базового).
Множественное наследование не допускается. Таким образом, для каждого дочернего класса может быть только один базовый класс. При необходимости, однако, этот дочерний класс может реализовывать произвольное количество интерфейсов.
Для ссылки на методы базового класса вы должны использовать ключевое слово super.
При необходимости вы можете вызвать в первой исполняемой строке конструктора дочернего класса конструктор базового класса (опять же с помощью ключевого слова super).
Нажатие клавиши мыши
Переопределив метод mouseDown, вы сможете отслеживать нажатия клавиши мыши. Прототип этого метода приведен ниже:
public boolean mouseDown(Event evt, int x, int y);
Через параметр evt методу передается ссылка на объект Event, с помощью которой метод может получить полную информацию о событии.
Анализируя содержимое параметров x и y, приложение может определить координаты курсора на момент возникновения события.
Заметим, что для отслеживания двойного щелчка мыши не предусмотрено никакого отдельного метода. Однако анализируя содержимое поля clickCount переменной evt, вы можете определить кратность щелчка мыши:
if(evt.clickCount > 1)
// Двойной щелчок
showStatus("Mouse Double Click");
else
// Одинарный щелчок
showStatus("Mouse Down");
Обработка событий от кнопки
Для обработки событий, создаваемых кнопками и другими компонентами, вы можете переопределить метод handleEvent, описанный нами ранее. Однако существует более простой способ.
Этот способ основан на переопределении метода action, который получает управление, когда пользователь совершает какое-либо действие с компонентом. Под действием подразумевается нажатие на кнопку, завершение ввода текстовой строки, выбор элемента из списка, изменение состояния переключателя и так далее.
Прототип метода action представлен ниже:
public boolean action(Event evt, Object obj)
{
. . .
}
В качестве первого параметра методу передается ссылка на объект класса Event, содержащий всю информацию о событии. Второй параметр представляет собой ссылку на объект, вызвавший появление события.
Как обрабатывать событие в методе action?
Прежде всего необходимо проверить, объект какого типа создал событие. Это можно сделать, например, следующим образом:
if(evt.target instanceof Button)
{
. . .
return true;
}
return false;
Здесь мы с помощью оператора instanceof проверяем, является ли объект, вызвавший появление события, объектом класса Button.
Далее, если в окне аплета имеется несколько кнопок, необходимо выполнить ветвление по ссылкам на объекты кнопок, как это показано ниже:
if(evt.target.equals(btn1))
{
. . .
}
else if(evt.target.equals(btn2))
{
. . .
}
. . .
else
{
return false;
}
return true;
Тем из вас, кто создавал приложения Windows на языке программирования С, этот фрагмент кода может напомнить длинный переключатель switch обработки сообщений Windows.
Обработка событий от списка класса List
В отличие от списка класса Choice, для выбора строки (или нескольких строк) из списка класса List, пользователь должен сделать двойной щелчок левой клавишей мыши по выделенному элементу (или элементам, если выделено несколько элементов). При этом событие можно обработать переопределенным методом action, как мы это делали для списка класса Choice.
Однако список класса List создает события не только при двойном щелчке, но и при выделении или отмены выделения элементов, сделанном пользователем одинарным щелчком клавиши мыши. Аплет может перехватывать и обрабатывать такие события, переопределив метод handleEvent. Пример такой обработки вы найдете в исходных текстах приложения ListBox.
Окна класса Frame
Ниже мы привели краткое описание класса Frame. Так как этот класс реализует интерфейс java.awt.MenuContainer, окно класса Frame может содержать меню.
public class java.awt.Frame
extends java.awt.Window
implements java.awt.MenuContainer
{
// -----------------------------------------------------
// Поля
// -----------------------------------------------------
// Различные типы курсоров
public final static int CROSSHAIR_CURSOR;
public final static int DEFAULT_CURSOR;
public final static int E_RESIZE_CURSOR;
public final static int HAND_CURSOR;
public final static int MOVE_CURSOR;
public final static int N_RESIZE_CURSOR;
public final static int NE_RESIZE_CURSOR;
public final static int NW_RESIZE_CURSOR;
public final static int S_RESIZE_CURSOR;
public final static int SE_RESIZE_CURSOR;
public final static int SW_RESIZE_CURSOR;
public final static int TEXT_CURSOR;
public final static int W_RESIZE_CURSOR;
public final static int WAIT_CURSOR;
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Создание окна без заголовка
public Frame();
// Создание окна с заголовоком
public Frame(String title);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Вызов метода createFrame
public void addNotify();
// Удаление окна и освобождение связанных с ним ресурсов
public void dispose();
// Определение типа курсора
public int getCursorType();
// Получение пиктограммы, установленной для окна
public Image getIconImage();
// Получение ссылки на главное меню
public MenuBar getMenuBar();
// Получение заголовка окна
public String getTitle();
// Определение возможности изменения
// размеров окна пользователем
public boolean isResizable();
// Получение строки параметров
protected String paramString();
// Удаление компоненты меню
public void remove(MenuComponent m);
// Установка типа курсора
public void setCursor(int cursorType);
// Установка пиктограммы
public void setIconImage(Image image);
// Установка главного меню
public void setMenuBar(MenuBar mb);
// Включение или выключение возомжности
// изменения размеров окна
public void setResizable(boolean resizable);
// Установка заголовка окна
public void setTitle(String title);
}
Для того чтобы создать свое окно на базе класса Frame, вы должны определить свой класс, унаследовав его от класса Frame следующим образом:
class MainFrameWnd extends Frame
{
. . .
public MainFrameWnd(String sTitle)
{
super(sTitle);
. . .
resize(400, 200);
}
. . .
}
Если мы будем создавать окно с заголовком, нам необходимо соответствующим образом определить конструктор класса этого окна. В частности, наш конструктор должен вызывать конструктор базового класса, передавая ему в качестве параметра строку заголовка окна. Напомним, что конструктор базового класса должен вызываться в конструкторе дочернего класса перед выполнением каких-либо других действий.
Обратите также внимание на вызов метода resize. Этот вызов необходим для задания размеров окна.
В конструкторе вы можете определить различные параметры создаваемого вами окна, например, указать форму курсора, пиктограмму, представляющую окно, задать меню, определить возможность изменения размеров окна и так далее. Мы остановимся подробнее на процедуре добавления меню к окну класса Frame, так как она требует пояснений. С изменением других характеристик окна вы справитесь самостоятельно.
При создании окна классов Frame и Dialog для них устанавливается режим размещения BorderLayout. Если вам нужен другой режим размещения, необходимо установить его явным образом.
Кроме того, созданное окно появится на экране только после вызова для него метода show.
Убрать окно с экрана вы можете методом hide. Этот метод прячет окно, но оставляет в памяти все связанные с ним ресурсы, поэтому вы сможете вновь отобразить спрятанное окно, вызвав метод show.
В отличие от метода hide, метод dispose удаляет окно и освобождает все связанные с ним ресурсы. Этот метод применяется для окончательного удаления окна с экрана и из памяти.
Еще одно замечание касается обработки операции уничтожения окна при помощи двойного щелчка левой клавиши мыши по системному меню окна или при помощи кнопки уничтожения окна, расположенной в правой части заголовка.
Когда пользователь пытается уничтожить окно класса Frame или Dialog подобным образом, возникает событие Event.WINDOW_DESTROY. Вы должны предусмотреть обработку этого события, выполняя действия, соответствующие логике работы вашего окна. Обычно окно уничтожается вызовом метода dispose, как это показано ниже:
public boolean handleEvent(Event evt)
{
if(evt.id == Event.WINDOW_DESTROY)
{
dispose();
return true;
}
else
return super.handleEvent(evt);
}
Описание исходного текста
Наиболее важными для нас являются методы init и paint.
В исходном тексте класса MouseClick мы определили поля класса с именами dimMouseCursor и ev:
Dimension dimMouseCursor;
Event ev;
Первое из них предназначено для хранения координат курсора в момент возникновения события, а второе - хранит ссылку на это событие.
В нашем аплете мы будем создавать объект класса Vector, который является массивом с динамически изменяемым размером. Этот класс имеет полное имя java.util.Vector, поэтому мы подключаем соответствующую библиотеку классов:
import java.util.*;
Наш аплет определяет несколько полей в своем классе и переопределяет несколько методов базового класса.
После того как исходный текст приложения был создан системой Java Applet Wizard, мы добавили поля для хранения ссылок на кнопки и текстовую строку для записи метки нажатой кнопки, а также добавили и изменили несколько методов.
Рассмотрим поля класса CheckBoxes и переопределенные нами методы.
Рассмотрим поля класса ChoiceList и переопределенные нами методы.
В классе ListBox мы добавили четыре поля и переопределили несколько методов.
В классе TextLabel мы определили четыре поля и несколько методов.
В классе TxtField мы определили три поля и несколько методов.
В классе TextEdit мы определили четыре поля и несколько методов.
В исходном тексте приложения Grid вы сможете разобраться саомстоятельно. Заметим только, что в методе init мы вызываем метод setLayout, передавая ему объект класса GridLayout:
setLayout(new GridLayout(3, 3));
В свою очередь, параметры конструктора объекта GridLayout определяют, что для размещения компонент будет использована таблица, состоящая из трех строк и трех столбцов.
Компоненты (кнопки) добавляются в окно аплета хорошо известным вам способом - с помощью метода add:
add(btn1);
add(btn2);
add(btn3);
add(btn4);
add(btn5);
add(btn6);
add(btn7);
add(btn8);
Как видно из рис. 6.2, таблица заполняется кнопками слева направо и сверху вниз, как это и предполагает режим компоновки GridLayout.
Все самое интересное в приложении Border происходит в методе init, поэтому мы ограничимся описанием только этого метода.
Прежде всего метод init устанавливает желтый цвет фона:
setBackground(Color.yellow);
И хотя весь фон в нашем аплете закрыт кнопками, вы можете изменить это, выбрав конструктор класса BorderLayout, допускающий задание зазора между компонентами по вертикали и горизонтали.
Далее метод init создает пять кнопок для размещения в окне аплета. Здесь тоже для вас нет ничего нового:
btn1 = new Button("Button North");
btn2 = new Button("Button East");
btn3 = new Button("Button West");
btn4 = new Button("Button South");
btn5 = new Button("Button Center");
Далее мы устанавливаем режим размещения компонент в окне контейнера, вызывая для этого метод setLayout:
setLayout(new BorderLayout());
В качестве параметра методу setLayout передается ссылка на только что созданный объект класса BorderLayout. Так как выбран конструктор класса BorderLayout без параметров, зазор между компонентами будет отсутствовать.
Добавление компонент выполняется методом add с указанием направления расположения компоненты:
add("North", btn1);
add("East", btn2);
add("West", btn3);
add("South", btn4);
add("Center", btn5);
Заметим, что нельзя размещать несколько компонент в одном и том же направлении.
Приведем описание полей и методов, определенных в нашем аплете.
В классе Notebook определено довольно много полей и переопределено несколько методов.
Как мы уже говорили, в приложении Panel2 мы создали два класса, взяв для них в качестве базового класс Panel. Имена этих классов - FirstPanel и SecondPanel. После трансляции проекта системой Microsoft Visual J++ получаются три двоичных файла с именами Panel2.class, FirstPanel.class и SecondPanel.class - по одному для каждого класса.
Рассмотрим по очереди поля и методы классов, определенных в нашем приложении.
Описание исходных текстов
Если при создании шаблона аплета с помощью системы Java Applet Wizard вы указываете, что аплету передаются параметры и определяете их список, система Java Applet Wizard организует для вас прием и хранение параметров. Поэтому обработка параметров аплета не отнимет у вас много сил.
Какие строки добавляются системой Java Applet Wizard для обработки параметров?
Описание класса List
В классе List определено два конструктора и довольно много различных методов. Ниже мы привели краткое описание класса List:
public class java.awt.List
extends java.awt.Component
{
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Конструктор без параметров
public List();
// Конструктор, позволяющий указать количество
// отображаемых строк и флаг одновременного
// выбора нескольких элементов
public List(int rows, boolean multipleSelections);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Добавление элемента в список
public void addItem(String item);
// Добавление элемента в список с указанием номера позиции
public void addItem(String item, int index);
// Вызов метода createList
public void addNotify();
// Переключение списка в режим, при котором возможно
// выбирать одновременно несколько элементов
public boolean allowsMultipleSelections();
// Удаление из списка всех элементов
public void clear();
// Определение количества элементов в списке
public int countItems();
// Удаление элемента из заданной позиции
public void delItem(int position);
// Удаление нескольких элементов
public void delItems(int start, int end);
// Отмена выделения элемента с заданной позицией
public void deselect(int index);
// Получение строки, связанной с элементом, по
// позиции этого элемента
public String getItem(int index);
// Определение количества элементов, которые
// видны в окне списка
public int getRows();
// Определение номера выделенного элемента
public int getSelectedIndex();
// Определение номеров выделенных элементов
public int[] getSelectedIndexes();
// Получение текстовой строки, связанной с
// выделенным элементом
public String getSelectedItem();
// Получение ссылки на массив строк, связанных
// с выделенными элементами
public String[] getSelectedItems();
// Определение номера элемента массива, который
// был сделан в последний раз выделенным
// с помощью метода makeVisible
public int getVisibleIndex();
// Проверка, является ли выделенной
// строка с заданным номером
public boolean isSelected(int index);
// Выполняется свертка элементов списка таким
// образом, чтобы элемент с заданным номером
// стал видимым
public void makeVisible(int index);
// Минимальные размеры области, необходимые
// для отображения списка
public Dimension minimumSize();
// Минимальные размеры области, необходимые
// для отображения списка с заданным
// количеством строк
public Dimension minimumSize(int rows);
// Получение строки параметров
protected String paramString();
// Предпочтительные размеры области, необходимые
// для отображения списка
public Dimension preferredSize();
// Предпочтительные размеры области, необходимые
// для отображения списка с заданным
// количеством строк
public Dimension preferredSize(int rows);
// Извещение об уничтожении узла
public void removeNotify();
// Замещение элемента списка с заданным номером
public void replaceItem(String newValue, int index);
// Выделение элемента с заданным номером
public void select(int index);
// Установка или сброс режима одновременного
// выделения нескольких строк
public void setMultipleSelections(boolean v);
}
Процесс создания списка класса List несложен:
List chBackgroundColor;
chBackgroundColor = new List(6, false);
При создании списка вы передаете конструктору количество одновременно отображаемых строк и флаг разрешения одновременного выбора нескольких строк. Если значение этого флага равно true, пользователь сможет выбирать из списка одновременно несколько строк, а если false - только одну строку.
Для наполнения списка вы можете использовать уже знакомый вам метод addItem:
chBackgroundColor.addItem("Yellow");
chBackgroundColor.addItem("Green");
chBackgroundColor.addItem("White");
Список класса List добавляется к окну аплета методом add:
add(chBackgroundColor);
Кратко остановимся на нескольких методах класса List.
Если вы разрешили пользователю выбирать из списка одновременно несколько элементов, то для получения ссылки на массив выбранных элементов вам пригодятся методы getSelectedItems и getSelectedIndexes:
public String[] getSelectedItems();
public int[] getSelectedIndexes();
С помощью метода setMultipleSelections вы можете динамически включать или выключать режим одновременного выбора нескольких элементов.
В некоторых случаях вам может пригодиться метод clear, удаляющий все элементы из списка:
public void clear();
Методика использования других методов очевидна из краткого описания класса List, приведенного в этом разделе.
Определение атрибутов контекста отображения
Ряд методов класса Graphics позволяет определить различные атрибуты контекста отображения, например, цвет, выбранный в контекст отображения или метрики текущего шрифта, которым выполняется рисование текста.
Рассмотрим методы, позволяющие определить атрибуты контекста отображения.
Определение цвета, выбранного в контекст отображения
Метод getColor возвращает ссылку на объект класса Color, представляющий текущий цвет, выбранный в контекст отображения:
public abstract Color getColor();
Определение границ области ограничения вывода
С помощью метода clipRect, о котором мы расскажем чуть позже, вы можете определить в окне аплета область ограничения вывода прямоугольной формы. Вне этой области рисование графических изображений и текста не выполняется.
Метод getClipRect позволяет вам определить координаты текущей области ограничения, заданной в контексте отображения:
public abstract Rectangle getClipRect();
Метод возвращает ссылку на объект класса Rectangle, который, в частности, имеет поля класса с именами x, y, height и width. В этих полях находится, соответственно, координаты верхнего левого угла, высота и ширина прямоугольной области.
Определение класса
Для создания классов вы можете использовать только ключевое слово class. Что же касается union, то это ключевое слово в Java не применяется для создания классов.
В языке программирования С++ описание класса может быть отделено от его определения. Для Java это не так - описание класса не допустимо. Все методы должны быть определены внутри определения класса.
Недопустимо определение вложенных классов.
В Java также нет шаблонов. Вы можете создавать классы только на базе других классов.
Объект класса создается при помощи ключевого слова new, однако вы не можете удалить объект явным образом, так как ключевое слово delete языка программирования С++ в Java не используется.
При определении класса вы не можете указать деструктор. Функции удаления объектов Java из памяти выполняет система сборки мусора.
Внутри одного исходного файла вы можете определить только один общедоступный класс public.
Все классы в Java наследуются от класса Object, поэтому для любого объекта вы можете использовать методы этого класса.
Определение методов
Вы не можете определять методы вне тела класса, создавая таким образом глобальные функции. Нет также возможности определения вне класса глобальных данных. Тем не менее, внутри класса можно определять статические методы и поля (с помощью ключевого слова static), которые будут играть роль глобальных методов и данных.
Пользуясь ключевыми словами static и final, вы можете определять внутри классов глобальные константы.
Если в базовом классе метод определен с ключевым словом final, его нельзя переопределить в дочернем классе, созданном на базе данного метода.
Методы не могут быть определены как inline.
Методы Java могут создавать исключения, вызванные возникновением ошибок или других событий. Все создаваемые исключения должны либо обрабатываться внутри метода, либо описываться в определении метода после ключевого слова throws.
Определение метрик текущего шрифта
Несмотря на то что вы можете заказать шрифт с заданным именем и размером, не следует надеяться, что навигатор выделит вам именно такой шрифт, какой вы попросите. Для правильного размещения текста и других изображений в окне аплета вам необходимо знать метрики реального шрифта, выбранного навигатором в контекст отображения.
Метрики текущего шрифта в контексте отображения вы можете узнать при помощи метода getFontMetrics, прототип которого приведен ниже:
public FontMetrics getFontMetrics();
Метод getFontMetrics возвращает ссылку на объект класса FontMetrics. Ниже мы привели список наиболее важных методов этого класса, предназначенных для получения отдельных параметров шрифта:
Метод | Описание | ||
public Font getFont(); | Определение шрифта, который описывается данной метрикой | ||
public int bytesWidth(
byte data[], int off, int len); | Метод возвращает ширину строки символов, расположенных в массиве байт data. Параметры off и len задают, соответственно, смещение начала строки в массиве и ее длину | ||
public int charsWidth(
char data[], int off, int len); | Метод возвращает ширину строки символов, расположенных в массиве символов data. Параметры off и len задают, соответственно, смещение начала строки в массиве и ее длину | ||
public int charWidth(
char ch); | Метод возвращает ширину заданного символа | ||
public int charWidth(
int ch); | Метод возвращает ширину заданной строки символов | ||
public int getAscent(); | Определение расстояния от базовой линии до верхней выступающей части символов | ||
public int getDescent(); | Определение расстояния от базовой линии до нижней выступающей части символов | ||
public int getLeading(); | Расстояние между строками текста | ||
public int getHeight(); | Определение полной высоты символов, выполняется по формуле:
getLeading() + getAscent() + getDescent() | ||
public int
getMaxAdvance(); | Максимальная ширина символов в шрифте | ||
public int getMaxAscent(); | Максимальное расстояние от базовой линии до верхней выступающей части символов для символов данного шрифта | ||
public int
getMaxDescent(); | Максимальное расстояние от базовой линии до нижней выступающей части символов для символов данного шрифта | ||
public int[] getWidths(); | Массив ширин первых 256 символов в шрифте | ||
public int
stringWidth(String str); | Ширина строки, передаваемой методу в качестве параметра | ||
public String toString(); | Тектовая строка, которая представляет данную метрику шрифта |
Обратите внимание на метод stringWidth, позволяющий определить ширину текстовой строки. Заметим, что без этого метода определение ширины текстовой строки было бы непростой задачей, особенно если шрифт имеет переменную ширину символов.
Для определения полной высоты строки символов вы можете воспользоваться методом getHeight.
Определение метрик заданного шрифта
Метод getFontMetrics с параметром типа Font позволяет определить метрики любого шрифта, передаваемого ему в качетсве параметра:
public abstract FontMetrics getFontMetrics(Font f);
В отличие от нее метод getFontMetrics без параметров возвращает метрики текущего шрифта, выбранного в контекст отображения.
Определение шрифта, выбранного в контекст отображения
С помощью метода getFont, возвращающего ссылку на объект класса Font, вы можете определить текущий шрифт, выбранный в контекст отображения:
public abstract Font getFont();
Особенности реализации классов в Java
Если вы умеете программировать на языке С++, у вас не возникнет никаких проблем с программированием на Java, так как эти языки очень похожи. Однако есть и некоторые отличия, которые следует учитывать. Мы приведем только краткое перечисление основных отличий. Более подробную информацию вы найдете в литературе, список которой есть в конце книги.
Отпускание клавиши мыши
При отпускании клавиши мыши управление получает метод mouseUp:
public boolean mouseUp(Event evt, int x, int y);
Анализируя параметры x и y, вы можете определить координаты точки, в которой пользователь отпустил клавишу мыши.
Овалы и круги
Для рисования окружностей и овалов вы можете воспользоваться методом drawOval:
public abstract void drawOval(int x, int y,
int width, int height);
Параметры этого методы задают координаты и размеры прямоугольника, в который вписывается рисуемый овал (рис. 3.7).
Рис. 3.7. Рисование овала
Метод fillOval предназначен для рисования заполненного овала (рис. 3.8). Назначение его параметров аналогично назначению параметров метода drawOval:
public abstract void
fillOval(int x, int y, int width, int height);
Рис. 3.7. Рисование заполненного овала
Переключатели
Аплеты Java могут создавать в своем окне переключатели двух типов: с независимой фиксацией и с зависимой фиксацией.
Переключатели с независимой фиксацией имеют прямоугольную форму и, исходя из названия, работают независимо друг от друга. Если такой переключатель находится во включенном состоянии, внутри изображения маленького квадрата появляется галочка, если в выключенном - галочка исчезает.
Обычно переключатели с независимой фиксацией используются для управления независящими друг от друга режимами или параметрами.
Переключатели с зависимой фиксацией имеют круглую форму. В каждый момент времени может быть включен только один такой переключатель из группы переключателей с фиксацией. Аплет может создавать несколько групп переключателей с зависимой фиксацией.
Переключатели с зависимой фиксацией используются для выбора из нескольких взаимоисключающих возможностей, например, для установки одного из нескольких режимов.
Перемещение курсора мыши
Когда пользователь перемещает курсор мыши над окном аплета, в процессе перемещения происходит вызов метода mouseMove:
public boolean mouseMove(Event evt, int x, int y);
Через переменные x и y передаются текущие координаты курсора мыши.
Переопределение операторов
В языке С++ вы могли переопределить операторы, такие как +, -, ++ и так далее. Язык Java не допускает такое переопределение, что сделано для упрощения программирования. Тем не менее, операторы “+” и “+=” перегружены по умолчанию для выполнения операции слияния текстовых строк класса String.
Подготовка и запуск приложения
Итак, запустите среду Microsoft Developer Studio, сделав двойной щелчок левой клавишей мыши по соответствующей пиктограмме.
Выберите из меню File строку New. На экране появится диалоговая панель New, показанная на рис. 2.1.
Рис. 2.1. Диалоговая панель New
В этой диалоговой панели вам нужно выбрать строку Project Workspace и нажать кнопку OK. Сразу влсед за этим вы увидите диалоговую панлеь New Project Workspace (рис. 2.2).
Рис. 2.2. Диалоговая панель New Project Workspace
В левой части этой диалоговой панели есть список различных типов проектов, которые можно создать. К теме нашей книги относятся проекты типа Java Workspace и Java Applet Wizard. Первый из них предназначен для ручного создания приложений и аплетов Java, второй позволяет создавать заготовки аплетов Java в полуавтоматическом режиме.
Выберите проект типа Java Workspace. В поле Location укажите каталог, в котором будут создаваться проекты, а в поле Name - имя проекта. Переключатель Java Virtual Machine должен находиться во включенном состоянии.
После заполнения диалоговой панели New Project Workspace нажмите кнопку Create. Будет создан проект, в котором пока нет ни одного исходного файла.
Далее из меню Insert среды разработки Microsoft Developer Studio выберите строку Files into Project. В поле Filename наберите имя файла hello.java и нажмите кнопку Add. На экране появится сообщение о том, что файл с указанным именем не существует. Вы, однако, можете добавить ссылку на этот файл в проект, нажав кнопку Yes.
На следующем этапе вы должны открыть папку файлов проекта, отмеченную как hello files на средней странице блокнота, расположенного в левой части окна системы разработки (рис. 2.3).
Рис. 2.3. В проект добавлен файл hello.java
Сделайте двойной щелчок по имени файла hello.java. На экране появится сообщение о том, что файла с указанным именем не существует. Для того чтобы создать его, нажмите кнопку Yes.
В правой части главного окна системы разработки появится окно редактирования, в котором вам нужно ввести исходный текст нашей программы, приведенный в листинге 2.1.
Листинг 2.1. Файл hello\hello.java
public class hello
{
public static void main(String[] args)
{
System.out.println("Hello, Java!\n");
}
}
Затем выберите из меню Build строку Execute. На экране появится сообщение о том, что запускаемый файл hello.class не существует (рис. 2.4).
Рис. 2.4. Сообщение о том, что файл hello.class не существует
Для создания файла нажмите кнопку Yes. Исходный текст программы будет откомпиллирован. Если вы ввели его правильно, сообщения об ошибках не появятся.
Затем вы увидите на экране диалоговую панель Information For Running Class, показанную на рис. 2.5.
Рис. 2.5. Диалоговая панель Information For Running Class
В поле Class file name вам нужно ввести строку hello. Это имя класса и оно должно в точности соответствовать имени класса, указанному в определении класса (листинг 2.1), а также имени файла, в котором определен класс.
Заметим, что для каждого класса типа public вы должны создавать отдельный файл. Имя этого файла должно быть таким же, что и имя класса (с учетом строчных и прописных букв), а расширение имени файла необходимо указать как class.
Указав имя класса, включите переключатель Stand-alone interpreter в поле Run project under. При этом ваша программа будет выполняться под управлением автономного интерпретатора Java jview.exe, который находится в каталоге Windows.
После того как вы нажмете кнопку OK, ваше приложение будет запущено. На короткое время вы увидите окно интерпретатора Java, в котором появится сообщение Hello, Java! (рис. 2.6).
Рис. 2.6. Окно интерпретатора Java с сообщением, выведенным нашим приложением
Не огорчайтесь, что это окно быстро исчезло - вы можете запустить программу под отладкой и наслаждаться видом окна сколько угодно, остановив работу программы после оператора вывода сообщения. Давайте попробуем сделать это.
Установите курсор на оператор System.out.println("Hello, Java!\n") и нажмите комбинацию клавиш <Ctrl+F10>. Работа программы будет остановлена в момент достижения указанной строки. На экране появится окно интерпретатора jview.exe, не содержащее пока никаких сообщений.
Далее выполняйте программу по шагам, нажимая клавишу <F10>. После первого раза в окне интерпретатора появится сообщение Hello, Java!. На второй раз приложение завершит свою работу и окно интерпретатора Java исчезнет с экрана.
Подключаемые библиотеки классов
Ниже мы кратко перечислим подлкючаемые библиотеки классов для того чтобы вы могли оценить возможности набора классов Java. Подробное описание этих классов есть в справочной системе Microsoft Visual J++ и в литературе, список которой приведен в конце книги. Мы же ограничимся описанием тех классов, которые будем использовать в наших примерах приложений.
Поля класса ButtonPress
Четыре поля класса Button с именами btn1, btn2, btn3 и btn4 предназначены для хранения ссылок на кнопки, размещенные в окне нашего аплета:
Button btn1;
Button btn2;
Button btn3;
Button btn4;
В поле sTextLabel класса String хранится строка, предназначенная для записи названия нажатой кнопки:
String sTextLabel;
Поля класса CheckBoxes
В нашем классе мы определили несколько полей, предназначенных для хранения ссылок на переключатели, группу переключателей и кнопку.
Ссылки на переключатели имеют тип Checkbox:
Checkbox chbox1;
Checkbox chbox2;
Checkbox chbox3;
Checkbox rdbox1;
Checkbox rdbox2;
Checkbox rdbox3;
Checkbox rdbox4;
Для того чтобы сгруппировать переключатели с зависимой фиксацией в группу, мы создали ссылку на объект класса CheckboxGroup:
CheckboxGroup grModeGroup;
Кроме того, нам потребуется ссылка на объект класса Button:
Button btnGet;
Поля класса ChoiceList
В нашем классе мы определили два поля для хранения ссылок на списки цвета фона и цвета изображения:
Choice chBackgroundColor;
Choice chForegroundColor;
Поля класса FrameWnd
В поле fMainFrame класса MainFrameWnd хранится ссылка на окно, которое будет создано, если пользователь нажмет кнопку “Show Frame Window”, расположенную в окне аплета. Класс MainFrameWnd создан нами на базе класса Frame.
Поля с именами btnShowFrame и btnHideFrame предназначены, соответственно, для хранения ссылок на только что указанную кнопку и кнопку “Hide Frame Window”, с помощью которой можно скрыть окно.
Поля класса KeyCode
Поле yHeight используется для хранения полной высоты символов текущего шрифта, выбранного в контекст отображения окна аплета. Эта величина нужна для определения шага свертки окна.
В поле dimAppWndDimension типа Dimension хранятся текущие размеры окна аплета.
Поля класса LineDraw
В нашем классе мы определили несколько полей, предназначенных для хранения текущих координат рисуемых линий.
В переменную dmDown класса Dimension записываются координаты курсора на момент нажатия клавиши мыши. Если пользователь нажал клавишу мыши для того чтобы приступить к рисованию линии, это будет координатами начала линии.
Когда пользователь отпускает клавишу мыши, координаты записываются в переменную dmUp.
В процессе рисования линии метод mouseDrag стирает ранее нарисованную линию и рисует новую. Координаты конца старой линии хранятся в переменной dmPrev.
Переменная bDrawing типа boolean хранит текущее состояние аплета. Когда аплет находится в состоянии рисования линии, в эту переменную записывается значение true, а когда нет - значение false.
И, наконец, переменная lines типа Vector является динамическим массивом, в котором хранятся координаты нарисованных линий.
Поля класса ListBox
В нашем классе мы определили два поля для хранения ссылок на списки цвета фона и цвета изображения, а также две строки для хранения названий выбираемых цветов:
List chBackgroundColor;
List chForegroundColor;
String sSelBackground = new String("Yellow");
String sSelForeground = new String("Black");
Содержимое строк sSelBackground и sSelForeground изменяется в процессе выделения пользователем различных строк списков.
Поля класса MainFrameWnd
В поле btnOK хранится ссылка на кнопку, при нажатии которой окно удаляется.
Поле mbMainMenuBar класса MenuBar предназначено для хранения ссылки на главное меню окна. В него мы будем добавлять меню “File” и “Help”, идентификаторы которых хранятся в полях mnFile и mnHelp, соответственно.
Поля класса MessageBox
Внутри диалоговой панели мы расположили текстовое поле класса Label, предназначенное для отображения сообщения, и кнопку с надписью OK, с помощью которой можно завершить работу диалоговой панели.
Ссылка на текстовое поле хранится в поле lbMsg, на кнопку - в поле btnOK.
Поля класса Notebook
В полях pDraw, pCardPanel и pButtonPanel находятся ссылки, соответственно, на верхнюю, среднюю и нижнюю панели, предназначенные для рисования, размещения блокнота диалоговых панелей настроек и кнопок управления блокнотом.
В предыдущем приложении на страницах блокнота размещались кнопки. Теперь мы решили более сложную задачу - поместили на страницы блокнота три панели, по одной на каждую страницу. Первая из этих панелей содержит список для выбора цвета фона, вторая - для выбора цвета изображения и, наконец, третья, для выбора шрифта. Поля pBackgroundColor, pForegroundColor и pFont хранят ссылки на соответствующие панели настроек.
Нижняя панель содержит кнопки управления страницами блокнота. С помощью кнопок, ссылки на которые хранятся в полях btnBackgroundColor, btnForegroundColor и btnFont вы можете выбирать для отображения страницы блокнота, содержащие панели настройки цвета фона, изображения и шрифта. Таким образом, нет необходимости перебирать страницы блокнота по очереди до тех пор, пока в окне не появится нужная страница. Тем не менее, мы предусмотрели кнопки и для циклического перебора страниц блокнота. Ссылки на эти кнопки хранятся в полях btnNext и btnPrev.
На каждой панели в блокноте размещается один список и одна надпись, объясняющая назначение списка. Списки создаются как объекты класса Choice, а надписи - как объекты класса Label.
Поля chBackgroundColor, chForegroundColor и chFont хранят ссылки на списки, соответственно, цвета фона, цвета изображения и шрифтов. В полях tBackgroundColor, tForegroundColor и tFont хранятся ссылки надписей.
Поле sFontName класса String предназначено для хранения названия текущего шрифта, с использованием которого отображается текст в верхней панели.
В классе Panel2 определено два
В классе Panel2 определено два поля с именами pPanel1 и pPanel2 класса Panel. Первое из них предназначено для хранения ссылки на верхюю панель, второе - на нижнюю (в соответствии с их расположением в окне аплета).
Поля класса PanelDemo
В поле pCardPanel хранится ссылка на панель блокнота, страницы которого содержать кнопки. Эта панель располагается в верхней части окна аплета.
Поле pButtonPanel предназначено для хранения ссылки на панель кнопок, предназначенных для перелистывания страниц блокнота pCardPanel.
Ссылки на кнопки, расположенные на страницах блокнота, хранятся в полях btn1, btn2, btn3, btn4 и btn5.
Ссылки на кнопки, предназначенные для перелистывания страниц блокнота, записываются в поля btnNext и btnPrev (соответственно, кнопка пролистывания блокнота в прямом и обратном направлении).
В поле sTextLabel хранится название нажатой кнопки. Это название отображается в строке состояния навигатора, когда пользователь нажимает какую-либо кнопку в верхней или нижней панели.
Поля класса TextLabel
Мы определили четыре поля - lbTextLabel, btnLeft, btnCenter и btnRight:
Label lbTextLabel;
Button btnLeft;
Button btnCenter;
Button btnRight;
Первое из них предназначено для хранения ссылки на объект класса Label (однострочное текстовое поле), остальные три - для хранения ссылок на кнопки, определяющие выравнивание.
Поля класса TextOut
Прежде всего, создаются поля класса для хранения значений параметров:
private String m_Str1 = "Hello 1";
. . .
private String m_Str5 = "Hello 5";
private String m_Font1 = "Arial";
. . .
private String m_Font5 = "Undefined";
private String m_Type1 = "Bold";
private String m_Type2 = "Italic";
private String m_Type3 = "Plain";
Поля инициализируются значениями по умолчанию, которые вы ввели при заполнении таблицы, показанной на рис. 3.13.
Далее в классе определяются поля с названиями параметров:
private final String PARAM_Str1 = "Str1";
. . .
private final String PARAM_Str5 = "Str5";
private final String PARAM_Font1 = "Font1";
. . .
private final String PARAM_Font5 = "Font5";
private final String PARAM_Type1 = "Type1";
private final String PARAM_Type2 = "Type2";
private final String PARAM_Type3 = "Type3";
Названия параметров будут нужны для извлечения значений параметров методом getParameter класса Applet.
Поля класса TxtField
В поле txt хранится ссылка на объект класса TextField - наше однострочное поле редактирования:
TextField txt;
В полях btnGetText и str хрянятся, соответственно, ссылки на кнопку и текстовую строку, в которую записывается текущее содержимое поля редактирования:
Button btnGetText;
String str;
В поле txt хранится ссылка на объект класса TextArea - многострочное поле редактирования:
TextArea txt;
В полях btnGetText, btnGetSelectedText и str хрянятся, соответственно, ссылки на кнопки и текстовую строку, в которую записывается текущее содержимое поля редактирования:
Button btnGetText;
Button btnGetSelectedText;
String str;
Полотно для рисования
Проще всего представить себе контекст отображения как полотно, на котором рисует художник. Точно так же как художник может выбирать для рисования различные инструменты, программист, создающий аплет Java, может выбирать различные методы класса Graphics и задавать различные атрибуты контекста отображения.
Приложение Border
В приложении Border создается пять кнопок, которые размещаются в режиме BorderLayout (рис. 6.3).
Рис. 6.3. Окно аплета Border
Заметьте, что в процессе размещения северная и южная кнопка (верхняя и нижняя на нашем рисунке) заняли по ширине все окно аплета. Высота же этих кнопок была установлена достаточной для размещения одной строки текста.
Восточная и западная кнопка (левая и правая) имеют ширину, достаточную для размещения текста, и высоту, равную высоте области, которая осталась от сервеной и южной кнопок.
Для центральной кнопки было выделено все оставшееся пространство в центре окна аплета.
Приложение ButtonPress
В окне приложения ButtonPress мы создаем четыре кнопки с названиями от Button 1 до Button 4. Когда пользователь нажимает на одну из кнопок, название нажатой кнопки отображается в окне аплета и в строке состояния навигатора (рис. 5.3).
Рис. 5.3. Кнопки в окне аплета ButtonPress
Обратите внимание на расположение кнопок. По мере добавления, кнопки располагаются по горизонтали справа налево и центрируются в окне аплета. Если бы ширины окна аплета не хватило для размещения четырех кнопок, не поместившиеся кнопки были бы нарисованы ниже. Такую стратегию размещения выбирает по умолчанию система Layout Manager класса Panel, от которого, как вы знаете, произошел класс Applet.
Приложение CheckBoxes
Для демонстрации методов работы с различными переключателями мы подготовили приложение CheckBoxes. Окно соответствующего аплета показано на рис. 5.4.
Рис. 5.4. Окно аплета CheckBoxes с переключателями и кнопкой
В верхней части окна располагаются четыре переключателя с зависимой фиксацией, принадлежащих к одной группе. Ниже находятся три переключателя с независимой фиксацией, а еще ниже - кнопка с надписью Get CheckBoxes state. Нажав на эту кнопку, вы можете увидеть в нижней части окна аплета список включенных переключателей.
Одновременно может быть включен только один из переключателей Mode1 - Mode 4, так как эти переключатели составляют группу переключателей с зависимой фиксацией. Переключатели Switch 1, Switch 2 и Switch 3 могут находиться в произвольном состоянии независимо друг от друга.
Заметим, что переключатели и кнопка размещались в окне аплета автоматически по мере добавления. Если бы мы добавляли эти компоненты в другой последовательности или если бы окно аплета имело другие размеры, то переключатели могли бы не оказаться сгруппированными, как это показано на рис. 5.4. Позже в этой главе мы научим вас настраивать систему Layout Manager таким образом, чтобы вы смогли располагать компоненты в заданном вами порядке с предсказуемым результатом.
Приложение ChoiceList
В прложении ChoiceList мы создали два списка, первый из которых управляет цветом фона окна аплета, а второй - цветом изображения, то есть цветом, которым рисуется изображение в этом окне (рис. 5.7).
Рис. 5.7. Окно аплета ChoiceList, в котором создано два списка класса Choice
Пользоваться этим аплетом очень просто - выбирайте из левого списка цвет фона, а из правого - цвет изображения, при этом следите за цветом, которым нарисована текстовая строка и рамка вокруг окна аплета.
Приложение FontList
Наше следующее приложение отображает список шрифтов, доступных в системе. Окно аплета этого приложения, запущенного в среде Microsoft Internet Explorer, работающего в Microsoft Windows NT версии 4.0, показано на рис. 3.10.
Рис. 3.10. Окно аплета со списком доступных шрифтов
Возможно, этот список покажется вам несколько необычным. В самом деле, давайте заглянем в папку Fonts, которую можно найти в папке Control Panel. Беглого взгляда достаточно для того, чтобы убедиться - список шрифтов, доступных аплету, не совпадает со списком шрифтов, установленных в системе (рис. 3.11).
Рис. 3.11. Список шрифтов, установленных в системе Microsoft Windows NT
Задавая имена шрифтов в конструкторе класса Font, вы должны использовать имена шрифтов, доступные аплету, а не имена шрифтов, установленных в системе. Наш аплет FontList извлекает и отображает список доступных для него шрифтов.
Приложение FrameWnd
В приложении FrameWnd мы демонстрируем создание окон, меню и диалоговых панелей на базе классов, описанных в этой главе.
В окне аплета FrameWnd расположены две кнопки с названиями Show Frame Window и Hide Frame Window. Первая из них предназначена для отображения окна Main Frame Window, а вторая - для его временного удаления (скрытия).
В окне Main Frame Window мы создали главное меню, содержащее меню File и Help. При выборе любой строки из этого меню, кроме строки Exit меню File, на экране появляется окно диалоговой панели Dialog from Frame с названием выбранной строки меню (рис. 8.2).
Рис. 8.2. Окно и диалоговая панель, создаваемая аплетом FrameWnd
Помимо меню, в окне Main Frame Window находится кнопка OK, нажатие на которую вызывает удаление окна. Кроме того, в нижней части окна отображается строка “Окно класса Frame”.
В окне диалоговой панели, разделенном по вертикали на две части, находится текстовое поле для отображения сообщения и кнопка для завершения работы диалоговой панели.
Обратите также внимание на то, что в самой нижней части окно Main Frame Window и Dialog from Frame находится предупреждающее сообщение “Warning: Applet Window”. Это предупреждение пользователю, что данное окно или диалоговая панель выведена не локальным приложением, запущенным на компьютере пользователя, а аплетом, загруженным из сети. Пользователь должен понимать, что данные, введенные им в окнах, созданных аплетами, передаются по сети и могут оказаться доступной кому угодно. Поэтому он не должен вводить конфиденциальную информацию, например, номера своих кредитных карточек.
Приложение Grid
Приложение Grid демонстрирует использование режима размещения компонент GridLayout. В окне аплета мы создали таблицу размером 3х3, разместив в ее ячейках восемь кнопок (рис. 6.2).
Рис. 6.2. Окно приложения Grid
Обратите внимание, что все кнопки в окне аплета имеют одинаковый размер. Если вы станете нажимать на них, в строке состояния навигатора будет появляться название нажатой кнопки (на рис. 6.2 не показано).
Приложение Hello
Как мы уже говорили, приложения Java могут выполняться под управлением специального интерпретатора, работающего в рамках отдельного процесса, либо под управлением навигатора Internet, такого как Microsoft Internet Explorer или Netscape Navigator. В последнем случае приложение называется аплетом.
Первое приложение, которое мы рассмотрим, относится к простым приложениям, второе будет аплетом, встроенным в документ HTML.
Приложение KeyCode
Для демонстрации методов обработки клавиатурных событий мы подготовили аплет KeyCode. В его окне отображаются символы, соответствующие нажимаемым клавишам, код соответствующих клавиш и коды модификации (рис. 4.4).
Рис. 4.4. Окно аплета KeyCode
Аплет KeyCode интересен тем, что в процессе отображения новые строки появляются в верхней части окна, а старые сдвигаются вниз после отпускания клавиши. Таким образом, мы организовали свертку в окне аплета.
Прежде чем нажимать клавиши, вы должны передать фокус вода окну аплета. Это можно сделать, щелкнув в окне левой клавишей мыши. Фокус ввода - это атрибут, который присваивается окну, обрабатывающему ввод от клавиатуры. Так как клавиатура одна, а аплетов и других активных окон на экране может быть много, необходим механизм, позволяющий определить, в какое окно направялются события, создаваемые клавиатурой. Такой механизм и обеспечивается атрибутом фокуса ввода.
Приложение LineDraw
Следующее приложение тоже работает с мышью. В его окне вы можете рисовать прямые линии черного цвета (рис. 4.3).
Рис. 4.3. Аплет, в окне которого можно рисовать прямые линии
Для того чтобы нарисовать линию в окне аплета LineDraw, вы должны установить курсор в начальную точку, нажать клавишу мыши и затем, не отпуская ее, переместить курсор в конечную точку. После отпускания клавиши мыши координаты линии будут сохранены аплетом в массиве, после чего произойдет перерисовка окна аплета.
По мере того как вы будете рисовать линии, аплет будет заполнять массив с координатами линий. Каждый раз, когда окно аплета будет перерисовываться, метод paint перерисует все линии заново, пользуясь координатами, сохраненными в массиве.
Для того чтобы стереть содержимое окна аплета, вам достаточно сделать двойной щелчок в его окне. При этом из массива координать линий будут удалены все элементы.
Приложение ListBox
В окне приложения ListBox мы создали два списка класса List, первый из которых предназначен для выбора цвета фона, а второй - для выбора цвета изображения. Размер первого списка достаточен для отображения всех добавленных в него элементов. Размер второго списка специально сделан меньше, поэтому справа от него появилась полоса просмотра (рис. 5.10).
Рис. 5.10. Окно приложения ListBox
Если вы будете выделять различные строки списков одинарным щелчком клавиши мыши, в нижней части окна и строке состояния навигатора (на рисунке не показана) появятся названия выделенных цветов. Таким образом, аплет отслеживает выделение элементов этих двух списков, отображая связанные с ним текстовые строки.
В том случае, если вы сделаете двойной щелчок мышью внутри одного из списков, соответствующим образом изменится цвет фона или цвет изображения (текстовых строк и рамки вокруг окна аплета).
Приложение MouseClick
Аплет MouseClick демонстрирует обработку событий, поступающих от мыши.
Когда мы создавали проект этого аплета, то в третьей диалоговой панели системы Java Applet Wizard включили три переключателя в поле Which mouse event handlers would you like added (рис. 4.1).
Рис. 4.1. Включение обработчиков событий от мыши
В результате в исходный текст приложения были добавлены перечисленные выше методы, обрабатывающие события, создаваемые мышью.
Мы изменили эти методы таким образом, чтобы в ответ на различные действия, выполняемые пользователем с помощью мыши, аплет реагировал соответствующим образом:
Действие пользователя | Реакция аплета | ||
Перемещение курсора мыши при отжатой клавише | Игнорирование | ||
Перемещение курсора мыши при нажатой клавише | В строку состояния записывается текстовая строка Mouse Drag | ||
Нажатие клавиши мыши | В месте расположения курсора выводятся текущие координаты курсора мыши. Дополнительно в строку состояния записывается текстовая строка Mouse Down | ||
Отжатие клавиши мыши | В строку состояния записывается текстовая строка Mouse Up | ||
Курсор мыши входит в область окна аплета | В строку состояния записывается текстовая строка Mouse pointer enters applet's window | ||
Курсор мыши выходит из области окна аплета | В строку состояния записывается текстовая строка Mouse pointer leaves applet's window |
Внешний вид окна аплета, в котором отображаются координаты курсора, показан на рис. 4.2.
Рис. 4.2. Внешний вид окна аплета MouseClick, в котором отображаются координаты курсора
Приложение Notebook
Приложение Notebook служит в качестве более сложного примера техники работы с панелями.
В окне аплета Notebook создаются три панели, расположенные в одном столбце. В верхней панели, имеющей рамку по периметру, рисуется строка текста “Смотри на шрифт, цвет фона и текста!”. Средняя панель представляет собой блокнот, предназначенный для выбора цвета фона, цвета изображения и шрифта для верхней панели. И, наконец, нижняя панель содержит кнопки, позволяющие перелистывать страницы блокнота.
На рис. 7.4 показана страница, предназанченная для выбора цвета фона:
Рис. 7.4. Страница, предназанченная для выбора цвета фона
Нажимая кнопки Background Color, Foreground Color и Set Text Font, вы сможете выдвигать на передний план страницы блокнота, предназначенные, соответственно, для выбора цвета фона, изображения и шрифта, которым отображается текст в верхней панели.
Кнопки Next и Prev работают таким же образом, что и в предыдущем приложении, а именно: если нажать на кнопку Next, произойдет пролистывание страниц в прямом направлении, а если на кнопку Prev - в обратном направлении.
На рис. 7.5 изображена страница блокнота, предназначенная для выбора цвета изображения.
Рис. 7.5. Страница, предназанченная для выбора цвета изображения
На рис. 7.6 представлена страница, с помощью которой можно выбрать один из нескольких шрифтов для рисования текста в верхней панели.
Рис. 7.6. Страница, предназанченная для выбора шрифта
Рассмотрим исходные тексты приложения Notebook/
Приложение Painter
В этом разделе мы рассмотрим исходные тексты аплета Painter, в которых демонстрируется использование большинства только что описанных нами функций рисования.
Внешний вид окна аплета при просмотре соответствующего документа HTML навигатором Microsoft Internet Explorer показано на рис. 3.9.
Рис. 3.9. Окно аплета Painter
Здесь мы написали текстовую строку, нарисовали несколько горизонтальных линий, скопировав это линии в другое место окна, а также изобразили несколько простейших геометрических фигур.
В окне аплета Panel2 мы
В окне аплета Panel2 мы создали две панели, одна из которых занимает верхнюю половину окна, а другая - нижнюю (рис. 7.7).
Рис. 7.7. Окно аплета Panel2 с двумя панелями
Для каждой панели мы создали два отдельных класса на базе класса Panel. В созданных нами классах переопределен метод paint, который рисует одну текстовую строку в окне своей панели. В верхней панели рисуется строка “Первая панель”, в нижней - “Вторая панель”.
Кроме того, метод paint класса нашего аплета рисует две строки в окнах обеих панелей, получая контекст отображения для панелей и указывая ссылку на этот контекст явным образом.
В процессе инициализации метод init класса нашего аплета устанавливает различный цвет фона и изображения для панелей, поэтому рамки вокруг окон панелей и текст получаются нарисованными различным цветом независимо от способа их рисования.
Приложение PanelDemo
В приложении PanelDemo мы создаем две панели, расположенные горизонтально. Первая из них используется как блокнот, на каждой странице которого находится кнопка, вторая содержит две управляющие кнопки, позволяющие перебирать страницы блокнота по очереди (рис. 7.2).
Рис. 7.2. Окно аплета PanelDemo
Объемное изображение схемы расположения панелей и кнопок относительно окна аплета показано на рис. 7.3.
Рис. 7.3. Объемное изображение схемы расположения панелей и кнопок
В верхней панели друг над другом располагаются пять кнопок (как колода карт), причем видна только одна из них. В нижней панели только две кнопки, с помощью которых можно выдвигать на передний план по очереди все кнопки из верхней панели.
Нажимая на кнопки Next и Prev, попробуйте понажимать на кнопки в верхней панели. В строке состояния навигатора при этом будет отображаться название нажатой кнопки (на рис. 6.5 это не показано).
Приложение TextEdit
Приложение TextEdit (рис. 5.13) демонстрирует некоторые приемы работы с многострочным полем редактирования текста, созданным на базе класса TextArea.
Рис. 5.13. Окно приложения TextEdit
В окне редактирования вы можете вводить строки текста. Если нажать на кнопку “Получить все”, в нижней части окна отобразится полное содержимое окна редактирования. Каждая строка будет отделена символом перехода на новую строку.
Если же нажать кнопку “Получить выделенное”, в нижней части появится только выделенный фрагмент текста (как это показано на рис. 5.13).
Приложение TextLabel
В окне приложения TextLabel, демонстрирующего способы работы с полями класса Label, мы разместили одно такое поле и три кнопки, позволяющие изменять выравнивание текста в поле (рис. 5.11).
Рис. 5.11. Окно приложения TextLabel
Нажимая кнопки, вы можете заметить, как строка, расположенная под ними, немного сдвигается по горизонтали.
Приложение TextOut
До сих пор наши аплеты не получали параметров из документов HTML, в которые мы их встраивали. Конечно, все константы, текстовые строки, адреса URL и другую информацию можно закодировать непосредственно в исходном тексте аплета, однако, очевидно, это очень неудобно.
Пользуясь операторами <PARAM>, расположенными в документе HTML сразу после оператора <APPLET>, можно передать аплету произвольное количество параметров, например, в виде текстовых строк:
<applet
code=TextOut.class
id=TextOut
width=320
height=240 >
<param name=ParamName1 value="Param Value 1">
<param name=ParamName2 value="Param Value 2">
<param name=ParamName3 value="Param Value 3">
<param name=ParamName4 value="Param Value 4">
. . .
</applet>
Здесь через параметр NAME оператора <PARAM> передается имя параметра аплета, а через параметр VALUE - значение соответствующего параметра.
Как параметр может получить значение параметров?
Для получения значения любого параметра аплет должен использовать метод getParameter. В качестве единственного параметра этому методу передается имя параметра аплета в виде строки типа String, например:
private String m_ParamName1;
private final String PARAM_ ParamName1= "ParamName1";
String param;
param = getParameter(PARAM_ParamName1);
if (param != null)
m_ParamName1 = param;
Если вы создаете аплет с помощью системы Java Applet Wizard, то в четвертой диалоговой панели вам предоставляется возможность определить все параметры, передаваемые аплету (рис. 3.12).
Рис. 3.12. Определение параметров аплета (список параметров уже заполнен)
Первоначально список параметров, отображаемых в четвертой диалоговой панели системы Java Applet Wizard, пуст. Такую панель мы показывали раньше на рис. 2.11.
Для добавления нового параметра сделайте щелчок левой клавишей мыши в столбце Name по свободному полю, отмеченному пунктирным прямоугольником. На месте этого прямоугольника появится поле редактирования, в котором вы должны ввести имя параметра. После ввода сделайте щелчок вне поля, после чего в списке параметров появится новая строка.
Создавая проект TextOut, мы выполнили эту операцию для всех параметров, за исключением параметра Font4. Этот параметр мы добавили позже в ручном режиме, когда все файлы проекта уже были созданы.
Обратите внимание, что в столбце Member при заполнении списка автоматически появляются имена полей класса, в которые попадут значения параметров.
После завершения формирования списка параметров мы заполнили столбцы Def-Value и Description (рис. 3.13).
Рис. 3.13. Заполнение столбцов Def-Value и Description
Значения из столбца Def-Value будут использованы для инициализации соответствующих полей класса. Что же касается столбца описаний Description, о эта информация может быть извлечена аплетом и проанализирована. Если в документе HTML находится несколько аплетов (что вполне допустимо), другие аплеты также могут получить описание параметров нашего аплета.
Какие параметры получает наш аплет и что он делает, кроме получения значения параметров?
Через параметры с именами Str1 - Str5 передается пять строк, который аплет отображает в своем окне (рис. 3.14).
Рис. 3.14. Отображение строк в окне аплета TextOut
Параметры Font1 - Font5 задают имена шрифтов для отображения этих строк. С помощью параметра Type1 можно задать стиль шрифта первой и второй строки, с помощью параметра Type2 - третьей и четвертой, а с помощью параметра Type3 - стиль шрифта для пятой строки.
Рассмотрим исходный тексты приложения TextOut.
Приложение TxtField
В приложении TxtField мы создали однострочное поле редактирования на базе класса TextField и кнопку, с помощью которой можно извлечь текст из поля для отображения (рис. 5.12).
Рис. 5.12. Окно аплета TxtField
Изменив текст в поле редактирования, нажмите кнопку “Получить строку”. В нижней части окна аплета вы увидите измененный вами текст.
Прямоугольники и квадраты
Среди методов класса Graphics есть несколько, предназначенных для рисования прямоугольников. Первый из них, с именем drawRect, позволяет нарисовать прямоугольник, заданный координатами своего левого вернего угла, шириной и высотой:
public void drawRect(int x, int y,
int width, int height);
Параметры x и y задают, соответственно, координаты верхнего левого угла, а параметры width и height - высоту и ширину прямоугольника (рис. 3.2).
Рис. 3.2. Рисование прямоугольника
В отличие от метода drawRect, рисующего только прямоугольную рамку, метод fillRect рисует заполненный прямоугольник. Для рисования и заполнения прямоугольника используется цвет, выбранный в контекст отображения (рис. 3.3).
Прототип метода fillRect приведен ниже:
public abstract void
fillRect(int x, int y, int width, int height);
Рис. 3.3. Рисование заполненного прямоугольника
Метод drawRoundRect позволяет нарисовать прямоугольник с закругленными углами:
public abstract void
drawRoundRect(int x, int y, int width,
int height, int arcWidth, int arcHeight);
Параметры x и y определяют координаты верхнего левого угла прямоугольника, параметры width и height задают, соответственно его ширину и высоту.
Размеры эллипса, образующего закругления по углам, вы можете задать с помощью параметров arcWidth и arcHeight. Первый из них задает ширину эллипса, а второй - высоту (рис. 3.4).
Рис. 3.4. Рисование прямоугольника с закругленными углами
Метод fillRoundRect позволяет нарисовать заполненный прямоугольник с закругленными углами (рис. 3.5). Назначение параметров этого метода аналогично назначению параметров только что рассмотренного метода drawRoundRect:
public abstract void
fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight);
Рис. 3.5. Рисование заполненного прямоугольника с закругленными углами
Метод fill3Drect предназначен для рисования выступающего или западающего прямоугольника:
public void
fill3DRect(int x, int y, int width,
int height, boolean raised);
Если значение параметра raised равно true, рисуется выступающий прямоугольник, если false - западающий. Назначение остальных параметров аналогично назначению параметров метода drawRect.
Простейший аплет
Аплетами называются приложения Java, которые выполняются под управлением виртуальной машины Java, встроенной в навигатор, такой как Microsoft Internet Explorer или Netscape Navigator. Аплет встраивается в документ HTML и выглядит как окно заранее заданного размера. Он может рисовать в своем окне (и только в нем) произвольные изображения или текст.
Двоичный файл с исполняемым (а точнее говоря, интерпретируемым) кодом Java располагается на сервере WWW. В документе HTML с помощью оператора <APPLET> организуется ссылка на этот двоичный файл.
Когда пользователь загружает в навигатор документ HTML с аплетом, файл аплета переписывается с сервера WWW на рабочую станцию пользователя. После этого навигатор начинает его выполнение.
Возможно, вам не понравится такая идея, как запуск чужого аплета на своем компьютере - мало ли чего этот аплет может там сделать. Однако аплеты, в отличие от обычных приложений Java, сильно ограничены в своих правах. Например, они не могут читать локальные файлы и тем более в них писать. Есть также ограничения и на передачу данных через сеть: аплет может передавать данные только тому серверу WWW, с которого он загружен. В крайнем случае вы можете совсем отказаться от использования аплетов, отключив возможность их загрузки соответствующей настройкой навигатора. Но мы пока не будем этого делать, так как аплеты являются предметом изучения в нашей книге.
Давайте создадим простейший аплет, воспользовавшись для этого системой автоматизированной разработки шаблонов аплета Java Applet Wizard, встроенной в Microsoft Visual J++.
Запустите систему Microsoft Visual J++ и выберите из меню File строку New. В появившейся на экране диалоговой панели New выберите строку New Project Workspace. Затем вам нужно выбрать тип проекта Java Applet Wizard, как это показано на рис. 2.7.
Рис. 2.7. Выбор типа проекта Java Applet Wizard
В поле Name введите имя приложения HelloAp, а в каталоге Location укажите путь к каталогу, в котором будут созданы файлы проекта. Затем нажмите кнопку Create. Вслед за этим на экране появится по очереди несколько диалоговых панелей, в которых вы должны описать создаваемый аплет.
Первая такая диалоговая панель показана на рис. 2.8.
Рис. 2.8. Выбор типа приложения, названия класса и степени подробности создаваемых комментариев к исходному тексту
В поле How would you like to be able to run your program включите переключатель As an applet only. При этом создаваемое приложение сможет работать только под управлением навигатора.
Имя класса аплета нужно указать в поле What would you like to name your applet class. Оставьте имя HelloAp, которое там есть по умолчанию.
Состояние переключателей в поле Would you like to generate source file comments влияет на то, насколько подробно будут комментироваться создаваемый исходный текст приложения, и будет ли он комментироваться вообще.
Если включить переключатель Yes, please, в исходный текст будут добавлены комментарии. Если же включить переключатель No, thank you, никаких комментариев не будет.
При включении переключателя Explanatory comments в исходный текст будут включены комментарии, объясняющие назначение отдельных фрагментов кода. Переключатель TODO влияет на то, будут ли отмечены места исходного текста, в который вы должны вставить свой код, наполняющий аплет реальной жизнью.
Завершив заполнение первой диалоговой панели, нажмите кнопку Next и переходите к следующей панели, показанной на рис. 2.9.
Рис. 2.9. Запрос на создание документа HTML и определение размера окна аплета
Система Java Applet Wizard может создать для вас образец документа HTML, в который будет включен разрабатываемый вами аплет. Для этого во второй диалоговой панели вы должны включить переключатель Yes, please, расположенный в поле Would you like a sample HTML file.
Начальные размеры окна, создаваемого в документе HTML для аплета, определяются в полях Width in pixels и Height in pixels (соответственно, ширина и высота). Заметим, что аплет может изменять размеры своего окна, о чем мы еще будем говорить.
Третья диалоговая панель показана на рис. 2.10.
Рис. 2.10. Вопросы, связанные с мультизадачностью, анимацией и обработкой сообщений от мыши
В этой панели вы должны указать, будет ли ваш аплет создавать задачи. Наш первый аплет однозадачный, поэтому в поле Would you like your applet to be multi-threaded вы должны вклюить переключатель No, thank you.
На вопрос Would you like support for animation вы сможете ответить утвердительно только в том случае, если ваш аплет мультизадачный.
Три переключателя, расположенные в поле Which mouse event handlers would you like added, позволят вам автоматически добавить обработчики сообщений от мыши. Пока не включайте их, так как мышью мы займемся позже.
Следующая, четвертая диалоговая панель показана на рис. 2.11.
Рис. 2.11. Определение параметров, передаваемых аплету
С помощью этой диалоговой панели вы можете указать, какие параметры должны передаваться аплету через документ HTML при запуске. Нажмите здесь кнопку Next, не добавляя никаких параметров.
В пятой диалоговой панели (рис. 2.12) вам дается возможность отредактировать информацию, описывающую ваш аплет.
Рис. 2.12. Редактирование информации, описывающей аплет
Эта информация будет возвращаться методом getAppInfo, определенным в классе аплета. При необходимости измените строки описания и нажмите кнопку Next.
Финальная диалоговая панель показана на рис. 2.13.
Рис. 2.13. Финальная диалоговая панель
Здесь вы можете последний раз перед созданием файлов проекта посмотреть на заданные вами параметры. Если нажать кнопку OK, проект будет создан. Для отказа от создания проекта нажмите кнопку Cancel.
В результате работы системы Java Applet Wizard будет создано два файла (не считая файла проекта). Это исходный текст аплета HelloAp.java (листинг 2.2) и исходный текст документа HTML HelloAp.html, в который включен создаваемый аплет (листинг 2.3).
Листинг 2.2. Файл HelloAp\HelloAp.java (комментарии переведены на русский язык)
//**********************************************************
// HelloAp.java: Applet
//
//**********************************************************
import java.applet.*;
import java.awt.*;
//==========================================================
// Основной класс для аплета HelloAp
//
//==========================================================
public class HelloAp extends Applet
{
// Конструктор класса HelloAp
//---------------------------------------------------
public HelloAp()
{
// Сделать: Добавьте сюда код конструктора
}
// Обеспечение информации об аплете:
//
// Метод getAppletInfo возвращает строку, которая
// описывает аплет. Вы можете приведсти такую информацию,
// как имя автора и дата создания, а так же любые другие
// сведения об аплете
//------------------------------------------------------
public String getAppletInfo()
{
return "Name: HelloAp\r\n" +
"Author: Alexandr Frolov\r\n" +
"Created with Microsoft Visual J++ Version 1.0";
}
// Метод init вызывается системой AWT при первой загрузке
// или перезагрузке аплета. Вы можете переопределить этот
// метод для выполнения еобходимой инициализации аплета,
// например, инициализации структур данных, загрузку
// изображений или шрифтов, создание окон фреймов,
// установку системы управления внешним видом или
// добавление элементов пользовательского интерфейса
//------------------------------------------------------
public void init()
{
// Если для размещения в окне аплета органов управления
// вы используете класс "control creator", созданный
// системой ResourceWizard, из метода init можно
// вызывать метод CreateControls. Удалите вызов функции
// resize перед добавлением вызова функции
// CreateControls, так как эта функция выполняет
// изменение размера окна аплета самостоятельно
//--------------------------------------------------
resize(320, 240);
// Сделать: Добавьте сюда дополнительный код
// инициализации
}
// Разместите здесь дополнительный код, необходимый
// для “чистого” завершения работы аплета. Метод
// destroy вызывается, когда аплет завершает работу
// и будет выгружен из памяти
//---------------------------------------------------
public void destroy()
{
// Сделать: Добавьте сюда код завершения работы аплета
}
// Обработчик процедуры рисования окна аплета HelloAp
//---------------------------------------------------
public void paint(Graphics g)
{
g.drawString(
"Created with Microsoft Visual J++ Version 1.0",
10, 20);
}
// Метод start вызывается при первом появлении на
// экране страницы HTML с аплетом
//---------------------------------------------------
public void start()
{
// Сделать: Добавьте сюда дополнительный код,
// который должен работать при запуске аплета
}
// Метод stop вызывается когда страница HTML с
// аплетом исчезает с экрана
//---------------------------------------------------
public void stop()
{
// Сделать: Добавьте сюда дополнительный код,
// который должен работать при остановке аплета
}
// Сделать: Добавьте сюда дополнительный код
}
Листинг 2.3. Файл HelloAp\HelloAp.html
<html>
<head>
<title>HelloAp</title>
</head>
<body>
<hr>
<applet
code=HelloAp.class
id=HelloAp
width=320
height=240 >
</applet>
<hr>
<a href="HelloAp.java">The source.</a>
</body>
</html>
Режим BorderLayout
При использовании режима BorderLayout окно контейнера разделяется на рамку и центральную часть. При размещении компонент указывается направление от центра окна, в котором слудует размещать компоненты.
Ниже приведено краткое описание класса BorderLayout:
public class java.awt.BorderLayout
extends java.lang.Object
implements java.awt.LayoutManager
{
// -----------------------------------------------------
// Конструктор
// -----------------------------------------------------
public BorderLayout();
public BorderLayout(int hgap, int vgap);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
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();
}
Два конструктора предназначены для создания схемы размещения, соответственно, без зазора между компонентами и с зазором заданной величины.
Добавляя компоненты к контейнеру, вы должны использовать метод add с двумя параметрами, первый из которых указывает направление размещения, а второй - ссылку на добавляемый объект:
add("North", btn1);
add("East", btn2);
add("West", btn3);
add("South", btn4);
add("Center", btn5);
Режим CardLayout
Режим CardLayout предназначен для создания набора диалоговых панелей, которые можно показывать по очереди в одном окне прямоугольной формы. Обычно для управления процессом перебора диалоговых панелей в режиме CardLayout используются отдельные органы управления, расположенные в другой панели или даже в другом аплете на той же самой странице сервера WWW. Пример такого аплета мы приведем после того как рассмотрим использование класса Panel.
Класс CardLayout содержит два конструктора и несколько методов:
public class java.awt.CardLayout
extends java.lang.Object
implements java.awt.LayoutManager
{
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Режим без зазоров
public CardLayout();
// Режим с зазорами по вертикали и горизонтали
// между компонентами и окном контейнера
public CardLayout(int hgap, int vgap);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Добавление компоненты с указанием имени
public void addLayoutComponent(String name,
Component comp);
// Отображение первой страницы блокнота
public void first(Container target);
// Отображение последней страницы блокнота
public void last(Container target);
// Отображение следующей страницы блокнота
public void next(Container target);
// Отображение предыдущей страницы блокнота
public void previous(Container target);
// Выполнение размещения компонент
public void layoutContainer(Container target);
// Определение минимальных размеров окна,
// необходимых для размещения компонент
public Dimension minimumLayoutSize(Container target);
// Определение предпочтительных размеров окна,
// необходимых для размещения компонент
public Dimension preferredLayoutSize(Container target);
// Удаление заданной компоненты
public void removeLayoutComponent(Component comp);
// Отображение произвольной страницы блокнота
// по ее имени
public void show(Container target, String name);
// Получение текстовой строки названия режима размещения
public String toString();
}
Как пользоваться режимом размещения 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".
Режим FlowLayout
В этом режиме мы добавляли компоненты во всех примерах аплетов, приведенных в предыдущей главе, так как по умолчанию для аплетов используется именно режим FlowLayout.
Ниже мы привели краткое описание класса FlowLayout:
public class java.awt.FlowLayout
extends java.lang.Object
implements java.awt.LayoutManager
{
// -----------------------------------------------------
// Поля
// -----------------------------------------------------
// Способы выравнивания
public final static int CENTER; // центрирование
public final static int LEFT; // по левой границе
public final static int RIGHT; // по правой границе
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Без указания выравнивания и зазора между компонентами
public FlowLayout();
// С указанием выравнивания
public FlowLayout(int align);
// С указанием выравнивания и зазора между компонентами
// по вертикали и горизонтали
public FlowLayout(int align, int hgap, int vgap);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Не используется
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();
}
Обычно приложения не вызывают методы класса FlowLayout, устанавливая варианты компоновки при помощи конструкторов.
Первый конструктор класса FlowLayout, не имеющий параметров, устанавливает по умолчанию режим центрирования компонент и зазор между компонентами по вертикали и горизонтали, равный 5 пикселам. Именно этот режим и использовался во всех наших аплетах из предыдущей главы, так как именно он применяется по умолчанию объектами класса Panel, от которого наследуется класс Applet.
С помощью второго конструктора вы можете выбрать режим размещения с заданным выравниванием компонент в окне контейнера по горизонтали. В качестве параметров этому конструктору необходимо передавать значения FlowLayout.LEFT, FlowLayout.RIGHT, или FlowLayout.CENTER. Зазор между компонентами будет при этом равен по умолчанию 5 пикселам.
И, наконец, третий конструктор допускает раздельное указание режима выравнивания, а также зазоров между компонентами по вертикали и горизонтали в пикселах.
Режим GridBagLayout
Режим GridBagLayout намного сложнее только что описанного режима GridLayout. Он позволяет размещать компоненты разного размера в таблице, задавая при этом для отдельных компонент размеры отступов и количество занимаемых ячеек.
В нашей книге мы не будем рассматривать этот режим, так как сходные результаты могут быть достигнуты другими, менее сложными способами. Например, вы можете создать в контейнере несколько панелей, использовав внутри каждой свой метод размещения компонент.
Если вы создаете аплеты для размещения в документах HTML, никто не заставляет вас ограничиваться только одним аплетом для одного документа HTML - вы можете разместить там произвольное количество аплетов, организовав взаимодействие с одной стороны, между отдельными аплетами, а с другой - между аплетами и расширениями сервера WWW.
Тех, кого интересует режим GridBagLayout, мы адресуем к документации, которая входит в комплект Microsoft Visual J++, а также к книге Д. Родли “Создание Java-апплетов”, которая издана на русском языке.
В интегрированной системе разработки приложений Java Microsoft Visual J++ версии 1.1 имеется система автоматизированного проектирования пользовательского интерфейса, в результате работы которой создаются исходные тексты классов. Размещение органов управления при этом выполняется интерактивными средствами, аналогичными средствам разработки диалоговых панелей для приложений Microsoft Windows. В следующем томе “Библиотеки системного программиста”, посвященном Java, мы научим вас пользоваться этой системой.
Режим GridLayout
В режиме GridLayout компоненты размещаются в ячейках таблицы, параметры которой можно задать с помощью конструкторов класса GridLayout:
public class java.awt.GridLayout
extends java.lang.Object
implements java.awt.LayoutManager
{
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Создание таблицы с заданным
// количеством строк и столбцов
public GridLayout(int rows, int cols);
// Создание таблицы с заданным количеством строк и
// столбцов и с заданным зазором между компонентами
public GridLayout(int rows, int cols, int hgap, int vgap);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
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();
}
При размещении компонент внутри ячеек таблицы все они получают одинаковые размеры. Если один из параметров, задающих размерность таблицы, равен нулю, это означает, что соответствующий столбец или строка может содержать любое количество элементов.
Заметим, что оба параметра rows и cols не могут быть равны нулю одновременно.
Режимы системы Layout Manager
Прежде чем мы рассмотрим различные режимы компоновки системы Layout Manager, вспомним, как происходит наследование класса Applet (рис.6.1).
Рис. 6.1. Наследование класса Applet
Класс Applet наследуется от класса Panel, который, в свою очередь, наследуется от класса Container и Component. Класс Container пользуется интерфейсом LayoutManager, что позволяет выбирать для контейнеров один из нескольких режимов размещения компонент в окне контейнера.
Что же касается класса Panel, то для него по умолчанию выбирается режим размещения компонент с названием Flow Layout. Разумеется, вы можете выбрать другой режим размещения, указав его явным образом.
Ниже мы перечислили все возможные режимы системы Layout Manager:
Режим размещения компонент | Описание | ||
FlowLayout | Компоненты заполняют окно контейнера “потоком” по мере их добавления методом add. Они размещаются слева направо и сверху вниз | ||
GridLayout | Компоненты размещаются в виде таблицы по мере добавления слева направо и сверху вниз. Для этой таблицы можно указать количество столбцов и строк | ||
GridBagLayout | Аналогично предыдущему, однако при добавлении компонент в таблицу можно указать координаты ячейки, в которую помещается компонента | ||
BorderLayout | При размещении компоненты указывается одно из нескольких направлений: юг, север, запад, восток, центр. Направление определяется относительно центра окна контейнера | ||
CardLayout | Размещение компонент друг над другом в одном окне. Этот режим позволяет организовать набор диалоговых панелей в виде блокнота |
Каждому режиму соответсвует одноименный класс, методы и конструкторы которого позволяют выбирать различные компоновки.
Далее на примере конкретных приложений мы рассмотрим использование перечисленных выше режимов системы Layout Manager.
Рисование геометрических фигур
В этом разделе мы опишем методы класса Graphics, предназначенные для рисования элементарных геометрических фигур, таких как линии, прямоугольники, окружности и так далее.
Рисование в окне панели
Как вы знаете, для того чтобы что-нибудь нарисовать, необходимо вначале получить контекст отображения. Методу 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”.
Сборка мусора
Одна из интереснейших особенностей языка программирования Java и среды выполнения приложений Java заключается в наличии специального процесса сборки мусора, предназначенного для удаления ненужных объектов из памяти. Эта система избавляет программиста от необходимости внимательно следить за использованием памяти, освобождая ненужные более области явным образом.
Создавая объекты в Java, вы можете руководствоваться принципом “Создай и забудь”, так как система сборки мусора позаботится об удалении ваших объектов. Объект будет удален из памяти, как только на него не останется ни одной ссылки из других объектов.
Приоритет процесса сборки мусора очень низкий, поэтому “уборка” среды выполнения приложений Java не отнимает ресурсы у самих приложений.
Сдвиг начала системы координат
Метод translate сдвигает начало системы координат в контексте отображения таким образом, что оно перемещается в точку с координатами (x, y), заданными через параметры метода:
public abstract void translate(int x, int y);
Сегменты
Метод drawArc предназначен для рисования незаполненного сегмента (рис. 3.8). Прототип этого метода приведен ниже:
public abstract void drawArc(int x, int y,
int width, int height, int startAngle, int arcAngle);
Рис. 3.8. Рисование незаполненного сегмента
Параметры x, y, width и height задают координаты прямоугольника, в который вписан сегмент.
Параметры startAngle и arcAngle задаются в градусах. Они определяют, соответственно, начальный угол и угол разворота сегмента.
Для того чтобы нарисовать заполненный сегмент, вы можете воспользоваться методом fillArc:
public abstract void
fillArc(int x, int y, int width,
int height, int startAngle, int arcAngle);
События от клавиатуры
Аплет может обрабатывать события, создаваемые клавиатурой. Например, он может реагировать на функциональные клавиши или на клавиши ускоренного выбора функций.
Для того чтобы обработать события от клавиатуры, ваш аплет должен переопределить методы keyDown и keyUp:
public boolean keyDown(Event evt, int nKey)
{
. . .
}
public boolean keyUp(Event evt, int nKey)
{
. . .
}
В качестве первого параметра этим методам передается объект типа Event, о полях которого мы рассказывали в разделе “Как обрабатываются события” этой главы.
Наибольший интерес представляют поля объекта evt с именами key и modifiers. Через них передается, соответственно, код нажатой клавиши и код модификации. Возможные значения для этих полей вы найдете в только что указанном разделе.
Второй параметр методов keyDown и keyUp с именем nKey дублирует поле key объекта evt.
События от мыши
В этом разделе мы рассмотрим события, которые возникают в результате того, что пользователь выполняет в окне аплета операции с мышью. Это такие операции, как нажатие и отпускание клавиши мыши, перемещение курсора мыши в окне аплета с нажатой или отпущенной клавишей, перемещение курсора мыши в окно аплета и удаление этого курсора из окна аплета.
Все перечисленные ниже методы должны вернуть значение true, если обработка события выполнена успешно и дальнейшая обработка не требуется. Если же методы вернут значение fasle, событие будет обработано методом из базового класса, то есть для него будет выполнена обработка, принятая по умолчанию.
Программисты, создававшие приложения для операционной системы Microsoft Windows, могут найти здесь аналогию с вызовом функции DefWindowProc, которая выполняет обработку сообщений, принятую по умолчанию.
Создание диалоговых панелей
Диалоговые панели создаются на базе класса Dialog, краткое описание которого приведено ниже:
public class java.awt.Dialog
extends java.awt.Window
{
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Создание диалоговой панели без заголовка
public Dialog(Frame parent, boolean modal);
// Создание диалоговой панели с заголовком
public Dialog(Frame parent, String title, boolean modal);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Вызов метода createDialog
public void addNotify();
// Получение строки заголовка диалоговой панели
public String getTitle();
// Определение, является ли диалоговая панель модальной
public boolean isModal();
// Определение возможности изменения размеров окна
// диалоговой панели
public boolean isResizable();
// Получение строки параметров
protected String paramString();
// Включение или выключение возможности изменения
// размеров окна диалоговой панели
public void setResizable(boolean resizable);
// Установка заголовка диалоговой панели
public void setTitle(String title);
}
Для того чтобы создать свою диалоговую панель, вы должны определить новый класс, унаследовав его от класса Dialog, как это показано ниже:
class MessageBox extends Dialog
{
. . .
public MessageBox(String sMsg,
Frame parent, String sTitle, boolean modal)
{
super(parent, sTitle, modal);
. . .
resize(200, 100);
. . .
}
}
В этом классе нужно определить конструктор, который вызывает конструктор базового метода класса Dialog и определяет размеры окна диалоговой панели. Кроме того, в конструкторе вы должны создать все необходимые компоненты для размещения внутри диалоговой панели (кнопки, списки, текстовые поля, переключатели и так далее), а также выполнить размещение этих компонент, установив нужный режим размещения.
Для окон класса Dialog устанавливается режим размещения BorderLayout. Если нужен другой режим размещения, необходимо установить его явным образом методом setLayout.
Для отображения окна диалоговой панели необходимо вызвать метод show. Чтобы спрятать диалоговой окно, применяйте метод hide. Метод dispose удаляет окно диалоговой панели окончательно и освобождает все связанные с ним ресурсы.
Когда пользователь пытается уничтожить окно диалоговой панели при помощи органов управления, расположенных в заголовке такого окна, возникает событие Event.WINDOW_DESTROY. Вы должны обработать его, обеспечив удаление окна диалоговой панели вызовом метода dispose, если, конечно, это соответствует логике работы вашей панели.
Создание нового класса на базе класса Panel
Если ваш аплет создает много панелей, техника рисования в окнах этих панелей, использованная в только что рассмотренном приложении Notebook, может привести к усложнению исходного текста приложения. Так как рисование в окнах панелей выполняется в методе paint класса аплета, вам придется получать контекст отображения для каждой панели.
Намного проще создать несколько дочерних классов от класса Panel, переопределив в каждом из них метод paint. В этом случае для каждой панели вы можете создать свой метода paint, которому будет автоматически передаваться контекст отображения, связанный с окном соответствующей панели.
Эта техника использована в приложении Panel2, которое мы рассмотрим в следующем разделе.
Создание панелей
Панель создается очень просто. Прежде всего необходимо выбрать для окна аплета схему размещения компонент, соответствующую требуему расположению панелей. Например, для создания в окне аплета двух панелей, разделяющих его по горизонтали, следует выбрать режим GridLayout:
setLayout(new GridLayout(2, 1));
Панели будут размещаться в ячейках таблицы, состоящей из одного столбца и двух строк.
Далее нужно создать объекты класса Panel:
Panel pTopPanel;
pTopPanel = new Panel();
Panel pBottomPanel;
pBottomPanel = new Panel();
Ссылка на панель, которая будет располагаться сверху, записывается в переменную pTopPanel, а на ту, что будет располагаться снизу - в переменную pBottomPanel.
Создание переключателей с независимой фиксацией
Переключатели с независимой и зависимой фиксацией создаются на базе класса Checkbox:
public class java.awt.Checkbox
extends java.awt.Component
{
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Создание переключателя с независимой фиксацией
// без названия
public Checkbox();
// Создание переключателя с независимой фиксацией
// и названием
public Checkbox(String label);
// Создание переключателя с зависимой фиксацией
// и названием
public Checkbox(String label, CheckboxGroup group,
boolean state);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Вызов метода createCheckbox
public void addNotify();
// Получение группы, к которой относится
// данный переключатель с зависимой фиксацией
public CheckboxGroup getCheckboxGroup();
// Получение названия переключателя
public String getLabel();
// Определение текущего состояния переключателя
public boolean getState();
// Получение строки параметров
protected String paramString();
// Установка группы, к которой относится
// данный переключатель с зависимой фиксацией
public void setCheckboxGroup(CheckboxGroup g);
// Установка названия переключателя
public void setLabel(String label);
// Установка нового состояния переключателя
public void setState(boolean state);
}
Создать переключатель с независимой фиксацией не сложнее, чем создать кнопку:
Checkbox rdbox1;
. . .
public void init()
{
chbox1 = new Checkbox("Switch 1");
add(chbox1);
}
В этом фрагменте кода мы создаем переключатель chbox1 с названием Switch 1, а затем с помощью метода add добавляем его в контейнер, которым является окно аплета.
Для определения текущего состояния переключателя вы можете использовать метод getState. Если переключатель включен, этот метод возвращает значение true, а если выключен - значение false.
Создание переключателей с зависимой фиксацией
Для каждой группы переключателей с зависимой фиксацией вы должны создать объект класса CheckboxGroup:
public class java.awt.CheckboxGroup
extends java.lang.Object
{
// -----------------------------------------------------
// Конструктор
// -----------------------------------------------------
public CheckboxGroup();
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Получение ссылки на переключатель, который
// находится во включенном состоянии
public Checkbox getCurrent();
// Установка указанного переключателя в группе
// во включенное состояние
public void setCurrent(Checkbox box);
// Получение строки, которая представляет группу
public String toString();
}
Ссылка на этот объект указывается при создании отдельных переключателей с зависимой фиксацией, входящих в группу:
CheckboxGroup grModeGroup;
Checkbox rdbox1;
Checkbox rdbox2;
Checkbox rdbox3;
Checkbox rdbox4;
. . .
public void init()
{
grModeGroup = new CheckboxGroup();
rdbox1 = new Checkbox("Mode 1",grModeGroup, true);
rdbox2 = new Checkbox("Mode 2",grModeGroup, false);
rdbox3 = new Checkbox("Mode 3",grModeGroup, false);
rdbox4 = new Checkbox("Mode 4",grModeGroup, false);
add(rdbox1);
add(rdbox2);
add(rdbox3);
add(rdbox4);
}
Через первый параметр конструктору Checkbox в этом примере передается название переключателя, через второй - ссылка на группу, а через третий - состояние, в которое должен быть установлен переключатель. Из всех переключателей группы только один может находиться во включенном состоянии.
Списки класса Choice
На базе класса Choice вы можете создать списки типа Drop Down или, как их еще называют, “выпадающие” списки. Такой список выглядит как текстовое поле высотой в одну строку, справа от которого располагается кнопка (рис. 5.5).
Рис. 5.5. Список типа Drop Down, созданный на базе класса Choice
Если нажать на эту кнопку, список раскроется и вы сможете сделать выбор из его элементов (рис. 5.6).
Рис. 5.6. Раскрытый список, созданный на базе класса Choice
В списке класса Choice одновременно можно выбрать только один элемент.
Рассмотрим класс Choice. Определение этого класса выглядит несложно:
public class java.awt.Choice
extends java.awt.Component
{
// -----------------------------------------------------
// Конструктор
// -----------------------------------------------------
public Choice();
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Добавление элемента в список
public void addItem(String item);
// Вызов метода createChoice
public void addNotify();
// Определение количества элементов в списке
public int countItems();
// Получение строки списка по номеру соответствующего
// ему элемента списка
public String getItem(int index);
// Получение номера текущего выбранного элемента
public int getSelectedIndex();
// Получение строки, соответствующей текущему
// выбранному элементу списка
public String getSelectedItem();
// Получение строки параметров
protected String paramString();
// Выбор в списке элемента по заданному номеру
public void select(int pos);
// Выбор в списке элемента по заданной строке
public void select(String str);
}
Конструктор класса Choice не имеет параметров. Создание списка с его помощью не вызовет у вас никаких затруднений:
Choice chBackgroundColor;
chBackgroundColor = new Choice();
Для наполнения списка используйте метод addItem. В качестве параметра ему необходимо передать текстовую строку, которая будет связана с добавляемым элементом списка:
chBackgroundColor.addItem("Yellow");
Далее список можно добавить в окно аплета как компонент с помощью метода add:
add(chBackgroundColor);
Заметим, что список можно заполнять до или после добавления в окно аплета.
После наполнения списка по умолчанию выделяется элемент, который был добавлен в список первым. При помощи метода select вы можете выделить любой элемент списка по его номеру или строке, связанной с элементом.
Когд пользователь выбирает новую строку в списке, возникает событие. Обработчик этого события, реализованный, например, переопределением метода action, может получить номер выбранной строки при помощи метода getSelectedIndex. Пример обработки такого события вы найдете в разделе “Приложение ChoiceList”.
Если вас интересует не номер выбранного элемента, а строка, связанная с выбранным элементом, воспользуйтесь методом getSelectedItem.
И, наконец, с помощью метода getItem вы можете получить текст строки, связанной с элементом, по номеру элемента.
Списки класса List
На базе класса List вы можете сделать список другого типа, который допускает выбор не только одного, но и нескольких элементов. В отличие от списка, созданного на базе класса Choice, список класса List может занимать прямоугольную область, в которой помещаются сразу несколько элементов. Этот список всегда находится в раскрытом состоянии (рис. 5.8).
Рис. 5.8. Список класса List, все элементы которого помещаются в окне списка
Если размеры окна списка класса List недостаточны для того чтобы вместить в себя все элементы, в правой части окна списка автоматически создается полоса просмотра, с помощью которой можно пролистать весь список (рис. 5.9).
Рис. 5.9. Список класса List с полосой просмотра
Ссылки на методы класса
Так как в Java нет указателей, нет возможности ссылаться на методы с помощью оператора ->. Для ссылки на метод класса используется только оператор “точка”.
Оператор “::” также не определен в Java. Если вам необходимо вызвать метод из базового класса, следует использовать ключевое слово super.
Текстовое поле класса Label
На базе класса Label вы можете создать в окне аплета однострочное текстовое поле, которое не поддается редактированию. Основное назначение таких полей - подпись других компонент, таких, например, как группы переключателей или списки.
Ниже мы привели краткое описание класса Label:
public class java.awt.Label
extends java.awt.Component
{
// -----------------------------------------------------
// Поля
// -----------------------------------------------------
// Способ выравнивания текстового поля
public final static int CENTER; // центрирование
public final static int LEFT; // по левой границе
public final static int RIGHT; // по правой границе
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Создание текстового поля без текста
public Label();
// Создание текстового поля с заданным текстом
public Label(String label);
// Создание текстового поля с заданным текстом
// и заданным выравниванием
public Label(String label, int alignment);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Вызов метода createLabel
public void addNotify();
// Определение текущего выравнивания текстового поля
public int getAlignment();
// Получение текста из поля
public String getText();
// Получение строки параметров
protected String paramString();
// Установка выравнивания текстового поля
public void setAlignment(int alignment);
// Запись текста в поле
public void setText(String label);
}
Текстовое поле класса Label создается вызовом соответствующего конструктора. Например, ниже мы создали текстовое поле, указав строку, которую надо в него записать:
Label lbTextLabel;
lbTextLabel = new Label("Выберите выравнивание");
С помощью метода add вы можете добавить текстовое поле в окно аплета:
add(lbTextLabel);
Метод setAlignment позволяет при необходимости изменить выравнивание текста. Способ выравнивания необходимо указать через единственный параметр метода:
lbTextLabel.setAlignment(Label.LEFT);
При помощи метода setText вы сможете динамически изменять текст, расположенный в поле класса Label.
Текстовое поле класса TextField
Для редактирования одной строки текста вы можете создать текстовое поле на базе класса TextField, которое несложно в использовании. Класс TextField создан на базе другого класса с именем TextComponent, поэтому при работе с текстовым полем класса TextField вы можете использовать и методы класса TextComponent.
Приведем краткое описание класса TextField:
public class java.awt.TextField
extends java.awt.TextComponent
{
// -----------------------------------------------------
// Конструкторы
// -----------------------------------------------------
// Создание поля без текста
public TextField();
// Создание поля без текста с заданной шириной
public TextField(int cols);
// Создание поля и инициализация его текстом
public TextField(String text);
// Создание поля заданной ширины
// и инициализация его текстом
public TextField(String text, int cols);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Вызов метода createTextField
public void addNotify();
// Проверка, установлен ли для поля эхо-символ
public boolean echoCharIsSet();
// Определение размера поля
public int getColumns();
// Получение текущего эхо-символа
public char getEchoChar();
// Определение минимальных размеров области
// для отображения поля
public Dimension minimumSize();
// Определение минимальных размеров области
// для отображения поля заданной ширины
public Dimension minimumSize(int cols);
// Получение строки параметров
protected String paramString();
// Определение оптимальных размеров области
// для отображения поля
public Dimension preferredSize();
// Определение оптимальных размеров области
// для отображения поля заданной ширины
public Dimension preferredSize(int cols);
// Установка эхо-символа для отображения в поле
public void setEchoCharacter(char c);
}
При создании текстового поля вы можете выбрать один из четырех конструкторов, соответственно, для создания поля без текста и без указания размера, без текста заданного размера, для создания поля с текстом и для создания поля с текстом указанного размера.
Вот фрагмент кода, в котором создается поле с текстом, имеющее ширину, достаточную для размещения 35 символов:
TextField txt;
txt = new TextField("Введите строку текста", 35);
Созданное поле добавляется в окно аплета методом add.
Большинство самых полезнных методов, необходимых для работы с полем класса TextField, определено в классе TextComponent, краткое описание которого мы привели ниже:
public class java.awt.TextComponent
extends java.awt.Component
{
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Получение текста, выделенного пользователем
// в окне поля
public String getSelectedText();
// Получение позиции конца выделенной области
public int getSelectionEnd();
// Получение позиции начала выделенной области
public int getSelectionStart();
// Получение полного текста из поля
public String getText();
// Проверка, возможно ли редактирование
// текста в поле
public boolean isEditable();
// Получение строки параметров
protected String paramString();
// Удаление извещения
public void removeNotify();
// Выделение заданной области текста
public void select(int selStart, int selEnd);
// Выделение всего текста
public void selectAll();
// Включение или выключение возможности
// редактирования текста
public void setEditable(boolean t);
// Установка текста в поле
public void setText(String t);
}
С помощью метода getText вы можете получить весь текст, который имеется в поле. Метод getSelectedText позволяет получить только ту часть текста, которая предварительно была выделена пользователем.
Приложение может выделить любой фрагмент текста или весь текст при помощи методов select и selectAll, соответственно.
Для записи текста в поле приложение может воспользоваться методом setText.
Возможно, для вас будет интересен метод setEditable, позволяющий переключать текстовое поля из режима, при котором редактирование заблокировано, в режим с разрешенным редактированием и обратно.
Указатели, которых нет
Самая большая и шокирующая новость для тех, кто раньше программировал на С, а теперь занялся изучением Java, это то, что в языке Java нет указателей. Традиционно считалась, что работать с указателями трудно, а их использование приводит к повялению трудно обнаруживаемых ошибок. Поэтому разработчики Java решили отказаться от использования указателей совсем.
Спешим успокоить - вы сможете успешно составлять приложения Java и без указателей, несмотря на то что вам, возможно, придется немного изменить стиль программирования.
Вы можете спросить: как же передавать функциям ссылки на объекты, если нет указателей?
Если вам нужно передать ссылку на переменную базового типа, такого, например, как int или long, то ничего не получится - мы уже говорили, что переменные базовых типов передаются по значению, а не по ссылке. Поэтому вы не сможете напрямую создать на языке Java эквивалент следующей программы, составленной на языке С:
// Некоторая переменная
int nSomeValue;
// Функция, изменяющая значение переменной,
// заданной своим адресом
void StoreValue(int *pVar, int nNewValue)
{
pVar->nNewValue;
}
. . .
StoreValue(&nSomeValue, 10);
Выход, однако, есть.
Язык Java позволяет использовать вместо указателей ссылки на объекты. Пользуясь этими ссылками, вы можете адресовать объекты по их имени, вызывая методы и изменяя значения данных объектов.
Что же касается данных базовых типов, если вам нужно передавать на них ссылки, то следует заменить базовые типы на соответствующие встроенные классы. Например, вместо типа int используйте класс Integer, вместо типа long - класс Long и так далее.
Инициализация таких объектов должна выполняться с помощью конструктора, как это показано ниже:
Integer nSomeValue;
nSomeValue = new Integer(10);
Первая строка создает неинициализированную ссылку с именем nSomeValue и типом Integer. При попытке использования такой ссылки возникнет исключение.
Вторая строка создает объект класса Integer, вызывая конструктор. Этот конструктор определяет начальное значение. После выполнения оператора присваивания ссылка nSomeValue будет ссылаться на реальный объект класса Integer и ее можно будет использовать.
Имя объекта nSomeValue типа Integer вы можете передавать функциям в качестве параметра, причем это будет ссылкой на объект.
Составляя программы на языке С, вы часто использовали указатели для адресации элементов массивов, созданных статически или динамически в оперативной памяти. Зная начальный адрес такого массива и тип хранящихся в нем элементов, вы могли адресоваться к отдельным элементам массива.
В языке Java реализован механизм массивов, исключающих необходимость использования указателей.
Упрощаем исходный текст аплета
Если вам показалось, что исходный текст аплета слишком сложный, вы можете его упростить, как это показано ниже:
//**********************************************************
// HelloAp.java: Applet
//
//**********************************************************
import java.applet.*;
import java.awt.*;
//==========================================================
// Основной класс для аплета HelloAp
//
//==========================================================
public class HelloAp extends Applet
{
// Обработчик процедуры рисования окна аплета HelloAp
//---------------------------------------------------
public void paint(Graphics g)
{
g.drawString(
"Created with Microsoft Visual J++ Version 1.0",
10, 20);
}
}
Мы выбросили определения всех методов, которые не выполняют никакой полезной работы, а также удалили методы getAppletInfo и init. Аплет будет работать также, как и раньше, потому что методы init, start, stop, destroy, getAppletInfo, удаленные нами, определены в базовом классе Applet.
Однако метод paint необходимо переопределить в любом случае, так как именно в нем выполняется рисование строки, то есть то, что делает наш аплет.
Почему же система Java Applet Wizard создает пустые определения методов? Просто для того, чтобы вы при необходимости наполнили их чем нибудь полезным. Если вам не нужны эти определения, вы можете их удалить.
Установка атрибутов контекста отображения
Изменяя атрибуты контекста отображения, приложение Java может установить цвет для рисования графических изображений, таких как линии и многоугольники, шрифт для рисования текста, режим рисования и маску. Возможен также сдвиг начала системы координат.
Установка маски для рисования
Задавая маску для рисования при помощи метода setXORMode, вы можете выполнить при рисовании замещение текущего цвета на цвет, указанный в параметре метода, и наоборот, цвета, указанного в параметре метода, на текущий.
Все остальные цвета изменяются непредсказуемым образом, однако эта операция обратима, если вы нарисуете ту же самую фигуру два раза на одном и том же месте.
Прототип метода setXORMode:
public abstract void setXORMode(Color c1);
Установка режима рисования
Метод setPaintMode устанавливает в контексте отображения режим рисования, при котором выполняется замещение изображения текущим цветом, установленном в контексте отображения.
Прототип метода setPaintMode приведен ниже:
public abstract void setPaintMode();
Вход курсора мыши в область окна аплета
Метод mouseEnter получает управление, когда курсор мыши в процессе перемещения по экрану попадает в область окна аплета:
public boolean mouseEnter(Event evt, int x, int y);
Вы можете использовать этот метод для активизации аплета, на который указывает курсор мыши.
Встроенные классы
В языке Java все классы происходят от класса Object, и, соответственно, наследуют методы этого класса. Некоторые библиотеки классов подключаются автоматически, и мы будем называть их встроенными. К таким относится, в частности, библиотека с названием java.lang. Другие библиотеки классов вы должны подключать в исходном тексте приложения Java явным образом с помощью оператора import, о котором мы еще расскажем.
Казалось бы, на сегодняшний день
Казалось бы, на сегодняшний день изобрели уже все языки программирования, какие только можно придумать. Но нет - появился еще один, с названием Java. Этот язык сумел завоевать весьма заметную популярность за последние несколько лет, так как он ориентирован на самую популярную компьютерную среду - сеть Internet и серверы WWW.
Язык Java произошел от языка программирования Oak (а не от С++, как думают многие). Oak был приспособлен для работы в Internet и затем переименован в Java. Изучая Java, вы будете приятно удивлены тем, что его синтаксис близок к синтаксису языка C++. Унаследовав самое лучшее от языка программирования C++, язык Java при этом избавился от некоторых недостатков С++, в результате чего на нем стало проще программировать. В этом языке нет, например, указателей, которые сложны в использовании и потенциально могут послужить причиной доступа программы к не принадлежащей ей области памяти. Нет множественного наследования и шаблонов, хотя функциональные возможности языка Java от этого не пострадали. Если вы умеете программировать на C++, для вас не составит особого труда изучить язык Java.
Огромное преимущество Java заключается в том, что на этом языке можно создавать приложения, способные работать на различных платформах. К сети Internet подключены компьютеры самых разных типов - совместимые с IBM PC, компьютеры фирмы Apple, рабочие станции Sun и так далее. Даже в рамках компьютеров, созданных на базе процессоров Intel, существует несколько платформ, например, Microsoft Windows версии 3.1, Microsoft Windows 95,. Microsoft Windows NT, IBM OS/2, Solaris, различные разновидности операционной системы UNIX с графической оболочкой X-Windows. Между тем, создавая сервер WWW в сети Internet, вы бы наверняка хотели, чтобы им могло пользоваться как можно большее число людей. В этом случае вас выручат мультиплатформные приложения Java, не зависящие от конкретного типа процессора и операционной системы.
Программы, составленные на языке программирования Java, можно разделить по своему назначению на две большие группы.
К первой группе относятся приложения Java, предназначенные для автономной работы под управлением специальной интерпретирующей машины Java. Реализации этой машины созданы для всех основных компьютерных платформ.
Вторая группа - это так называемые аплеты (applets). Аплеты представляют собой разновидность приложений Java, которые интерпретируются виртуальной машиной Java, встроенной в навигаторы WWW, такие как Microsoft Internet Explorer или Netscape Navigator.
Приложения, относящиеся к первой группе (в нашей книге мы будем называть их просто приложениями Java), это обычные автономные программы. Так как они не содержат машинного кода и работают под управлением специального интерпретатора, их производительность заметно ниже, чем у обычных программ, составленных, например, на языке программирования C++. Однако не следует забывать, что программы Java без перетрансляции способны работать на любой платформе, что само по себе имеет большое значение в плане разработок для Internet.
Аплеты Java встраиваются в документы HTML, хранящиеся на сервере WWW. С помощью аплетов вы можете сделать страницы сервера WWW динамичными и интерактивными. Аплеты позволяют выполнять сложную локальную обработку данных, полученных от сервера WWW и введенных пользователем с клавиатуры. Из соображений безопасности аплеты (в отличие от обычных приложений Java) не имеют никакого доступа к файловой системе локального компьютера. Все данные для обработки они могут получить только от сервера WWW. Более сложную обработку данных можно выполнять, организовав взаимодействие между аплетами и расширениями сервера WWW - приложениями CGI и ISAPI.
Для повышения производительности приложений Java в навигаторе Microsoft Internet Explorer использована технология с названием Just-in-Time Compilation, или JIT. При первой загрузке аплета его код транслируется в обычную исполнимую программу, которая сохраняется на диске и запускается. В результате общая скорость выполнения аплета Java увеличивается в несколько раз.
Язык Java является объектно-ориентированным и поставляется с достаточно объемной библиотекой классов. Так же как и библиотеки классов систем разработки приложений на языке С++, такие как Microsoft Foundation Classes (MFC), библиотеки классов Java значительно упрощают разработку приложений, представляя в распоряжение программиста мощные средства решения распространенных задач. Поэтому программист может больше внимания уделить решению прикладных задач, а не таких, как, например, организация динамических массивов, взаимодействие с операционной системой или реализация элементов пользовательского интерфейса.
Первоначально средства разработки приложений и аплетов Java были созданы фирмой Sun и до сих пор эти средства пользуются популярностью. В сети Internet по адресу http://www.sun.com есть сервер фирмы Sun, с которого можно бесплатно получить набор Java Development Kit (JDK). В JDK входят пакетные программы для компиляции исходных текстов приложений Java, виртуальная машина, программа автоматизированного создания документации по классам, справочник по классам Java и другие необходимые средства.
Для тех, кто привык пользоваться средствами разработки корпорации Microsoft, мы можем порекомендовать SDK-Java - пакетное средство разработки приложений и аплетов Java, расположенное на сервере http://microsoft.com. В составе этого средства есть также комплект документации по классам Java в виде набора документов HTML. Вы можете переписать себе SDK-Java бесплатно с указанного сревера Microsoft.
Если вы привыкли к интегрированным средствам разработки приложений, таким как Microsoft Visual C++, инструментарий JDK и SDK-Java могут показаться вам неудобными. В этом случае вы можете воспользоваться такими системами разработки приложений Java, как, например, Symantec Cafe или Microsoft Visual J++.
Мы рассмотрим недорогое, но удобное и мощное интегрированное средство разработки приложений Microsoft Visual J++. Оценочную версию этого средства можно бесплатно получить с сервера WWW корпорации Microsoft. Заметим, что эта оценочная версия не содержит внутри себя “бомбы”, уничтожающей программу через заданное время, и вы сможете оценивать ее достаточно долго. Стоимость коммерческой версии Microsoft Visual J++ невелика, особенно с учетом того, что в коробке вы найдете прекрасную книгу Стефана Дэвиса “Learn Java Now” (на английском языке) издательства Microsoft Press. Если вы работаете с Microsoft Visual C++, то после установки Microsoft Visual J++ вы получите единую среду для разработки на языках программирования C++ и Java, что очень удобно.
На прилавках книжных магазинов вы можете найти несколько переводных книг, посвященных программированию на языке Java. Практически все они ориентированы на инструментарий JDK, созданный фирмой Sun, и содержат более или менее подробное описание классов Java. В нашей книге мы научим вас работать с Microsoft Visual J++ и приведем все сведения, необходимые для разработки как автономных приложений, так и аплетов Java.
При изложении материала мы будем предполагать, что вы знакомы с языком программирования C++. Наша книга не является учебником по языку Java. Мы будем рассказывать о том, как использовать язык Java и систему разработки Microsoft Visual J++ для создания автономных приложений и аплетов Java, как организовать взаимодействие аплетов с сервером WWW (во второй части этой книги). При этом мы будем считать, что с основами языка Java вы знакомы.
Что вам потребуется для работы с книгой?
Очень хорошо, если вы подключены к сети Internet или имеете возможность хотя бы эпизодической работы в этой сети. В этом случае вам будет доступна бесплатная оценочная версия Microsoft Visual J++, другие бесплатные средства разработки приложений и аплетов Java, грандиозные запасы документации и примеров программ.
Для проверки работы аплетов вам следует установить навигатор Internet, способный запускать аплеты Java. Это Microsoft Internet Explorer версии 3.01 и Netscape Navigator версии 3.0. Заметим, что для запуска аплетов вам не нужно обязательно подключаться к Internet - вы можете встраивать аплеты в документы HTML, расположенные на локальном диске вашего компьютера и просматривать эти документы навигатором просто как локальные файлы.
Автономные приложения Java работают под управлением специального интерпретатора (виртуальной машины Java), поэтому для их отладки вам также не потребуется сеть Internet.
Если вы собираетесь проверять работу приложений и аплетов Java, взаимодействующих с сервером WWW, вы можете воспользоваться собственным сервером в Internet или в корпоративной сети Intranet (если они у вас есть). Примеры таких аплетов мы приведем в следующей книге “Библиотеки системного программиста”, посвященной Java. Можно также установить сервер WWW, входящий в комплект операционной системы Microsoft Windows NT Workstation версии 4.0, или Personal Web Service для операционной системы Microsoft Windows 95. Последний доступен для бесплатной загрузки с сервера http://microsoft.com.
Для того чтобы успешно работать с аплетами Java, вы должны иметь некоторое представление о серверах WWW и языке гипертекстовой разметки документов HTML. Поэтому перед чтением этой книги мы рекомендуем вам ознакомится с 29 томом “Библиотеки системного программиста”, который называется “Сервер Web своими руками”. В этой книге мы рассказали о том, как сделать собственный сервер WWW в сети Internet и Intranet, а также привели необходимую информацию о расширениях сервера WWW, реализованных как приложения CGI и ISAPI.
Базовые знания об Internet, а также описание конкретных способов подключения к ней в российских условиях вы найдете в 23 томе “Библиотеки системного программиста”, который называется “Глобальные сети компьютеров. Практическое введение в Internet, E-Mail, FTP, WWW и HTML, программирование для Windows Sockets”. Мы рекомендуем эту книгу для тех, кто только планирует подключиться к Internet, но еще не вполне осознает, как это можно сделать и для чего это нужно.
Что еще почитать?
Количество книг, посвященных Java, растет катастрофически, особенно за рубежом. Среди удачных еще раз назовем книгу Стефана Дэвиса с названием “Learn Java Now”, которая может служить учебником по языку Java для тех, кто никогда не программировал на С и С++.
Среди переводных книг, которые можно встретить в продаже, отметим книгу Джона Родли “Создание JAVA-апплетов”. Эта книга рассчитана на серьезных программистов, хорошо знающих язык программирования Java. Однако для тех, кто только начинает изучать язык Java, она может оказаться слишком сложной.
Другая книга, заслуживающая внимание, это книга Криса Джамса с названием “Java”. После небольшого введения, рассчитанного на начинающих, в этой книге приводится описание более чем дюжины достаточно интересных аплетов с исходными текстами и комментариями.
В качестве справочника по языку Java и библиотекам классов вы можете использовать книгу И. Баженовой “Язык программирования Java”, которая вышла в издательстве АО “Диалог -МИФИ”.
Ну и, конечно, вам следует ознакомиться с различными руководствами по языку Java, хранящимися в сети Internet. В качестве отправной точки для поиска вы можете выбрать сервер основного разработчика этого языка - фирмы Sun. Адрес ее сервера мы уже приводили: http://www.sun.com. Помимо документации и примеров программ на Java, здесь вы найдете ссылки на другие ресурсы, посвященные этому языку программирования. Попробуйте также воспользоваться поисковыми серверами, такими как Jahoo! и Alta Vista, указав в качестве ключевого слово “Java”.
Выбор цвета
Изменение цвета, выбранного в контекст отображения, выполняется достаточно часто. В классе Graphics для изменения цвета определен метод setColor, прототип которого представлен ниже:
public abstract void setColor(Color c);
В качестве параметра методу setColor передается ссылка на объект класса Color, с помощью которого можно выбрать тот или иной цвет.
Как задается цвет?
Для этого можно использовать несколько способов.
Прежде всего, вам доступны статические объекты, определяющие фиксированный набор основных цветов:
Объект | Цвет | ||
public final static Color black; | черный | ||
public final static Color blue; | голубой | ||
public final static Color cyan; | циан | ||
public final static Color darkGray; | темно-серый | ||
public final static Color gray; | серый | ||
public final static Color green; | зеленый | ||
public final static Color lightGray; | светло-серый | ||
public final static Color magenta; | малиновый | ||
public final static Color orange; | оранжевый | ||
public final static Color pink; | розовый | ||
public final static Color red; | красный | ||
public final static Color white; | белый | ||
public final static Color yellow; | желтый |
Этим набором цветов пользоваться очень просто:
public void paint(Graphics g)
{
// Выбираем в контекст отображения желтый цвет
g.setColor(Color.yellow);
g.drawString("Привет из аплета!", 10, 20);
. . .
}
Здесь мы привели фрагмент исходного текста метода paint, в котором в контексте отображения устанавливается желтый цвет. После этого метод drawString выведет текстовую строку "Привет из аплета!" желтым цветом.
Если необходима более точная установка цвета, вы можете воспользоваться одним из трех конструкторов объекта Color:
public Color(float r, float g, float b);
public Color(int r, int g, int b);
public Color(int rgb);
Первые два конструктора позволяют задавать цвет в виде совокупности значений трех основных цветовых компонент - красной, желтой и голубой (соотвестсвенно, параметры r, g и b). Для первого конструктора диапазон возможных значений компонент цвета находится в диапазоне от 0.0 до 1.0, а для второго - в диапазоне от 0 до 255.
Третий конструктор также позволяет задавать отдельные компоненты цвета, однако они должны быть скомбинированы в одной переменной типа int. Голубая компонента занимает биты от 0 до 7, зеленая - от 8 до 15, красная - от 16 до 23.
Ниже мы привели пример выбора цвета с помощью конструктора, передав ему три целочисленных значения цветовых компонент:
g.setColor(new Color(0, 128, 128));
В классе Color определено еще несколько методов, которые могут оказаться вам полезными:
Метод |
Описание |
public Color brighter(); |
Установка более светлого варианта того же цвета |
public Color darker(); |
Установка более темного варианта того же цвета |
public boolean equals( Object obj); |
Проверка равенства цветов текущего объекта и объекта, заданного параметром |
public int getBlue(); |
Определение голубой компоненты цвета (в диапазоне от 0 до 255) |
public int getRed(); |
Определение красной компоненты цвета (в диапазоне от 0 до 255) |
public int getGreen(); |
Определение зеленой компоненты цвета (в диапазоне от 0 до 255) |
getHSBColor(float h, float s, float b); |
Определение компонент оттенка, насыщенности и яркости (схема HSB) |
public int getRGB(); |
Определение компонент RGB для цвета, выбранного в контекст отображения |
public static int HSBtoRGB(float hue, float saturation, float brightness); |
Преобразование цветового представления из схемы HSB в схему RGB |
public static float[] RGBtoHSB(int r, int g, int b, float hsbvals[]); |
Преобразование, обратное выполняемому предыдущей функцией |
public String toString(); |
Получение текстовой строки названия цвета |
setBackground(Color.yellow);
setForeground(Color.black);
Здесь мы устанавливаем для окна аплета желтый цвет фона и черный цвет изображения.
Выбор шрифта
С помощью метода setFont из класса Graphics вы можете выбрать в контекст отображения шрифт, который будет использоваться методами drawString, drawBytes и drawChars для рисования текста. Вот прототип метода setFont:
public abstract void setFont(Font font);
В качестве параметра методу setFont следует передать объект класса Font:
public class java.awt.Font
extends java.lang.Object
{
// -----------------------------------------------------
// Поля класса
// -----------------------------------------------------
protected String name;
protected int size;
protected int style;
// Битовые маски стиля шрифта
public final static int BOLD;
public final static int ITALIC;
public final static int PLAIN
// -----------------------------------------------------
// Конструктор
// -----------------------------------------------------
public Font(String name, int style, int size);
// -----------------------------------------------------
// Методы
// -----------------------------------------------------
// Сравнение шрифтов
public boolean equals(Object obj);
// Определение названия семейства шрифтов
public String getFamily();
// Получение шрифта по его характеристикам
public static Font getFont(String nm);
public static Font getFont(String nm, Font font);
// Определение названия шрифта
public String getName();
// Определение размера шрифта
public int getSize();
// Определение стиля шрифта
public int getStyle();
// Получение хэш-кода шрифта
public int hashCode();
// Определение жирности шрифта
public boolean isBold();
// Проверка, является ли шрифт наклонным
public boolean isItalic();
// Проверка, есть ли шрифтовое выделение
public boolean isPlain();
// Плучение текстовой строки для объекта
public String toString();
}
Создавая шрифт конструктором Font, вы должны указать имя, стиль и размер шрифта.
В качестве имени можно указать, например, строки Arial или Courier. Учтите, что в системе удаленного пользователя, загрузившего ваш аплет, может не найтись шрифта с указанным вами именем. В этом случае навигатор заменит его на наиболее подходящий (с его точки зрения).
Стиль шрифта задается масками BOLD, ITALIC и PLAIN, которые можно комбинировать при помощи логической операции “ИЛИ”:
Маска |
Описание |
BOLD |
Утолщенный шрифт |
ITALIC |
Наклонный шрифт |
PLAIN |
Шрифтовое выделение не используется |
Выход курсора мыши из области окна аплета
Метод mouseExit вызывается при покидании куросром окна аплета:
public boolean mouseExit(Event evt, int x, int y);
Если пользователь убрал курсор из окна аплета, активизированного методом mouseEnter, то метод mouseExit может переключить аплет в пассивное состояние.
Выполнение операции Drag and Drop
Операция Drag and Drop выполняется следующим образом: пользователь нажимает клавишу мыши и, не отпуская ее, начинает перемещать курсор мыши. При этом происходит вызов метода mouseDrag:
public boolean mouseDrag(Event evt, int x, int y);
Через переменные x и y передаются текущие координаты курсора мыши. Метод mouseDrag вызывается даже в том случае, если в процессе перемещения курсор вышел за пределы окна аплета.
Взгляд на исходный текст приложения Hello
Давайте теперь взглянем еще раз на исходный текст приложения Hello и посмотрим, что там к чему. Так как этот текст невелик, для удобства приведем его снова:
public class hello
{
public static void main(String[] args)
{
System.out.println("Hello, Java!\n");
}
}
В приложении определен один класс public с именем hello. Исходный файл приложения Java может содержать только один класс public, причем имя файла должно в точности соответствовать имени такого класса. В данном случае исходный файл называется hello.java. Если бы вы назвали файл Hello.java, компилятор выдал бы сообщение об ошибке.
В классе hello мы определили один статический метод с именем main. Статическая функция с этим именем является точкой входа приложения Java, если она определена с классе public с именем, таким же как и имя файла.
В качестве параметра функции main передается ссылка на массив строк класса String. Через эти строки вы можете передавать приложению Java параметры запуска.
Как наше приложение выводит текстовую строку на консоль?
В классе System определена переменная класса PrintStream с именем out. В классе PrintStream определен метод println, при помощи которой наше приложение выводит сообщение “Hello, Java!” на консоль.
Но где же объект, для которого вызывается метод println? В классе System поле PrintStream определено как статическое, поэтому методы этого класса можно вызывать, не создавая объектов класса, чем мы и воспользовались.
Как видите, текст пристейшего приложения Java по своей сложности не намного превосходит исходный текст программы аналогичного назначения, составленной на языке программирования С.
Задание области ограничения
Если для окна аплета задать область ограничения, то рисование будет возможно только в пределах этой области. Область ограничения задается методом clipRect, прототип которого мы привели ниже:
public abstract void
clipRect(int x, int y, int width, int height);
Параметры x, y, width и height задают координаты прямоугольной области ограничения.
Замещающие классы
Очень часто в наших приложениях вместо базовых типов переменных мы будем использовать объекты встроенных классов, которые называются замещающими классами (wrapper classes). Ниже мы перечислили названия этих классов и названия базовых типов данных, которые они замещают:
Базовый тип данных | Замещающий класс | ||
boolean | Boolean | ||
char | Character | ||
int | Integer | ||
long | Long | ||
float | Float | ||
double | Double |
Заметим, что для преобразования базовых типов данных в объекты замещающего класса и обратно вы не можете применять оператор присваивания. Вместо этого необходимо использовать соответствующие методы замещающих классов, которые мы будем рассматривать по ходу дела. Полную информацию о классах и методах вы сможете найти в справочной системе, которая устанавливается вместе с Microsoft Visual J++, поэтому в нашей книге вы не найдете справочника по классам Java.