Методические указания. Апплет должен быть создан на основе шаблонов, содержащихся в Приложении 6(или при помощи системы Java Applet Wizard).
Объявление элементов класса апплета.
В классе апплета объявим следующие элементы:
// выводимые строки
String strs[]={"First string", "Second string", "Third string"};
// текущий размер окна апплета
Dimension appSize;
Перерисовка окна апплета (метод paint()).
Для перерисовки изображения в окне используется метод paint(), которому передается объект g типа Graphics (g - контекст отображения для окна). Методами этого класса пользуются для вывода графической информации в окно апплета.
В данном апплете этот метод используется для определения текущего размера appSize окна и для закраски фона окна и рисовании рамки окна. Сначала раскрасим фон окна и нарисуем рамку окна. Для этого сделаем следующие действия: при помощи метода size() класса апплета получим текущий размер окна и присвоим ссылку на него объекту appSize; методом g.setColor() выберем цвет фона Color.yellow; зарисуем всю внутреннюю область окна с помощью метода g.fillRect() и объекта appSize; методом g.setColor() выберем цвет рамки Color.black; нарисуем рамку вокруг окна методом g.drawRect(), используя объект appSize.
Метод, работающий в рамках отдельного потока (метод run()).
Поток, выполняющийся в рамках метода run() одновременно с кодом апплета, будет по очереди извлекать строки из массива strs и отображать их в нижней части окна: Сначала определим переменные метода и получим контекст окна апплета и высоту символов текущего шрифта:
public void run()
{ int counter=0; // счетчик сдвигов
int current=0; // номер текущей рисуемой строки
int hy=1; // размер сдвига по вертикали
Graphics g=getGraphics(); // контекст окна апплета
int yChar=g.getFontMetrics().getHeight(); // высота символа
while (true)
{ try
{ // вывод в окно апплета
Thread.sleep(50);
}
catch (InterruptedException e)
{ stop();
}
}
}
В блоке try метода run() выполним свертку окна апплета: 1) с помощью метода g.copyArea() скопируем верхнюю часть экрана, ограниченную прямоугольником с началом в точке (0, hy+1), шириной appSize.width-1 и высотой appSize.height-1, в область с началом в точке (0, -hy); 2) методом g.setColor() выберем цвет фона Color.yellow; 3) нарисуем методом g.fillRect() прямоугольник с началом в точке (1, appSize.height-hy-1), шириной appSize.width-2 и высотой hy.
Далее увеличим счетчик сдвигов counter на 1, а затем проверим его. Если значение counter равно yChar+5 (то есть сдвинута полная строка), то рисуем строку с номером current в нижней части окна. Для этого: 1) сбрасываем счетчик сдвигов counter в 0; 2) если строка первая (current равно 0) то методом g.setColor() устанавливаем красный цвет, иначе - черный; 3) методом g.drawString() выводим строку с номером current в точке с координатами (10, appSize.height-10); 4) увеличиваем номер текущей рисуемой строки current на 1; 5) если нарисованы все строки (current больше или равно strs.length), то устанавливаем номер текущей рисуемой строки current в 0.
Далее выполняется задержка на 50 миллисекунд, после чего работа бесконечного цикла возобновляется с самого начала.
Задания к лабораторной работе
Задание 1. Проверить и объяснить работу апплетов MultiTask, DoubleTask и Multi, рассматриваемых в данной главе в качестве примеров и отмеченных курсивом.
Задание 2.Создать апплет двойного назначения VertScroller и объяснить его работу.
Задание 3. Дать ответы на контрольные вопросы.
Контрольные вопросы
45. Что такое процесс (задача) и поток (нить)?
46. Чем определяется порядок передачи управления потоками?
47. Какие есть способы реализации многозадачности в Java?
48. Что необходимо сделать для создания подкласса потоков (подкласса Thread)?
49. Когда запускается на выполнение метод run() подкласса Thread?
50. Какими методами класса Thread необходимо запускать поток на выполнение и останавли-
вать его?
7. Что необходимо сделать для реализации классом интерфейса Runnable?
8. В каких состояниях может находиться поток?
9. Какой поток считается новым, выполняемым и завершенным?
10. В каких ситуациях поток является невыполняемым?
11. Когда возникают исключительные ситуации при работе с потоками?
12. Что такое приоритетная система и какой системой является виртуальная машина Java?
13. Что такое группы потоков и чем они полезны?
14. Что такое родовая группа потоков и главная группа потоков?
15. Чем определяется уровень защиты группы потоков?
ЛАБОРАТОРНАЯ РАБОТА № 7
АВТОНОМНЫЕ ПРИЛОЖЕНИЯ. ПОТОКИ ДАННЫХ. РАБОТА С ЛОКАЛЬНЫМИ ФАЙЛАМИ (2 ЧАСА)
МЕТОДИЧЕСКИЕ УКАЗАНИЯ К ЛАБОРАТОРНОЙ РАБОТЕ
Язык Java очень широко используется для создания апплетов, встраиваемых в html-страницы, однако необходимость реализации апплетов на компьютерах пользователей сети WWW накладывает на них некоторые ограничения. Так, например, апплеты не имеют доступа к файлам, расположенным на удаленном компьютере, на котором эти апплеты были запущены, хотя и могут при этом обращаться к файлам, которые находятся в каталоге сервера WWW, откуда эти апплеты были загружены.
Программировать на языке Java можно и за рамками модели апплета, создавая отдельные, независимые приложения. Эти приложения похожи на обычные программы, написанные на других языках программирования, и имеют доступ к локальной файловой системе компьютера, на котором они запущены. Автономные приложения Java могут работать также и с удаленными файлами (через сеть Internet или Intranet).
1. Самостоятельные графические приложения
Рассмотрим, как в самостоятельных приложениях создать графический интерфейс пользователя, работающий без оболочки времени выполнения.
Все, что нужно для создания отдельного приложения Java, - это иметь метод main(), определенный в классе. Когда запускается программа java.exe на обработку этого класса, она вызывает метод main().
Для того, чтобы сделать приложение таким же дружественным и иллюстративным, как апплет, необходимо создать фрейм либо непосредственно в методе main(), либо в одном из методов, им вызываемом. Можно создавать не только объект класса Frame, но и его подклассов, например, как в приложении StandAlone (пример 1). Текст подобного шаблонного файла содержится в Приложении 7 и его можно в дальнейшем использовать в качестве шаблона самостоятельного графического Java-приложения.
/*------------- Пример 1. Файл StandAlone.java -------------*/
import java.awt.*;
// Основной класс для приложения StandAlone
public class StandAlone
{ public static void main(String args[])
{// Создать рамку (фрейм)
MainWndFrame frame = new MainWndFrame("Title");
// Отображение окна фрейма
frame.show();
}
// Сделать: Добавьте сюда код, необходимый для работы
// создаваемого специализированного приложения
}
// Класс главного фрейма для приложения
class MainWndFrame extends Frame
{ public MainWndFrame(String str) // конструктор
{ super (str);
// Сделать: Добавьте сюда код конструктора
resize(320,240); // задание необходимых размеров окна
// здесь можно определить различные параметры фрейма,
// например, форму курсора, меню, добавить компоненты и др.
}
public boolean handleEvent(Event evt) // обработчик событий
{ switch (evt.id)
{ case Event.WINDOW_DESTROY:
// при закрытии окна завершается работа приложения
//-------------------------------------------------
// Сделать: Добавьте сюда код, который должен
// работать при остановке приложения
dispose(); // удаление окна
System.exit(0); // завершение приложение
return true;
default:
// передача сообщения на обработку
// методу базового класса
return super.handleEvent(evt);
}
}
}
В предыдущих главах подробно рассматривался Abstract Windowing Toolkit (AWT). Все элементы управления и контейнеры можно использовать и при создании отдельного графического приложения. Можно также создать подкласс Applet и ввести его во фрейм, тогда отдельное графическое приложения будет использовать все возможности апплетов (включая получение графических и звуковых данных из Internet).
Графические данные из Internet (без создания объекта подкласса Applet) можно получить при помощи класса Toolkit. Класс Toolkit - это абстрактный класс, который служит связкой между AWT и локальной системой управления окнами. Этот класс определяет метод getImage(), который работает аналогично методу с таким же именем класса Applet. Чтобы из самостоятельного приложения получить изображение из Internet, следует внутри любого подкласса Frame сделать следующие действия:
Toolkit T=getToolkit();
Im=T.getImage(U); // U - URL-адрес, объект класса URL
Теперь, за исключением проигрывания звуковых фрагментов, можно сделать с отдельными приложениями все, что можно сделать с апплетами.
Для приложения можно воспользоваться другой версией метода getImage() класса Toolkit для загрузки графических данных прямо из файловой системы (без использования только URL-адреса), как это сделано в следующем классе фрейма:
class MainWndFrame extends Frame
{ Image Im;
public MainWndFrame(String str) // конструктор
{ super (str);
// Сделать: Добавьте сюда код конструктора
Toolkit T=getToolkit();
Im=T.getImage("image.gif"); // файл из текущего каталога
}
public void paint(Graphics g)
{ g.drawImage(Im,10,10,this);
}
// остальной код класса
........................
}
В данном случае метод getImage() ищет файл image.gif в текущем каталоге файловой системы.