Java Примеры программирования Информатика начало

Описание исходных текстов аплета Rectangles

Назад Вперед

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

Что же касается основного класса аплета, то он унаследован, как обычно, от класса Applet и не реализует интерфейс Runnable:

public class 
Rectangles extends Applet { . . . }
Поля класса Rectangles

В классе Rectangles мы определили три поля с именами m_DrawRectThread, m_DrawEllipseThread и m_NotifyTaskThread:

DrawRectangles m_DrawRectThread 
= null; DrawEllipse m_DrawEllipseThread = null; NotifyTask m_NotifyTaskThread 
= null

Эти поля являются ссылками на классы, соответственно DrawRectangles, DrawEllipse и NotifyTask . Первый из них создан для рисования прямоугольников, второй - эллипсов, а третий - для управления потоком рисования эллипсов.

Указанные поля инициализируются занчением null, что соответствует неработающим или несозданным задачам.

Метод start класса Rectangles

Этот метод последовательно создает три потока и запускает их на выполнение:

if(m_DrawRectThread 
== null) { m_DrawRectThread = new DrawRectangles(this); m_DrawRectThread.start(); 
}
if(m_DrawEllipseThread == null) { m_DrawEllipseThread 
= new DrawEllipse(this); m_DrawEllipseThread.start(); }
if(m_NotifyTaskThread 
== null) { m_NotifyTaskThread = new NotifyTask(m_DrawEllipseThread); m_NotifyTaskThread.start(); 
}

В качестве параметра  конструкторам классов DrawRectangles и DrawEllipse мы передаем ссылку на аплет Rectangles. Эта ссылка будет нужна для получения контекста отображения и рисования геометрических фигур.

Поток класса NotifyTask будет управлять работой потока DrawEllipse, поэтому мы передаем его конструктору ссылку на соответствующий объект m_DrawEllipseThread.

Метод stop класса Rectangles

Когда пользователь покидает страницу сервера Web с аплетом, метод stop класса Rectangles последовательно останавливает gjnjrb рисования прямоугольников и эллипсов, а также управляющий поток:

if(m_DrawRectThread 
!= null) { m_DrawRectThread.stop(); m_DrawRectThread = null; }
if(m_DrawEllipseThread 
== null) { m_DrawEllipseThread.stop(); m_DrawEllipseThread = null; } 
if(m_NotifyTaskThread 
!= null) { m_NotifyTaskThread.stop(); m_NotifyTaskThread = null; }
Поля класса DrawRectangles

Класс DrawRectangles определен для потока рисования прямоугольников:

class DrawRectangles extends Thread 
{ . . . }

В поле g класа хранится контекст отображения окна аплета, а в поле dimAppWndDimension - размеры этого окна:

Graphics 
g; Dimension dimAppWndDimension;

Значения этих полей определяются конструктором класса по ссылке на главный класс аплета.

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

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

public 
DrawRectangles(Applet Appl) { g = Appl.getGraphics(); dimAppWndDimension = Appl.getSize(); 
}
Метод run класса DrawRectangles

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

Для того чтобы рисовать, необходимо получить контекст отображения. Этот контекст был получен конструктором класса DrawRectangles и может быть использован методом run.

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

В качестве генератора случайных чисел мы используем метод random из класса Math, который при каждом вызове возвращает новое случайное число типа double, лежащее в диапазоне значений от 0.0 до 1.0.

Координаты по осям X и Y рисуемого прямоугольника определяются простым умножением случайного числа, полученного от метода random, соответственно, на ширину и высоту окна аплета:

x = (int)(dimAppWndDimension.width * Math.random()); 
y = (int)(dimAppWndDimension.height * Math.random());

Аналогично определяются размеры прямоугольника, однако чтобы прямоугольники не были слишком крупными, мы делим полученные значения на 2:

width 
= (int)(dimAppWndDimension.width * Math.random()) / 2; height = (int)(dimAppWndDimension.height 
* Math.random()) / 2;

Так как случайное число имеет тип double, в обоих случаях мы выполняем явное преобразование результата вычислений к типу int.

Для случайного выбора цвета прямоугольника мы вычисляем отдельные цветовые компоненты, умножая значение, полученное от метода random, на число 255:

rColor = (int)(255 * Math.random()); gColor = (int)(255 
* Math.random()); bColor = (int)(255 * Math.random());

Полученные значения цветовых компонент используются в конструкторе Color для получения цвета. Этот цвет устанавливается в контексте отображения методом setColor:

g.setColor(new 
Color(rColor, gColor, bColor));

Теперь все готово для рисования прямоугольника, которое мы выполняем при помощи метода fillRect:

g.fillRect(x, 
y, width, height);

После рисования прямоугольника метод run задерживает свою работу на 50 миллисекунд, вызывая метод sleep:

try 
{ Thread.sleep(50); } catch (InterruptedException e) { stop(); }

Для обработки исключения InterruptedException, которое может возникнуть во время работы этого метода, мы предусмотрели блок try - catch. При возникновении указанного исключения работа потока останавливается вызовом метода stop.

Метод run класса DrawEllipse

Класс DrawEllipse очень похож на только что рассмотренный класс DrawRectangles. Отличие есть только в финальном фрагменте метода run, который мы и рассмотрим.

Вместо задержки на 50 миллисекунд метод run из класса DrawEllipse переходит в состояние ожидания извещения, вызывая метод wait:

try 
{ this.wait(); } catch (InterruptedException e) { }

Это извещение создается управляющим потоком класса NotifyTask, к описанию которого мы переходим.

Поля класса NotifyTask

В классе NotifyTask мы определили одно поле STask класса Thread. Это поле которое хранит ссылку на поток, работой которого управляет данный класс:

class NotifyTask extends Thread { Thread 
STask; . . . }
Конструктор класса NotifyTask

Конструктор класса NotifyTask записывает в поле STask ссылку на задачу рисования эллипсов:

public 
NotifyTask(Thread SynchroTask) { STask = SynchroTask; }
Метод run класса NotifyTask

Метод run класса NotifyTask периодически разблокирует поток рисования эллипсов, вызывая для этого метод notify в цилке с задержкой 30 миллисекунд. Обращение к объекту STask, который хранит ссылку на поток рисования эллипсов, выполняется с использованием синхронизации:

public 
void run() { while (true) { try { Thread.sleep(30); } catch (InterruptedException 
e) { }
 synchronized(STask) { STask.notify(); 
} } }
Назад Вперед

Машиностроительное черчение, инженерная графика, начертательная геометрия. Выполнение контрольной