Иерархия классов
Заглянем в документацию. Выберите из меню Help главного окна приложения Java WorkShop строку Java API Documentation. На экране появится окно браузера, встроенного в Java WorkShop. С помощью этого браузера вы сможете просматривать содержимое справочной системы.
В разделе Java API Packages выберите библиотеку классов java.applet, а затем в разделе Class Index - строку Applet. Вы увидите иерархию классов:
java.lang.Object | +---java.awt.Component | +---java.awt.Container | +---java.awt.Panel | +---java.applet.Applet
Из этой иерархии видно, что класс java.applet.Applet произошел от класса java.awt.Panel. Этот класс, в свою очередь, определен в библиотеке классов java.awt и произошел от класса java.awt.Container.
Продолжим наши исследования. В классе java.awt.Container снова нет метода paint, но сам этот класс создан на базе класса java.awt.Component.
Но и здесь метода paint нет. Этот метод определен в классе java.awt.Component, который, в свою очередь, произошел от класса java.lang.Object и реализует интерфейс java.awt.image.ImageObserver.
Таким образом мы проследили иерархию классов от класса java.applet.Applet, на базе которого создан наш аплет, до класса java.lang.Object, который является базовым для всех классов в Java.
Метод paint определен в классе java.awt.Component, но так как этот класс является базовым для класса Applet и для нашего класса HelloApplet, мы можем переопределить метод paint.
Исходный текст аплета
Полный исходный текст аплета, созданный автоматически мастером проектов Java WorkShop, мы представили в листинге 1.
Листинг 1. Файл HelloApplet.java
import java.applet.Applet; public class HelloApplet extends Applet { /** * Initializes the applet. You never need to * call this directly; it is * called automatically by the system once the * applet is created. */ public void init() {}
/** * Called to start the applet. You never need * to call this directly; it * is called when the applet's * document is visited. */ public void start() {}
/** * Called to stop the applet. This is called * when the applet's document is * no longer on the screen. It is guaranteed * to be called before destroy() * is called. You never need to * call this method directly */ public void stop() {}
/** * Cleans up whatever resources are being held. * If the applet is active * it is stopped. */ public void destroy() {} }
Из-за обилия комментариев вы можете подумать, что исходный текст аплета, который ничего не делает, слишком сложный. Однако это вовсе не так. Вот что получится, если мы уберем все комментарии:
import java.applet.Applet; public class HelloApplet extends Applet { public void init() {} public void start() {} public void stop() {} public void destroy() {} }
Исходный текст нашего аплета начинается со строки, подключающей оператором import библиотеку классов java.applet.Applet.
Оператор import должен располагаться в файле исходного текста перед другими операторами (за исключением операторов комментария). В качестве параметра оператору import передается имя подключаемого класса из библиотеки классов. Если же необходимо подключить все классы данной библиотеки, вместо имени класса указывается символ "*".
Напомним, что библиотека java.applet.Applet содержит классы, необходимые для создания аплетов, то есть разновидности приложений Java, встраиваемых в документы HTML и работающих под управлением браузера Internet.
Еще одна библиотека классов, которая нам скоро понадобится, это java.awt. С ее помощью аплет может выполнять в своем окне рисование различных изображений или текста. Преимущества данного метода перед использованием для рисования традиционного программного интерфейса операционной системы заключаются в том, что он работает на любой компьютерной платформе.
Далее в исходном тексте аплета определяется класс типа public с именем HelloApplet. Напомним, что это имя должно обязательно совпадать с именем файла, содержащего исходный текст этого класса.
public class HelloApplet extends Applet { . . . }
Определенный нами класс HelloApplet с помощью ключевого слова extends наследуется от класса Applet. При этом методам класса HelloApplet становятся доступными все методы и данные класса, за исключением определенных как private. Класс Applet определен в библиотеке классов java.applet.Applet, которую мы подключили оператором import.
Исходный текст документа HTML
Кроме файла исходного текста аплета мастер проектов создал файл документа HTML HelloApplet.tmp.html, представленный в листинге 2.
Листинг 2. Файл HelloApplet.tmp.html
<applet name="HelloApplet" code="HelloApplet" codebase="file:/e:/sun/vol3/src/HelloApplet" width="500" height="600" align="Top" alt="If you had a java-enabled browser, you would see an applet here."> </applet>
С помощью оператора <applet> наш аплет встраивается в этот документ. Оператор <APPLET> используется в паре с оператором </APPLET> и имеет следующие параметры:
Параметр | Описание | |
ALIGN | Выравнивание окна аплета относительно окружающего его текста. Возможны следующие значения:
LEFT - выравнивание влево относительно окружающего текста; CENTER - центрирование; RIGHT - выравнивание вправо относительно окружающего текста; TOP - выравнивание по верхней границе; MIDDLE - центрирование по вертикали; BOTTOM - выравнивание по нижней границе | |
ALT | С помощью этого параметра можно задать текст, который будет отображаться в окне аплета в том случае, если браузер не может работать с аплетами Java | |
CODE | Имя двоичного файла, содержащего байт-код аплета. По умолчанию путь к этому файлу указывается относительно каталога с файлом HTML, в который встроен аплет. Такое поведение может быть изменено параметром CODEBASE | |
CODEBASE | Базовый адрес URL аплета, то есть путь к каталогу, содержащему аплет | |
HEIGHT | Ширина окна аплета в пикселах | |
WIDTH | Высота окна аплета в пикселах | |
HSPACE | Зазор слева и справа от окна аплета | |
VSPACE | Зазор сверху и снизу от окна аплета | |
NAME | Идентификатор аплета, который может быть использован другими аплетами, расположенными в одном и том же документе HTML, а также сценариями JavaScript | |
TITLE | Строка заголовка |
Дополнительно между операторами <APPLET> и </APPLET> вы можете задать параметры аплета. Для этого используется оператор <PARAM>, который мы рассмотрим позже.
В нашем случае идентификатор NAME и имя двоичного файла заданы мастером проекта как "HelloApplet":
name="HelloApplet" code="HelloApplet"
Параметр CODEBASE задает путь к каталогу локального диска:
codebase="file:/e:/sun/vol3/src/HelloApplet"
Когда вы будете размещать документ HTML на сервере, параметр CODEBASE необходимо изменить или удалить, если этот документ и аплет располагаются в одном каталоге. В любом случае, если параметр CODEBASE задан, он должен указывать адрес URL каталога с аплетом.
Изменяем исходный текст аплета
Теперь давайте попробуем немного изменить исходный текст аплета, чтобы заставить его рисовать в своем окне текстовую строку "Hello, Java world".
Вначале измените исходный текст так, как это показано на рис. 6.
Рис. 6. Измененный исходный текст аплета HelloApplet |
Здесь мы намеренно внесли в исходный текст ошибку, чтобы показать, как Java WorkShop отреагирует на нее. Как видно из рисунка, сообщение об ошибке отображается на странице блокнота с названием Build. Текст сообщения гласит, что компилятор не смог найти определение класса Graphics, на который есть ссылка в девятой строке.
Добавим строку импортирования класса java.awt.*, как это показано в листинге 3.
Листинг 3. Файл HelloApplet.java (новый вариант)
import java.applet.Applet; import java.awt.*;
public class HelloApplet extends Applet { public String getAppletInfo() { return "HelloJava Applet"; } public void paint(Graphics g) { g.drawString("Hello, Java world!", 20, 20); } }
Теперь исходный текст аплета транслируется без ошибок (рис. 7).
Рис. 7. Измененный исходный текст успешно оттранслирован |
Если запустить аплет на выполнение, в его окне будет нарисована строка "Hello, Java world" (рис. 8).
![](image/pic08.gif)
Рис. 8. Теперь наш аплет "умеет" рисовать в своем окне текстовые строки
Метод destroy
Перед удалением аплета из памяти вызывается метод destroy, который определен в базовом классе Applet как пустая заглушка. Мастер проектов добавляет в исходный текст класса переопределение метода destroy, которое вы можете при необходимости изменить.
Методу destroy обычно поручают все необходимые операции, которые следует выполнить перед удалением аплета. Например, если в методе init вы создавали какие-либо потоки, в методе destroy их нужно завершить.
Метод getAppletInfo
Базовый класс Applet содержит определение метода getAppletInfo, возвращающее значение null. В нашем классе HelloApplet, который является дочерним по отношению к классу Applet, мы переопределили метод getAppletInfo из базового класса следующим образом:
public String getAppletInfo() { return "HelloJava Applet"; }
Теперь метод getAppletInfo возвращает текстовую информацию об аплете в виде объекта класса String.
Этой информацией могут воспользоваться другие аплеты или сценарии JavaScript, например, для определения возможности взаимодействия с аплетом.
Метод init
Метод init определен в базовом классе Applet, от которого наследуются все аплеты. Определение его таково, что этот метод ровным счетом ничего не делает.
Когда вызывается метод init и зачем он нужен?
Метод init вызывается тогда, когда браузер загружает в свое окно документ HTML с оператором <APPLET>, ссылающимся на данный аплет. В этот момент аплет может выполнять инициализацию, или, например, создавать потоки, если он работает в многопоточном режиме.
Существует контрпара для метода init - метод destroy. О нем мы расскажем ниже.
Метод paint
Наиболее интересен для нас метод paint, который выполняет рисование в окне аплета. Вот его исходный текст:
public void paint(Graphics g) { g.drawString("Hello, Java world!", 20, 20); }
Если посмотреть определение класса Applet, которое находится в файле JavaWorkshop20\JDK\src\java\applet\Applet.java, то в нем нет метода paint. В каком же классе определен этот метод?
Метод start
Метод start вызывается после метода init в момент, когда пользователь начинает просматривать документ HTML с встроенным в него аплетом.
Вы можете модифицировать текст этого метода, если при каждом посещении пользователем страницы с аплетом необходимо выполнять какую-либо инициализацию.
Метод stop
Дополнением к методу start служит метод stop. Он получает управление, когда пользователь покидает страницу с аплетом и загружает в окно браузера другую страницу. Заметим, что метод stop вызывается перед методом destroy.
Методы в классе HelloApplet
Создавая файл HelloApplet.java, мастер проектов системы Java WorkShop определила в классе HelloApplet несколько методов, заменив таким образом некоторые методы базового класса Applet.
Первый аплет Java
В предыдущем разделе мы создавали автономное приложение Java, работающее под управлением виртуальной машины Java. Теперь мы создадим приложение другого типа - аплет.
Аплет Java тоже выполняется под управлением виртуальной машины Java, но встроенной в браузер. Когда браузер загружает в свое окно документ HTML с аплетом, байт-код аплета начинает свою работу.
Внешне аплет выглядит как окно заданного размера. Он может рисовать внутри этого окна (и только в нем) произвольные изображения и текст.
Двоичный файл с интерпретируемым байт-кодом Java располагается на сервере Web. В документе HTML с помощью оператора <APPLET> организуется ссылка на этот двоичный файл.
Когда пользователь загружает в браузер документ HTML с аплетом, файл аплета переписывается с сервера Web на рабочую станцию пользователя. После этого браузер начинает его выполнение.
Возможно, вам не понравится такая идея, как запуск чужого аплета на своем компьютере - мало ли чего этот аплет может там сделать. Однако аплеты, в отличие от обычных приложений Java, сильно ограничены в своих правах. Например, они не могут читать локальные файлы и тем более в них писать. Есть также ограничения и на передачу данных через сеть: аплет может обмениваться данными только с тем сервером Web, с которого он был загружен.
Создание проекта аплета
Проект аплета создается таким же способом, что и проект автономного приложения Java, однако мастеру проектов необходимо указать другие параметры.
В первой диалоговой панели мастера проектов следует включить переключатели Applet и No GUI (рис. 1).
Рис. 1. Первая диалоговая панель мастера проектов |
Сделав это, нажмите кнопку Next. На экране появится вторая диалоговая панель мастера проектов. Здесь вы должны указать путь к каталогу, куда мастер проектов запишет файлы проекта, а также включить переключатель No (рис. 2).
Рис. 2. Вторая диалоговая панель мастера проектов |
В результате мастер проектов создаст исходные тексты аплета, а также добавит новый проект в портфель personal (если этот портфель остался активным в последний раз, когда вы запускали Java WorkShop). Новый проект называется HelloApplet (рис. 3).
![](image/sozdanie-proekta-apleta_1.gif)
Рис. 3. Новый проект появился в активном портфеле personal
Исходный текст аплета будет создан автоматически и загружен в окно редактирования системы Java WorkShop (рис. 4).
Рис. 4. Исходный текст аплета загружен в окно редактирования |
Вы можете оттранслировать полученный исходный текст и запустить аплет на выполнение. Он будет работать под управлением программы просмотра аплетов appletviewer, которая входит в состав Java WorkShop.
Пока в окне нашего аплета ничего нет (рис. 5), однако скоро мы исправим это положение.
![](image/sozdanie-proekta-apleta_2.gif)
Рис. 5. Окно аплета, созданного автоматически мастером проектов
Вызов метода paint
Метод paint вызывается, когда необходимо перерисовать окно аплета. Если вы создавали приложения для операционной системы Windows, то наверняка знакомы с сообщением WM_PAINT, которое поступает в функцию окна приложения при необходимости его перерисовки.
Перерисовка окна приложения Windows и окна аплета обычно выполняется асинхронно по отношению к работе приложения или аплета. В любой момент времени аплет должен быть готов перерисовать содержимое своего окна.
Такая техника отличается о той, к которой вы, возможно, привыкли, создавая обычные программы для MS-DOS. Программы MS-DOS сами определяют, когда им нужно рисовать на экране, причем рисование может выполняться из разных мест программы. Аплеты, так же как и приложения Windows, выполняют рисование в своих окнах централизованно. Аплет делает это в методе paint, а приложение Windows - при обработке сообщения WM_PAINT.
Обратите внимание, что методу paint в качестве параметра передается ссылка на объект Graphics:
public void paint(Graphics g) { . . . }
По своему смыслу этот объект напоминает контекст отображения, с которым хорошо знакомы создатели приложений Windows. Контекст отображения - это как бы холст, на котором аплет может рисовать изображение или писать текст. Многочисленные методы класса Graphics позволяют задавать различные параметры холста, такие, например, как цвет или шрифт.
Наше приложение вызывает метод drawString, который рисует текстовую строку в окне аплета:
g.drawString("Hello, Java world!", 20, 20);
Вот прототип этого метода:
public abstract void drawString(String str, int x, int y);
Через первый параметр методу drawString передается текстовая строка в виде объекта класса String. Второй и третий параметр определяют, соответственно, координаты точки, в которой начнется рисование строки.
В какой координатной системе?
Аплеты используют систему координат, которая соответствует режиму отображения MM_TEXT, знакомому тем, кто создавал приложения Windows. Начало этой системы координат расположено в левом верхнем углу окна аплета, ось X направлена слева направо, а ось Y - сверху вниз (рис. 9).
![](image/vyzov-metoda-paint_1.gif)
Рис. 9. Система координат, используемая методом drawString
На этом же рисунке показано, как метод drawString нарисует текстовую строку с координатами (xCoord, yCoord).
Аплет Draw
В этом разделе мы приведем исходные тексты аплета Draw, в которых демонстрируется использование различных функций рисования.
На рис. 11 показано окно этого аплета.
![](image/pic11.gif)
Рис. 11. Окно аплета Draw
В верхней части окна мы вывели список вех шрифтов, доступных аплету, а также примеры оформления строки Test string с использованием этих шрифтов.
В нижней части окна нарисовано несколько геометрических фигур.
Битовые маски стиля шрифта
BOLD
public final static int BOLD;
ITALIC
public final static int ITALIC;
PLAIN
public final static int PLAIN;
Документ HTML для аплета Draw
Документ HTML для аплета Draw не имеет никаких особенностей. Он представлен в листинге 2.
Листинг 2. Файл draw.tmp.html
<applet name="draw" code="draw" codebase="file:/e:/Sun/Articles/vol4/src/draw" width="250" height="350" align="Top" alt="If you had a java-enabled browser, you would see an applet here." > <param name="TestString" value="Test string"> <hr>If your browser recognized the applet tag, you would see an applet here.<hr> </applet>
Исходные тексты аплета Draw
Исходные тексты аплета Draw вы найдете в листинге 1.
Листинг 1. Файл draw.java
import java.applet.*; import java.awt.*;
public class draw extends Applet { Toolkit tk; String szFontList[]; FontMetrics fm; int yStart = 20; int yStep; String parm_TestString;
public void init() { tk = Toolkit.getDefaultToolkit(); szFontList = tk.getFontList(); parm_TestString = getParameter("TestString"); }
public String getAppletInfo() { return "Name: draw"; }
public void paint(Graphics g) { int yDraw; Dimension dimAppWndDimension = getSize();
g.clearRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
g.setColor(Color.yellow); g.fillRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
g.setColor(Color.black); g.drawRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
fm = g.getFontMetrics(); yStep = fm.getHeight();
for(int i = 0; i < szFontList.length; i++) { g.setFont(new Font("Helvetica", Font.PLAIN, 12)); g.drawString(szFontList[i], 10, yStart + yStep * i);
fm = g.getFontMetrics(); yStep = fm.getHeight();
g.setFont(new Font(szFontList[i], Font.PLAIN, 12)); g.drawString(parm_TestString, 100, yStart + yStep * i); }
yDraw = yStart + yStep * szFontList.length + yStep;
Polygon p = new Polygon();
p.addPoint(70, yDraw); p.addPoint(150, yDraw + 30); p.addPoint(160, yDraw + 80); p.addPoint(190, yDraw + 60); p.addPoint(140, yDraw + 30); p.addPoint(70, yDraw + 39);
g.drawPolygon(p);
g.setColor(Color.red); g.drawRect(10, yDraw + 85, 200, 100);
g.setColor(Color.black); g.drawArc(10, yDraw + 85, 200, 100, -50, 320); }
public String[][] getParameterInfo() { String[][] info = { { "TestString", "String", "Test string" } }; return info; } }
Извлечение списка шрифтов
Процедура извлечения списка доступных шрифтов достаточно проста и выполняется следующим образом:
Toolkit tk; String szFontList[]; . . . tk = Toolkit.getDefaultToolkit(); szFontList = tk.getFontList();
Аплет вызывает статический метод getDefaultToolkit из класса Toolkit и затем, пользуясь полученной ссылкой, извлекает список шрифтов, записывая его в массив szFontList.
Для чего еще можно использовать класс Toolkit?
Класс Toolkit является абстрактным суперклассом для всех реализаций AWT. Порожденные от него классы используются для привязки различных компонент конкретных реализаций.
Создавая свои аплеты, вы будете редко прибегать к услугам этого класса. Однако в нем есть несколько полезных методов, прототипы которых мы перечислим ниже:
getDefaultToolkit
Получение ссылки на Toolkit
public static Toolkit getDefaultToolkit();
getColorModel
Определение текущей цветовой модели, выбранной в контекст отображения
public abstract ColorModel getColorModel();
getFontList
Получение списка шрифтов, доступных аплету
public abstract String[] getFontList();
getFontMetrics
Получение метрик заданного шрифта
public abstract FontMetrics getFontMetrics(Font font);
getImage
Получение растрового изображения по имени файла
public abstract Image getImage(String filename);
getImage
Получение растрового изображения по адресу URL
public abstract Image getImage(URL url);
getScreenResolution
Определение разрешения экрана в точках на дюйм
public abstract int getScreenResolution();
getScreenSize
Размеры экрана в пикселах
public abstract Dimension getScreenSize();
prepareImage
Подготовка растрового изображения для вывода
public abstract boolean prepareImage( Image image, int width, int height, ImageObserver observer);
sync
Синхронизация состояния Toolkit
public abstract void sync();
Наиболее интересны, с нашей точки зрения, методы getFontList, getScreenResolution и getScreenSize, с помощью которых аплет может, соответственно, получить список шрифтов, определить разрешение и размер экрана. Последние два параметра позволяют сформировать содержимое окна аплета оптимальным образом исходя из объема информации, который может в нем разместиться.
Класс Font
Приведем краткое перечисление полей, конструкторов и методов этого класса.
Контекст отображения
Проще всего представить себе контекст отображения как полотно, на котором рисует художник. Точно так же как художник может выбирать для рисования различные инструменты, программист, создающий аплет Java, может выбирать различные методы класса Graphics и задавать различные атрибуты контекста отображения.
Копирование содержимого прямоугольной области
Метод copyArea позволяет скопировать содержимое любой прямоугольной области окна аплета:
public abstract void copyArea( int x, int y, int width, int height, int dx, int dy);
Параметры x, y, width и height задают координаты копируемой прямоугольной области. Область копируется в другую прямоугольную область такого же размера, причем параметры dx и dy определяют координаты последней.
Линии
Для того чтобы нарисовать прямую тонкую сплошную линию, вы можете воспользоваться методом drawLine, прототип которого приведен ниже:
public abstract void drawLine(int x1, int y1,int x2, int y2);
Концы линии имеют координаты (x1, y1) и (x2, y2), как это показано нарис. 1.
![](image/pic01.gif)
Рис. 1. Рисование прямой линии
К сожалению, в контексте отображения не предусмотрены никакие атрибуты, позволяющие нарисовать пунктирную линию или линию увеличенной толщины.
Метод init
При инициализации аплета метод init извлекает список доступных шрифтов и принимает значение параметра TestString, передаваемое аплету в документе HTML.
Метод paint
Первым делом метод paint определяет размеры окна аплета, вызывая для этого метод getSize:
Dimension dimAppWndDimension = getSize();
Метод getSize возвращает ссылку на объект класса Dimension, хранящий высоту и ширину объекта:
height
Высота
public int height;
width
Ширина
public int width;
В классе Dimension предусмотрено три конструктора и один метод:
public Dimension(); public Dimension(Dimension d); public Dimension(int width, int height);
toString
Получение строки, представляющей класс
public String toString();
После определения размеров окна аплета метод paint стирает содержимое всего окна:
g.clearRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
Далее в контексте отображения устанавливается желтый цвет:
g.setColor(Color.yellow);
Этим цветом заполняется внутренняя область окна аплета, для чего применяется метод fillRect:
g.fillRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
Затем метод paint устанавливает в контексте отображения черный цвет и рисует тонкую черную рамку вокруг окна аплета:
g.setColor(Color.black); g.drawRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height - 1);
На следующем этапе мы получаем метрики текущего шрифта, выбранного в контекст отображения:
fm = g.getFontMetrics();
Пользуясь этими метриками, мы определяем высоту символов текущего шрифта и записываем ее в поле yStep:
yStep = fm.getHeight();
После этого метод paint запускает цикл по всем шрифтам, установленным в системе:
for(int i = 0; i < szFontList.length; i++) { . . . }
Количество доступных шрифтов равно размеру массива szFontList, которое вычисляется как szFontList.length.
Метод paint выписывает в окне аплета название каждого шрифта, устанавливая для этого шрифт Helvetica размером 12 пикселов:
g.setFont(new Font("Helvetica", Font.PLAIN, 12)); g.drawString(szFontList[i], 10, yStart + yStep * i);
Смещение каждой новой строки с названием шрифта вычисляется исходя из высоты символов установленного шрифта:
fm = g.getFontMetrics(); yStep = fm.getHeight();
После названия шрифта метод paint рисует в окне аплета текстовую строку parm_TestString, полученную через параметр с именем "TestString":
g.setFont(new Font(szFontList[i], Font.PLAIN, 12)); g.drawString(parm_TestString, 100, yStart + yStep * i);
Перед тем как перейти к рисованию геометрических фигур, метод paint запоминает в поле yDraw координату последней строки названия шрифта, сделав отступ высотой yStep :
int yDraw; yDraw = yStart + yStep * szFontList.length + yStep;
Первая фигура, которую рисует наш аплет, это многоугольник.
Мы создаем многоугольник как объект класса Polygon:
Polygon p = new Polygon();
В этот объект при помощи метода addPoint добавляется несколько точек:
p.addPoint(70, yDraw); p.addPoint(150, yDraw + 30); p.addPoint(160, yDraw + 80); p.addPoint(190, yDraw + 60); p.addPoint(140, yDraw + 30); p.addPoint(70, yDraw + 39);
После добавления всех точек метод paint рисует многоугольник, вызывая для этого метод drawPolygon:
g.drawPolygon(p);
Затем мы устанавливаем в контексте отображения красный цвет и рисуем прямоугольник:
g.setColor(Color.red); g.drawRect(10, yDraw + 85, 200, 100);
Затем метод paint вписывает в этот прямоугольник сегмент окружности:
g.setColor(Color.black); g.drawArc(10, yDraw + 85, 200, 100, -50, 320);
Методы
clearRect
Стирание содержимого прямоугольной области
public abstract void clearRect(int x, int y, int width, int height);
clipRect
Задание области ограничения вывода
public abstract void clipRect(int x, int y, int width, int height);
copyArea
Копирование содержимого прямоугольной области
public abstract void copyArea(int x, int y, int width, int height, int dx, int dy);
create
Создание контекста отображения
public abstract Graphics create();
public Graphics create(int x, int y, int width, int height);
dispose
Удаление контекста отображения
public abstract void dispose();
draw3DRect
Рисование прямоугольной области с трехмерным выделением
public void draw3DRect(int x, int y, int width, int height, boolean raised);
drawArc
Рисование сегмента
public abstract void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle);
Рисование сегмента
drawBytes
Рисование текста из массива байт
public void drawBytes(byte data[], int offset, int length, int x, int y);
drawChars
Рисование текста из массива символов
public void drawChars(char data[], int offset, int length, int x, int y);
drawImage
Рисование растрового изображения
public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer);
public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer);
public abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer);
public abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer);
drawLine
Рисование линии
public abstract void drawLine(int x1, int y1, int x2, int y2);
drawOval
Рисование овала
public abstract void drawOval(int x, int y, int width, int height);
drawPolygon
Рисование многоугольника
public abstract void drawPolygon( int xPoints[], int yPoints[], int nPoints);
public void drawPolygon(Polygon p);
drawRect
Рисование прямоугольника
public void drawRect(int x, int y, int width, int height);
drawRoundRect
Рисование прямоугольника с круглыми углами
public abstract void drawRoundRect( int x, int y, int width, int height, int arcWidth, int arcHeight);
drawString
Рисование текстовой строки
public abstract void drawString(String str, int x, int y);
fill3DRect
Рисование заполненного прямоугольника с трехмерным выделением
public void fill3DRect(int x, int y, int width, int height, boolean raised);
fillArc
Рисование заполненного сегмента круга
public abstract void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle);
fillOval
Рисование заполненного овала
public abstract void fillOval(int x, int y, int width, int height);
fillPolygon
Рисование заполненного многоугольника
public abstract void fillPolygon( int xPoints[], int yPoints[], int nPoints);
fillPolygon
Рисование заполненного многоугольника
public void fillPolygon(Polygon p);
public abstract void fillRect(int x, int y, int width, int height);
fillRoundRect
Рисование заполненного прямоугольника с круглыми углами
public abstract void fillRoundRect( int x, int y, int width, int height, int arcWidth, int arcHeight);
finalize
Прослеживание вызова метода dispose
public void finalize();
getClipRect
Определение границ области ограничения вывода
public abstract Rectangle getClipRect();
getColor
Определение цвета, выбранного в контекст отображения
public abstract Color getColor();
getFont
Определение шрифта, выбранного в контекст отображения
public abstract Font getFont();
getFontMetrics
Определение метрик текущего шрифта
public FontMetrics getFontMetrics();
getFontMetrics
Определение метрик заданного шрифта
public abstract FontMetrics getFontMetrics(Font f);
setColor
Установка цвета для рисования в контексте отображения
public abstract void setColor(Color c);
setFont
Установка текущего шрифта в контексте отображения
public abstract void setFont(Font font);
setPaintMode
Установка режима рисования
Метод setPaintMode устанавливает в контексте отображения режим рисования, при котором выполняется замещение изображения текущим цветом, установленном в контексте отображения.
public abstract void setPaintMode();
setXORMode
Установка маски для рисования
Задавая маску для рисования при помощи метода setXORMode, вы можете выполнить при рисовании замещение текущего цвета на цвет, указанный в параметре метода, и наоборот, цвета, указанного в параметре метода, на текущий.
Все остальные цвета изменяются непредсказуемым образом, однако эта операция обратима, если вы нарисуете ту же самую фигуру два раза на одном и том же месте.
public abstract void setXORMode(Color c1);
translate
Сдвиг начала системы координат
Метод translate сдвигает начало системы координат в контексте отображения таким образом, что оно перемещается в точку с координатами (x, y), заданными через параметры метода:
public abstract void translate(int x, int y);
toString
Получение текстовой строки, представляющей данный контекст отображения
public String toString();
Методы класса Graphics
В качестве базового для класса Graphics (полное название класса java.awt.Graphics) выступает класс java.lang.Object.
Прежде всего мы приведем прототипы конструктора этого класса и его методов с краткими комментариями. Полное описание вы сможете найти в электронной документации, которая входит в комплект Java WorkShop.
Далее мы рассмотрим назначение основных методов, сгруппировав их по выполняемым функциям.
Многоугольники
Для рисования многоугольников в классе Graphics предусмотрено четыре метода, два из которых рисуют незаполненные многоугольники, а два - заполненные.
Первый метод рисует незаполненный многоугольник, заданный массивами координат по осям X и Y:
public abstract void drawPolygon( int xPoints[], int yPoints[], int nPoints);
Через параметры xPoints и yPoints передаются, соответственно, ссылки на массивы координат по оис X и Y. Параметр nPoints задает количество точек в массивах.
На рис. 6 показан многоугольник, нарисованный методом drawPolygon.
![](image/mnogougolniki_1.gif)
Рис. 6. Многоугольник, нарисованный методом drawPolygon
В этом многоугольнике шесть вершин с координатами от (x0,y0) до (x5, y5), причем для того чтобы он стал замкнутым, координаты первой и последней вершины совпадают.
Второй метод также рисует незаполненный многоугольник, однако в качестве параметра методу передается ссылка на объект Polygon:
public void drawPolygon(Polygon p);
Класс Polygon достаточно прост. Приведем описание его полей, конструкторов и методов:
Определение атрибутов контекста отображения
Ряд методов класса Graphics позволяет определить различные атрибуты контекста отображения, например, цвет, выбранный в контекст отображения или метрики текущего шрифта, которым выполняется рисование текста.
Рассмотрим методы, позволяющие определить атрибуты контекста отображения.
Определение цвета, выбранного в контекст отображения
Метод getColor возвращает ссылку на объект класса Color, представляющий текущий цвет, выбранный в контекст отображения:
public abstract Color getColor();
Определение границ области ограничения вывода
С помощью метода clipRect, о котором мы расскажем чуть позже, вы можете определить в окне аплета область ограничения вывода прямоугольной формы. Вне этой области рисование графических изображений и текста не выполняется.
Метод getClipRect позволяет вам определить координаты текущей области ограничения, заданной в контексте отображения:
public abstract Rectangle getClipRect();
Метод возвращает ссылку на объект класса Rectangle, который, в частности, имеет поля класса с именами x, y, height и width. В этих полях находится, соответственно, координаты верхнего левого угла, высота и ширина прямоугольной области.
Определение метрик текущего шрифта
Несмотря на то что вы можете заказать шрифт с заданным именем и размером, не следует надеяться, что навигатор выделит вам именно такой шрифт, какой вы попросите. Для правильного размещения текста и других изображений в окне аплета вам необходимо знать метрики реального шрифта, выбранного навигатором в контекст отображения.
Метрики текущего шрифта в контексте отображения вы можете узнать при помощи метода 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();
Овалы и круги
Для рисования окружностей и овалов вы можете воспользоваться методом drawOval:
public abstract void drawOval( int x, int y,
int width, int height);
Параметры этого методы задают координаты и размеры прямоугольника, в который вписывается рисуемый овал (рис. 8).
![](image/ovaly-i-krugi_1.gif)
Рис. 8. Рисование овала
Метод fillOval предназначен для рисования заполненного овала (рис. 9). Назначение его параметров аналогично назначению параметров метода drawOval:
public abstract void fillOval( int x, int y, int width, int height);
![](image/ovaly-i-krugi_2.gif)
Рис. 9. Рисование заполненного овала
Поля класса
name
protected String name;
size
protected int size;
style
protected int style;
npoints
Количество вершин
public int npoints;
xpoints
Массив координат по оси X
public int xpoints[];
ypoints
Массив координат по оси Y
public int ypoints[]
Получение значения параметров
До сих пор наши аплеты не получали параметров из документов HTML, в которые мы их встраивали.
Конечно, все константы, текстовые строки, адреса URL и другую информацию можно закодировать непосредственно в исходном тексте аплета, однако, очевидно, это очень неудобно.
Пользуясь операторами <PARAM>, расположенными в документе HTML сразу после оператора <APPLET>, можно передать аплету произвольное количество параметров, например, в виде текстовых строк:
<applet code=MyApplet.class id=MyApplet . . . width=320 height=240 > <param name=ParamName1 value="Value 1"> <param name=ParamName2 value="Value 2"> <param name=ParamName3 value="Value 3"> <param name=ParamName4 value="Value 4"> . . . </applet>
Здесь через параметр NAME оператора <PARAM> передается имя параметра аплета, а через параметр VALUE - значение соответствующего параметра.
Как параметр может получить значение параметров?
Для получения значения любого параметра аплет должен использовать метод getParameter. В качестве единственного параметра этому методу передается имя параметра аплета в виде строки типа String, например:
parm_TestString = getParameter("TestString");
Обычно в аплете также определяется метод getParameterInfo, возвращающий информацию о параметрах. Вот исходный текст этого метода для нашего аплета Draw:
public String[][] getParameterInfo() { String[][] info = { { "TestString", "String", "Test string" } }; return info; }
Метод getParameterInfo возвращает массив массивов текстовых строк. Первая строка указывает имя параметра, вторая - тип передаваемых через него данных, а третья - значение параметра по умолчанию.
Прямоугольники и квадраты
Среди методов класса Graphics есть несколько, предназначенных для рисования прямоугольников. Первый из них, с именем drawRect, позволяет нарисовать прямоугольник, заданный координатами своего левого верхнего угла, шириной и высотой:
public void drawRect(int x, int y, int width, int height);
Параметры x и y задают, соответственно, координаты верхнего левого угла, а параметры width и height - высоту и ширину прямоугольника (рис. 2).
![](image/pic02.gif)
Рис. 2. Рисование прямоугольника
В отличие от метода drawRect, рисующего только прямоугольную рамку, метод fillRect рисует заполненный прямоугольник. Для рисования и заполнения прямоугольника используется цвет, выбранный в контекст отображения (рис. 3).
![](image/prjamougolniki-i-kvadraty_1.gif)
Рис. 3. Рисование заполненного прямоугольника
Прототип метода fillRect приведен ниже:
public abstract void fillRect(int x, int y, int width, int height);
Метод drawRoundRect позволяет нарисовать прямоугольник с закругленными углами:
public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
Параметры x и y определяют координаты верхнего левого угла прямоугольника, параметры width и height задают, соответственно его ширину и высоту.
Размеры эллипса, образующего закругления по углам, вы можете задать с помощью параметров arcWidth и arcHeight. Первый из них задает ширину эллипса, а второй - высоту (рис. 4).
![](image/pic04.gif)
Рис. 4. Рисование прямоугольника с закругленными углами
Метод fillRoundRect позволяет нарисовать заполненный прямоугольник с закругленными углами (рис. 5).
![](image/prjamougolniki-i-kvadraty_2.gif)
Рис. 5. Рисование заполненного прямоугольника с закругленными углами
Назначение параметров этого метода аналогично назначению параметров только что рассмотренного метода drawRoundRect:
public abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
Метод fill3Drect предназначен для рисования выступающего или западающего прямоугольника:
public void fill3DRect(int x, int y, int width, int height, boolean raised);
Если значение параметра raised равно true, рисуется выступающий прямоугольник, если false - западающий. Назначение остальных параметров аналогично назначению параметров метода drawRect.
Проект для аплета Draw
Подготовьте файлы проекта аплета Draw, скопировав их из предыдущего раздела в какой-нибудь каталог. Затем запустите мастер проектов и в соответствующей диалоговой панели укажите путь к этому каталогу (рис. 12).
Рис. 12. Указание пути к каталогу с исходными файлами |
Так как в каталоге уже есть файлы, вы должны включить переключатель Yes и затем нажать кнопку Next.
После этого вы увидите на экране диалоговую панель, показанную на рис. 13.
Рис. 13. Добавление к проекту существующих файлов |
Здесь вам нужно нажать кнопку Add All in Directory. Как только вы это сделаете, в списке файлов Project Files появится имя файла draw.java, подготовленного вами заранее.
На следующем шаге вам опять нужно нажать кнопку Next и проследить, чтобы имя главного класса аплета, отображаемое в диалоговой панели, показанной на рис. 14, было draw.
Рис. 14. Задание имени главного класса |
Нажав кнопку Finish, вы можете завершить формирование проекта.
Hаш аплет принимает из документа HTML один параметр с именем TestString. Для добавления параметров вам нужно открыть окно менеджера проектов, выбрав из меню Project строку Show Project Manager. В этом окне проект draw должен быть текущим.
Выделите его курсором мыши в окне Java WorkShop Project Manager и из меню Project этого окна выберите строку Edit. Вы увидите блокнот Project Edit, с помощью которого можно изменять различные параметры проекта. Откройте в этом блокноте страницу Run (рис. 15).
Рис. 15. Добавление параметра TestString |
В полях Name и Value введите, соответственно, имя параметра и значение параметра по умолчанию, а затем нажмите кнопку Add. Добавленный вами параметр появится в списке Parameters. Теперь вам осталось только нажать кнопку OK.
Рисование геометрических фигур
В этом разделе мы опишем методы класса Graphics, предназначенные для рисования элементарных геометрических фигур, таких как линии, прямоугольники, окружности и так далее.
Рисование в окне аплета
В предыдущем разделе мы привели простейший пример аплета, который выполняет рисование текстовой строки в своем окне. Теперь мы расскажем вам о том, что и как может рисовать аплет.
Способ, которым аплет выполняет рисование в своем окне, полностью отличается от того, которым пользуются программы MS-DOS. Вместо того чтобы обращаться напрямую или через драйвер к регистрам видеоконтроллера, аплет пользуется методами из класса Graphics. Эти методы инкапсулируют все особенности аппаратуры, предоставляя в распоряжение программиста средство рисования, которое пригодно для любой компьютерной платформы.
Для окна аплета создается объект класса Graphics, ссылка на который передается методу paint. Раньше мы уже пользовались этим объектом, вызывая для него метод drawString, рисующий в окне текстовую строку. Объект, ссылка на который передается методу paint, и есть контекст отображения. Сейчас мы займемся контекстом отображения вплотную.
Сегменты
Метод drawArc предназначен для рисования незаполненного сегмента (рис. 10). Прототип этого метода приведен ниже:
public abstract void drawArc( int x, int y, int width, int height, int startAngle, int arcAngle);
![](image/pic10.gif)
Рис. 10. Рисование незаполненного сегмента
Параметры x, y, width и height задают координаты прямоугольника, в который вписан сегмент.
Параметры startAngle и arcAngle задаются в градусах. Они определяют, соответственно, начальный угол и угол разворота сегмента.
Для того чтобы нарисовать заполненный сегмент, вы можете воспользоваться методом fillArc:
public abstract void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle);
Установка атрибутов контекста отображения
Изменяя атрибуты контекста отображения, приложение 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("Hello, Java world!", 10, 20); . . . }
Здесь мы привели фрагмент исходного текста метода paint, в котором в контексте отображения устанавливается желтый цвет. После этого метод drawString выведет текстовую строку " Hello, Java world!" желтым цветом.
Если необходима более точная установка цвета, вы можете воспользоваться одним из трех конструкторов объекта 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.
Задание области ограничения
Если для окна аплета задать область ограничения, то рисование будет возможно только в пределах этой области. Область ограничения задается методом clipRect, прототип которого мы привели ниже:
public abstract void clipRect( int x, int y, int width, int height);
Параметры x, y, width и height задают координаты прямоугольной области ограничения.