Заключение
Апплеты были первоначальным практическим применением Java. За первые два года существования Java были написаны тысячи очень интересных и красивых апплетов, ожививших WWW. Масса апплетов разбросана по Internet, хорошие примеры апплетов собраны в JDK в каталоге demoapplets.
В JDK вошел целый пакет java.applet, в который фирма SUN собиралась заносить классы, развивающие и улучшающие апплеты.
С увеличением скорости и улучшением качества компьютерных сетей значение апплетов сильно упало. Теперь вся обработка данных, прежде выполняемая апплетами, переносится на сервер, браузер только загружает и показывает результаты этой обработки, становится "тонким клиентом".
С другой стороны, появилось много специализированных программ, в том числе написанных на Java, загружающих информацию из Internet. Такая возможность есть сейчас у всех музыкальных и видеопроигрывателей.
Фирма SUN больше не развивает пакет java.applet. В нем так и остался один класс и три интерфейса. В библиотеку Swing вошел класс JApplet, расширяющий класс Applet. В нем есть дополнительные возможности, например, можно установить систему меню. Он способен использовать все классы библиотеки Swing. Но большинство браузеров еще не имеют Swing в своем составе, поэтому приходится загружать классы Swing с сервера или включать их в jar-архив вместе с классами апплета.
Список литературы
1. Учебник по JBuilder
2. Borland® JBuilder™ Developers Guide
Приложение
// реализация класса CircleClock
package clock;
/*
* CircleClock.java
*
* Created on май 2009 г.
*/
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.util.Calendar;
/**
*
* @author Бочкарева Мария
*/
public class CircleClock extends java.applet.Applet implements Runnable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Needle hNeedle, mNeedle, sNeedle;
private ClockDial dial;
private int w, h;
private BufferedImage bi;
private Graphics2D big;
private boolean stop = false;
private Thread timer = null;
private Color dialColor = Color.YELLOW;
private Color hairLineColor = Color.GREEN;
private Color hoursColor = Color.BLACK;
private Color minutesColor = Color.BLUE;
private Color secondsColor = Color.RED;
/** Этот метод будет вызван после загрузки апплета */
public void init() {
try {
//Создаем объекты и устанавливаем начальные значения.
Dimension dim = getSize();
w = dim.width;
h = dim.height;
//устанавливаем цвета стрелок и циферблата
setColors();
//Создаем стрелки
int radius = 0;
if(w < h)
radius = w/2;
else
radius = h/2;
mNeedle = new Needle(radius, radius/5); //минутная стрелка
hNeedle = new Needle(2d/3d*radius, radius/4); //часовая стрелка
sNeedle = new Needle(radius, radius/10); //секундная стрелка
//создаем циферблат
dial = new ClockDial(radius*2, dialColor, hairLineColor);
//Создаем изображение и получаем его объект Graphics2D.
//Рисовать будем только на нем, а экран выводим уже
//готовый рисунок (т.н. двойная буферезация).
bi = (BufferedImage)createImage(w, h);
big = bi.createGraphics();
big.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//Создаем поток, который будет периодически вызывать метод update.
timer = new Thread(this);
timer.start();
}
catch(Exception error) {
System.out.println(error.getMessage());
}
}
/** Этот метод выполняет перерисовку окна апплета */
public void update(Graphics g) {
try {
//Получаем указатель на объект Graphics2D
Graphics2D g2 = (Graphics2D)g;
grawClock();
//Рисуем готовое изображение на экране
g2.drawImage(bi, 0, 0, this);
big.setTransform(new AffineTransform());
}
catch(Exception error) {
System.out.println(error.getMessage());
}
}
private void grawClock() {
//Узнаем текущее время
Calendar curTime = Calendar.getInstance();
curTime.setTimeInMillis(System.currentTimeMillis());
double hour = curTime.get(Calendar.HOUR_OF_DAY);
double min = curTime.get(Calendar.MINUTE);
double sec = curTime.get(Calendar.SECOND);
//Очищаем рисунок
big.setBackground(Color.WHITE);
big.clearRect(0, 0, w, h);
//Рисуем циферблат
Point luCorner = new Point(0, 0);
if(w > h)
{
luCorner.x = (w - h)/2;
luCorner.y = 0;
}
else
{
luCorner.x = 0;
luCorner.y = (h - w)/2;
}
big.drawImage(dial.getClockDial(), null, luCorner.x, luCorner.y);
//Рисуем стрелки
big.setColor(hoursColor);
AffineTransform hat = new AffineTransform();
hat.translate(w/2 - hNeedle.getRotationCenter().x,
h/2 - hNeedle.getRotationCenter().y);
/*Рассчитываем угол поворота часовой стелки. Каждый час на
12-ти часовом циферблате соответствует 30-ти градусам, а 1
минута - 0.5 градуса. Затем результат переводим в радианы. */
if(hour >= 12)
hour -= 12;
double theta = (-90 + (30*hour + 0.5*min))*Math.PI/180;
hat.rotate(theta, hNeedle.getRotationCenter().x,
hNeedle.getRotationCenter().y);
big.setTransform(hat);
big.fill(hNeedle.getNeedle());
big.setColor(minutesColor);
AffineTransform mat = new AffineTransform();
mat.translate(w/2 - mNeedle.getRotationCenter().x,
h/2 - mNeedle.getRotationCenter().y);
/*Рассчитываем угол поворота минутной стелки. Каждая минута на
12-ти часовом циферблате соответствует 6-ти градусам, а 1
секунда - 0.1 градуса. Затем результат переводим в радианы. */
theta = (-90 + (6*min + 0.1*sec))*Math.PI/180;
mat.rotate(theta, mNeedle.getRotationCenter().x,
mNeedle.getRotationCenter().y);
big.setTransform(mat);
big.fill(mNeedle.getNeedle());
big.setColor(secondsColor);
AffineTransform sat = new AffineTransform();
sat.translate(w/2 - sNeedle.getRotationCenter().x,
h/2 - sNeedle.getRotationCenter().y);
/*Рассчитываем угол поворота сеундной стелки. Каждая секунда на
12-ти часовом циферблате соответствует 6-ти градусам.
Затем результат переводим в радианы. */
theta = (-90 + (6*sec))*Math.PI/180;
sat.rotate(theta, sNeedle.getRotationCenter().x,
sNeedle.getRotationCenter().y);
big.setTransform(sat);
big.fill(sNeedle.getNeedle());
}
//Этот метод читает параметры апплета, и устанавливает
//цвета стрелок и циферблата.
private void setColors() {
try {
/* Вообще-то, для задания цвета нужно число типа int, т.е. 4 байта,
но int - это число со знаком (от "-2^31" до "2:31 - 1"), а нам
нужно число с диапазоном от "0" до "2^32", т.е. те же 4 байта,
но без знака. Для этого мы сначала создаем число типа Long, а
затем, с помощью метода intValue() получаем тип int.
*/
Long dc = new Long(Long.parseLong(getParameter("dialColor"), 16));
Long hlc = new Long(Long.parseLong(getParameter("hairLineColor"), 16));
Long hnc = new Long(Long.parseLong(getParameter("hoursNeedleColor"), 16));
Long mnc = new Long(Long.parseLong(getParameter("minutesNeedleColor"), 16));
Long snc = new Long(Long.parseLong(getParameter("secondsNeedleColor"), 16));
dialColor = new Color(dc.intValue(), true);
hairLineColor = new Color(hlc.intValue(), true);
hoursColor = new Color(hnc.intValue(), true);
minutesColor = new Color(mnc.intValue(), true);
secondsColor = new Color(snc.intValue(), true);
}
catch(Exception error) {
System.out.println(error.getMessage());
}
}
//Этот метод выполняется в отдельном потоке (timer).
//Он вызывает перерисовку окна апплета каждую секунду.
public void run() {
while(!stop) {
try {
repaint();
Thread.currentThread().sleep(1000);
}
catch(Exception err) {}
}
}
//Этот метод выполняется если пользователь покинул страницу
//с апплетом. Он останавливает поток (timer) и, соответственно,
//перерисовку окна апплета.
public void stop() {
super.stop();
stop = true;
}
//Этот метод выполняется когда пользователь попадает на страницу
//с апплетом. Он запускает парралельный поток (timer).
public void start() {
super.start();
stop = false;
if(timer == null) {
timer = new Thread(this);
timer.start();
}
}
//Этот метод выполняется при закрытии страницы с апплетом.
public void destroy() {
super.destroy();
stop = true;
//Ждем пока парралельный поток (timer) завершит работу.
Thread.currentThread().yield();
}
public String[][] getParameterInfo() {
String[][] retValue = {
{"dialColor", "hex", "alfa, red, green, blue (4 bytes, from 00 to FF)"},
{"hairLineColor", "hex", "alfa, red, green, blue (4 bytes, from 00 to FF)"},
{"hoursNeedleColor", "hex", "alfa, red, green, blue (4 bytes, from 00 to FF)"},
{"minutesNeedleColor", "hex", "alfa, red, green, blue (4 bytes, from 00 to FF)"},
{"secondsNeedleColor", "hex", "alfa, red, green, blue (4 bytes, from 00 to FF)"}
};
return retValue;
}
public String getAppletInfo() {
String retValue;
retValue = "Circle Clock";
return retValue;
}
}
// реализация класса ClockDial
package clock;
/*
* ClockDial.java
*
* Created on май 2009 г.
*/
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
/**
*
* @author Бочкарева Мария
*/
public class ClockDial {
private double diam;
private BufferedImage dial;
private Color dialColor;
private Color hairLineColor;
/** Создает экземпляры <code>ClockDial</code>. При создании
* необходимо указать диаметр циферблата.
*
* @param diam диаметр циферблата.
*
* @param dialColor цвет циферблата.
*
* @param hairLineColor цвет черточек на циферблате.
*
* @exception IncorrectParametersException - если диаметр меньше
* или равен нулю.
*/
public ClockDial(double diam, Color dialColor, Color hairLineColor)
throws IncorrectParametersException {
//проверяем диаметр
if(diam <= 0)
throw new IncorrectParametersException();
this.diam = diam;
this.dialColor = dialColor;
this.hairLineColor = hairLineColor;
//создаем рисунок
dial = new BufferedImage((int)diam, (int)diam,
BufferedImage.TYPE_INT_ARGB);
//создаем черточку на циферблате
Rectangle2D.Double r = new Rectangle2D.Double(-diam/40, -diam/60, diam/20, diam/30);
AffineTransform at = new AffineTransform();
//смещаем начало координат в центр циферблата
at.translate(diam/2, diam/2);
//сохраняем текущее преобразование
AffineTransform prev = (AffineTransform)at.clone();
//получаем графический контекст
Graphics2D g2 = dial.createGraphics();
//закрашиваем все заданным цветом
g2.setBackground(dialColor);
g2.clearRect(0, 0, (int)diam, (int)diam);
//устанавливаем цвет черточек
g2.setColor(hairLineColor);
//рисуем 12 штрихов
for(int i = 0; i < 12; i++)
{
//смещаем центр координат к краю циферблата (туда,
//где должен быть расположен штрих)
at.translate(-(diam/2 - r.width), 0);
//поворачиваем штрих относительно центра циферблата
at.rotate(Math.toRadians(30*i), diam/2 - r.width, 0);
//устанавливаем текущее преобразование
g2.setTransform(at);
//рисуем штрих
g2.fill(r);
//восстанавливаем начальное преобразование
at.setTransform(prev);
}
}
/**
* Возвращает изображение циферблата.
*
* @return BufferedImage рисунок, содержащий изображение циферблата
*/
public BufferedImage getClockDial() {
return dial;
}
}
// реализация класса IncorrectParametersException
package clock;
/*
* IncorrectParameters.java
*
* Created on май 2009 г.
* */
/**
*
* @author Бочкарева Мария
*/
public class IncorrectParametersException extends java.lang.Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new instance of <code>IncorrectParameters</code> without detail message.
*/
public IncorrectParametersException() {
this("IncorrectParameters");
}
/**
* Constructs an instance of <code>IncorrectParameters</code> with the specified detail message.
* @param msg the detail message.
*/
public IncorrectParametersException(String msg) {
super(msg);
}
}
// реализация класса Needle
package clock;
/*
* Needle.java
*
* Created on май 2009 г.
*/
import java.awt.*;
import java.awt.geom.*;
/**
* Этот класс предназначен для создания стрелки часов
*
* @author Бочкарева Мария
*/
public class Needle {
private GeneralPath shape;
private double length, width;
/** Создает экземпляры класса <code>Needle</code>.
* При создании необходимо указать длину и ширину стрелки.
* Длина должна быть больше ширины.
*
* @param length длина стрелки
* @param width длина стрелки
*
* @exception IncorrectParametersException - если длина меньше или
* равна нулю, если ширина меньше или равна нулю, если длина
* меньше или равна ширине.
*/
public Needle(double length, double width)
throws IncorrectParametersException {
//проверяем параметры
if(length <= 0 || width <=0 || length <= width)
throw new IncorrectParametersException();
this.length = length;
this.width = width;
//создаем графический объект
shape = new GeneralPath();
shape.moveTo(0f, (float)width/2);
shape.lineTo((float)width/2, 0);
shape.lineTo((float)length, (float)width/2);
shape.lineTo((float)width/2, (float)width);
shape.closePath();
}
/**
* Возвращает стрелку в виде объекта типа <code>Shape</code>.
* @return Shape - фигура, содержащая изображение стрелки
*/
public Shape getNeedle() {
return shape;
}
/**
* Возвращает центр вращения стрелки (точку, вокруг которой
* стрелка будет вращаться)
* @return Point2D.Double - точка, содержащая координаты центра вращения
* стрелки
*/
public Point2D.Double getRotationCenter() {
Point2D.Double rc = new Point2D.Double();
rc.x = rc.y = width/2;
return rc;
}
}
- Введение
- Глава 1 Основы Java
- 1.1 Выполнение Java-программы
- 1.2 Что такое JDK
- Глава 2 Объектно-ориентированное программирование в Java
- 2.1 Принципы объектно-ориентированного программирования
- Глава 3 Принципы построения графического интерфейса
- 3.1 Компонент и контейнер
- Глава 4 Апплеты
- 4.1 Апплеты
- 4.2 Параметры тега <applet>
- 4.3 Сведения об окружении апплета
- 4.4 Изображение и звук
- Заключение