Начните создание апплета со следующих строк кода: /* Пример для опробования 14.1. Простой апплет, отображающий крупный заголовок. В этом апплете создается поток, управляющий прокруткой крупного заголовка, хранящегося в переменной msg, справа налево в окне апплета. */ import java.awt.*; import java.applet.*; /* */ public class Banner extends Applet implements Runnable { String msg = " Java Rules the Web "; // "Java правит Паутиной" Thread t; boolean stopFlag; // инициализировать переменную t пустым значением null public void init { t = null; } }
Обратите внимание на то, что класс Banner не только является подклассом, производным от класса Applet, но и реализует интерфейс Runnable. Это необходимо потому, что апплет создает еще один поток исполнения, который служит для прокрутки крупного заголовка по горизонтали. Текст крупного заголовка хранится в переменной msg типа String, ссылка на поток, в котором выполняется апплет, хранится в переменной t, а логическая переменная stopFlag служит для остановки апплета. В методе init переменной t исходно присваивается пустое значение null.
Введите метод start , исходный код которого приведен ниже. // запустить поток public void start { t = new Thread(this); stopFlag = false; t.start; } Исполняющая система вызывает метод start для запуска апплета на выполнение. В этом методе создается новый поток исполнения, а ссылка на него присваивается переменной t типа Thread. Затем переменная stopFlag инициализируется логическим значением false. Далее поток запускается при вызове t. start . Это, в свою очередь, приводит к вызову метода run . Следует, однако, иметь ввиду, что метод start из класса Thread не имеет ничего общего с одноименным методом, определенным в классе Applet.
Введите метод run , исходный код которого приведен ниже. // Точка входа в поток, манипулирующий крупным заголовком, public void run { // отобразить крупный заголовок снова for( ; ; ) { try { repaint ; Thread.sleep(250); if(stopFlag) break; } catch(InterruptedException exc) {} } } В методе run вызывается метод repaint , что в конечном итоге приводит к вызову метода paint и отображению текущего содержимого переменной msg на экране. Между последовательными шагами цикла выполнение метода run приостанавливается на четверть секунды. В результате содержимое переменной msg постоянно прокручивается справа налево. На каждом шаге цикла проверяется содержимое переменной stopFlag. И как только она примет логическое значение true, выполнение метода run завершится.
Введите методы stop и paint , исходный код которых приведен ниже. // остановить выполнение апплета public void stop { stopFlag = true; t = null; } // отобразить крупный заголовок public void paint(Graphics g) { char ch; ch = msg.charAt(0); msg = msg.substring(1, msg.length); msg += ch; g.drawstring(msg, 50, 30); }
Если пользователь браузера переходит на другую веб-страницу, вызывается метод stop , в котором переменной stopFlag присваивается логическое значение true, завершая тем самым выполнение метода run . В этом же методе переменной t присваивается пустое значение null. После этого она уже не ссылается на объект типа Thread, а следовательно, этот объект будет удален системой “сборки мусора”. Этот механизм используется для остановки потока, когда страница с апплетом не просматривается. Когда же она снова появляется в окне браузера, вызывается метод start , запускающий новый поток манипулирования крупным заголовком.
В методе paint символы строки крупного заголовка, хранящегося в переменной msg, постоянно сдвигаются влево. После каждого сдвига вызывается метод drawstring , выводящий текущее содержимое переменной msg на экран.