Java -практические советы

         

Компонент и контейнер

Основное понятие графического интерфейса пользователя (ГИП) — компонент (component) графической системы. В русском языке это слово подразумевает просто составную часть, элемент чего-нибудь, но в графическом интерфейсе это понятие гораздо конкретнее. Оно означает отдельный, полностью определенный элемент, который можно использовать в графическом интерфейсе независимо от других элементов. Например, это поле ввода, кнопка, строка меню, полоса прокрутки, радиокнопка. Само окно приложения — тоже его компонент. Компоненты могут быть и невидимыми, например, панель, объединяющая компоненты, тоже является компонентом.



Вы не удивитесь, узнав, что в AWT компонентом считается объект класса Component или объект всякого класса, расширяющего класс component. В классе component собраны общие методы работы с любым компонентом графического интерфейса пользователя. Этот класс — центр библиотеки AWT.

Каждый компонент перед выводом на экран помещается в контейнер (container). Контейнер "знает", как разместить компоненты на экране. Разумеется, в языке Java контейнер — это объект класса Container или всякого его расширения. Прямой наследник этого класса — класс jcomponent — вершина иерархии многих классов библиотеки Swing.

Создав компонент — объект класса Component или его расширения, следует добавить его к предварительно созданному объекту класса container или его расширения одним из методов add ().

Класс Container сам является невидимым компонентом, он расширяет класс Component. Таким образом, в контейнер наряду с компонентами можно помещать контейнеры, в которых находятся какие-то другие компоненты, достигая тем самым большой гибкости расположения компонентов.

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

вия мыши и клавиатуры. В окне должны быть, как минимум, следующие стандартные компоненты.

Строка заголовка (title bar), с левой стороны которой необходимо разместить кнопку контекстного меню, а с правой — кнопки сворачивания и разворачивания окна и кнопку закрытия приложения. Необязательная строка меню (menu bar) с выпадающими пунктами меню.  Горизонтальная и вертикальная полосы прокрутки (scrollbars). Окно должно быть окружено рамкой (border), реагирующей на действия мыши.

Окно с этими компонентами в готовом виде описано в классе Frame. Чтобы создать окно, достаточно сделать свой класс расширением класса Frame, как показано в листинге 8.1. Всего восемь строк текста и окно готово.

Листинг 8.1. Слишком простое окно приложения

import j ava.awt.*;

class TooSimpleFrame extends Frame{

  public static void main(String[] args){ 

    Frame fr = new TooSimpleFrame(); 

  fr.setSize(400, 150); 

  fr.setVisible(true); 

  } 

}

Класс TooSimpleFrame обладает всеми свойствами класса Frame, являясь его расширением. В нем создается экземпляр окна fr, и устанавливаются размеры окна на экране— 400x150 пикселов— методом setsizeo. Если не задать размер окна, то на экране появится окно минимального размера — только строка заголовка. Конечно, потом его можно растянуть с помощью мыши до любого размера.

Затем окно выводится на экран методом setvisibie(true). Дело в том, что, с точки зрения библиотеки AWT, создать окно значит выделить область оперативной памяти, заполненную нужными пикселами, а вывести содержимое этой области на экран — уже другая задача, которую и решает метод

setVisible(true).

Конечно, такое окно непригодно для работы. Не говоря уже о том, что у него нет заголовка и поэтому окно нельзя закрыть. Хотя его можно перемещать по экрану, менять размеры, сворачивать на панель задач и раскрывать, но команду завершения приложения мы не запрограммировали. Окно нельзя закрыть ни щелчком кнопки мыши на кнопке с крестиком в правом верхнем углу окна, ни комбинацией клавиш <Alt>+<F4>. Приходится за вершать работу приложения средствами операционной системы, например, комбинацией клавиш <Ctrl>+<C>.

В листинге 8.2 к программе листинга 8.1 добавлены заголовок окна и обращение к методу, позволяющему завершить приложение.

Листинг 8.2. Простое окно приложения 

import java.awt.*; 

import j ava.awt.event.*;

class SimpleFrame extends Frame{ 

  SimpleFrame(String s){ 

    super (s);

    setSize(400, 150); 

    setvisible(true); 

    addWindowListener(new WindowAdapter(){

      public void windowClosing(WindowEvent ev){

        System.exit (0); 

      }

    }); 

  } 

  public static void main(String[] args){

    new SimpleFrame(" Моя программа"); 

  } 

}

В программу добавлен конструктор класса SimpleFrame, обращающийся к конструктору своего суперкласса Frame, который записывает свой аргумент s в строку заголовка окна.

В конструктор перенесена установка размеров окна, вывод его на экран и добавлено обращение к методу addWindowListener (), реагирующему на действия с окном. В качестве аргумента этому методу передается экземпляр безымянного внутреннего класса, расширяющего класс WindowAdapter. Этот безымянный класс реализует метод windowciosing (), обрабатывающий попытку закрытия окна. Данная реализация очень проста — приложение завершается статическим методом exit о класса system. Окно при этом закрывается автоматически.

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

Итак, окно готово. Но оно пока пусто. Выведем в него, по традиции, приветствие "Hello, World!", правда, слегка измененное. В листинге 3.3 приведена полная программа этого вывода, а рис. 8.1 демонстрирует окно.

Рис. 8.1. Окно программы-приветствия

Листинг 8.3. Графическая программа с приветствием

import java.awt.*; 

import java.awt.event.*;

class HelloWorldFrame extends Frame{ 

  HelloWorldFrame(String s){

    super(s); 

  } 

  public void paint(Graphics g){

    g.setFont(new Font("Serif", Font.ITALIC | Font.BOLD, 30));

    g.drawstring("Hello, XXI century World!", 20, 100); 

  } 

  public static void main(String[] args){

    Frame f = new HelloWorldFrame("Здравствуй, мир XXI века!");

    f.setSize(400, 150);

    f.setvisible(true);

    f.addWindowListener(new WindowAdapter(){

      public void windowciosing(WindowEvent ev)(

        System.exit(0); 

      }

    }); 

  } 

}

Для вывода текста мы переопределяем метод paint () класса component. Класс Frame наследует этот метод с пустой реализацией.

Метод paint о получает в качестве аргумента экземпляр g класса Graphics, умеющего, в частности, выводить текст методом drawstring (). В этом методе кроме текста мы указываем положение начала строки в окне — 20 пикселов от левого края и 100 пикселов сверху. Эта точка — левая нижняя точка первой буквы текста н.

Кроме того, мы установили новый шрифт "Serif" большего размера — 30 пунктов, полужирный, курсив. Всякий шрифт — объект класса Font, а задается ОН методом setFont () класса Graphics.

Работу со шрифтами мы рассмотрим в следующей главе.

В листинге 8.3, для разнообразия, мы вынесли вызовы методов установки размеров окна, вывода его на экран и завершения программы в метод

main ().

Как вы видите из этого простого примера, библиотека AWT большая и разветвленная, в ней множество классов, взаимодействующих друг с другом. Рассмотрим иерархию некоторых наиболее часто используемых классов AWT.

Иерархия классов AWT

На рис. 8.2 показана иерархия основных классов AWT. Основу ее составляют готовые компоненты: Button, Canvas, Checkbox, Choice, Container, Label, List, Scrollbar, TextArea, TextField, Menubar, Menu, PopupMenu, Menultem, CheckboxMenuItem. Если этого набора не хватает, то от класса Canvas можно породить собственные "тяжелые" компоненты, а от класса Component — "легкие" компоненты.

Основные контейнеры — это классы Panel, ScrollPane, Window, Frame, Dialog, FileDialog. Свои "тяжелые" контейнеры можно породить от класса Panel, а "легкие" — от класса container.

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

На рис. 8.2 показаны и начальные классы иерархии библиотеки Swing — классы JComponent, JWindow, JFrame, JDialog, JApplet.

Рис. 8.2. Иерархия  основных классов AWT

 

Заключение

Как видите, библиотека графических классов AWT очень велика и детально проработана. Это многообразие классов только отражает многообразие задач построения графического интерфейса. Стремление улучшить интерфейс безгранично. Оно приводит к созданию все новых библиотек классов и расширению существующих. Независимыми производителями создано уже много графических библиотек Java: KL Group, JBCL, и появляются все новые и новые библиотеки. Сведения о них можно получить на сайтах, указанных во введении.

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