Java. Полное руководство. 8-е издание. С. Н. Тригуб Перевод с английского и редакция
Скачать 25.04 Mb.
|
ГЛАВА Введение в библиотеку AWT: работа с окнами графикой и текстом Библиотека AWT (Abstract Window Toolkit) уже была представлена в главе 22, где она использовалась в нескольких примерах аплетов. В этой главе займемся ее более глубоким исследованием. Библиотека AWT включает в себя многочисленные классы и методы, позволяющие создавать окна и управлять ими. Кроме того, она служит фундаментом библиотеки Swing. Библиотека AWT достаточно велика, и полное ее описание легко бы заняло целую книгу. Поэтому невозможно во всех подробностях описать каждый метод, класс или переменную экземпляра библиотеки AWT. Однако в этой и двух последующих главах мы объясним базовые приемы эффективного применения библиотеки AWT для создания аплетов и независимых приложений с графическим интерфейсом пользователя. После этого вы получите возможность самостоятельно поработать и с другими частями библиотеки AWT. Кроме того, вы сможете легко перейти к библиотеке В настоящей главе вы научитесь создавать окна, управлять ими, а также шрифтами, выводом текста и графикой. В главе 25 будут описаны различные элементы управления, такие как полосы прокрутки и экранные кнопки, поддерживаемые библиотекой AWT. Также там пойдет речь о дополнительных аспектах механизма обработки событий Java. Глава 26 будет посвящена подсистемам графических изображений и анимации Хотя библиотека AWT чаще всего используется в аплетах, она применяется также при создании отдельных окон в среде графического пользовательского интерфейса (GUI), такой как операционная система Windows. По причине согласованности большинство примеров этой главы представлено в виде аплетов. Чтобы запускать их, вам понадобится средство просмотра аплетов или совместимый с Java веб-браузер. Несколько программ, однако, продемонстрируют создание самостоятельных оконных программ. Прежде чем начать, стоит упомянуть еще об одном. В настоящее время большинство программ на языке Java построено на основе пользовательского интерфейса библиотеки Swing. Поскольку библиотека Swing предлагает более широкие возможности, нежели библиотека AWT, в отношении создания таких распространенных компонентов GUI, как кнопки, окна, списки и флажки, очень легко прийти к мысли, что библиотека AWT утратила свое значение. Однако такое заключение ошибочно. Как уже упоминалось, библиотека Swing построена на базе библиотеки AWT. А потому многие аспекты библиотеки AWT относятся также и к библиотеке Swing. Более того, многие классы библиотеки AWT используются библиотекой Swing, прямо или опосредованно. И наконец, для некоторых типов небольших программ (особенно маленьких аплетов), которые очень ограниченно используют GUI, имеет смысл применять библиотеку AWT вместо библиотеки Swing. Поэтому даже несмотря на то, что большинство интерфейсов в наши дни базируется на библиотеке Swing, хорошее знание библиотеки AWT все еще вое 7 4 6 Часть II. Библиотека Java требовано. Просто примите к сведению, что без знания библиотеки AWT вы не можете считать себя профессиональным программистом на языке Наз а метку Если вы еще не читали главу 2 3 , сделайте это прямо сейчас. В ней представлен обзор обработки событий, которые будут использоваться во многих примерах настоящей главы. Классы библиотеки В пакете j av a . awt, одном из наиболее объемных пакетов Java, содержатся классы библиотеки AWT. К счастью, благодаря логической организации в виде иерархии сверху вниз, понять и использовать его гораздо легче, чем может показаться на первый взгляд. В табл. 24.1 перечислены некоторые из множества классов Таблица 24.1. Примеры классов библиотеки СМ э д ш е AWTEvent Инкапсулирует события Доставляет события множеству слушателей BorderLayout Граничный диспетчер раскладки. Использует пять компонентов North, South,East,West и Создает элемент управления — экранную кнопку Canvas Пустое, свободное от семантики окно CardLayout Карточный диспетчер раскладки. Эмулирует индексированные карты. Отображается только одна, находящаяся сверху Checkbox Создает элемент управления — флажок CheckboxGroup Создает группу флажков CheсkboxMenuItem Создает переключаемый пункт меню Choice Создает всплывающий список Color Управляет цветами в переносимой и независящей от платформы манере Component Абстрактный суперкласс для различных компонентов Подкласс класса Component, который может содержать другие компоненты Cursor Инкапсулирует курсор — битовую карту Dialog Создает диалоговое окно Dimension Определяет измерения объекта. Ширина сохраняется в width, а высота — в height Event Инкапсулирует события EventQueue Очередь событий. Класс FileDialog создает окно, в котором можно выбрать файл FlowLayout Потоковый диспетчер раскладки. Располагает компоненты слева направо и сверху вниз Font Инкапсулирует шрифт печати FontMetrics Инкапсулирует различную информацию, относящуюся к шрифту. Эта информация помогает отображать текст в окне Frame Создает стандартное окно, снабженное полосой заголовка, элементами управления размерами и полосой меню Глава 24. Введение в библиотеку AWT: работа с окнами, графикой и текстом 7 4 Продолжение табл. Описание • _ , ; \ : \ \ \ ’ j riJ'f'f ' Graphics Инкапсулирует графический контекст. Этот контекст используется разнообразными методами вывода для отображения в окне GraphicsDevice Описывает графическое устройство, такое как экран или принтер GraphicsEnvironment Описывает коллекцию доступных объектов класса Font и Описывает различные ограничения, относящиеся к классу GridBagLayout GridBagLayout Диспетчер сетчатой управляемой раскладки. Отображает компоненты в соответствии с ограничениями, указанными в объекте класса Диспетчер сетчатой раскладки. Отображает компоненты в двухмерной сетке Image Инкапсулирует графические образы Insets Инкапсулирует границы контейнера Label Создает метку, отображающую строку List Создает список, из которого пользователь может выбирать. Аналогичен стандартному окну списка Управляет медиаобъектами Menu Создает выпадающее меню MenuBar Создает полосу меню MenuComponent Абстрактный класс, реализованный различными классами меню Menultem Создает пункт меню MenuShortcut Инкапсулирует горячую клавишу для быстрого вызова пункта меню Panel Простейший конкретный подкласс класса Container Point Инкапсулирует пару декартовых координат, хранящихся в хи у Polygon Инкапсулирует многоугольник PopupMenu Создает всплывающее меню PrintJob Абстрактный класс, представляющий задание печати Rectangle Инкапсулирует прямоугольник Robot Поддерживает автоматическую проверку приложений на основе библиотеки Создает элемент управления — полосу прокрутки ScrollPane Контейнер, предоставляющий горизонтальную и вертикальную полосы прокрутки для другого компонента SystemColor Содержит цвета для элементов (виджетов) GUI, таких как окна, полосы прокрутки, текст и прочее TextArea Создает элемент управления — многострочный текстовый редактор 7 4 8 Часть II. Библиотека Java г. TextComponent Суперкласс для классов TextArea и Создает элемент управления — однострочный текстовый ре дактор Toolkit Абстрактный класс, реализованный библиотекой AWT W i Создает окно без рамки, без полосы меню и заголовка Хотя базовая структура библиотеки AWT не менялась со времен Java 1.0, некоторые из оригинальных методов устарели и заменены новыми. Для обеспечения обратной совместимости язык Java все еще поддерживает исходные методы версии 1.0. Однако поскольку эти методы не предназначены для использования в новом коде, мы не станем их описывать в настоящей книге. Основы окон Библиотека AWT определяет окна в соответствии с иерархией классов, которые обеспечивают функциональные и специфические возможности на каждом уровне. Два наиболее часто используемых класса окон происходят либо от класса Panel, который используется в аплетах, либо от класса Frame, который создает стандартное окно приложения. Большую часть своих функциональных возможностей эти окна наследуют от своих родительских классов. Поэтому описание иерархии классов, относящихся к этим двум классам, является основополагающим для их понимания. На рис. 24.1 показана иерархия для классов Panel и Frame. Рассмотрим каждый из этих классов Рис. 24.1. Иерархия классов Panel и Класс C o m p o n e n В вершине иерархии находится класс Component. Это — абстрактный класс, инкапсулирующий все атрибуты визуального компонента. За исключением меню, все элементы пользовательского интерфейса являются подклассами класса Component. Он определяет свыше сотни открытых методов, отвечающих за управление событиями, такими как ввод с клавиатуры и события мыши, перемещение и изменение размеров окна, а также перерисовка. (Вы уже использовали многие из Глава 24. Введение в библиотеку AWT: работа с окнами, графикой и текстом 7 4 этих методов, когда создавали аплеты в главах 22 и 23.) Объект класса Component отвечает за запоминание текущих цветов фона и переднего плана, а также текущего выбранного шрифта для печати. Класс C o n t a i n e Класс Container — это подкласс класса Component. Он имеет дополнительные методы, позволяющие вкладывать в него другие объекты класса Component. Другие объекты класса Container также могут находиться внутри класса Container поскольку они сами являются экземплярами класса Component), что позволяет строить многоуровневые системы вложенности. Контейнер отвечает за раскладку (те. расположение) любых компонентов, которые он содержит. Это достигается за счет использования различных диспетчеров раскладки, о которых вы узнаете в главе Класс P a n e Класс Panel — конкретный подкласс класса Container. Таким образом, класс Panel может обеспечивать рекурсивную вложенность и представляет собой конкретный экранный компонент. Класс Panel — суперкласс для класса Applet. Когда экранный вывод направляется в аплет, он рисуется на поверхности объекта класса Panel. По сути, класс Panel — это окно, лишенное полосы заголовка, полосы меню и рамки. И поэтому вы не можете видеть упомянутых элементов, когда аплет запущен внутри браузера. Когда же вы запускаете аплет в средстве просмотра аплетов, то заголовок и рамку предоставляет это средство. Другие компоненты могут быть добавлены к объекту класса Panel с помощью его метода add () (унаследованного от класса Container). Как только эти компоненты добавлены, вы можете позиционировать их и изменять размеры вручную, используя методы setLocation ( ) , setSize (), setPref erredSize () или set- Bounds ( ), определенные в классе Класс w i n d o Этот класс создает окно верхнего уровня, которое не содержится внутри другого объекта, а располагается непосредственно на рабочем столе. Обычно вам не придется создавать объекты класса Window непосредственно. Вместо этого выбудете работать с подклассом Frame класса Класс F r a m Этот класс инкапсулирует то, что обычно воспринимается как окно. Это подкласс класса Window, имеющий полосу заголовка, полосу меню, границы и элементы управления размером. Класс C a n v a Не являющийся частью иерархии аплетов или рамочных окон, класс Canvas, возможно, не покажется вам особенно полезным он инкапсулирует пустое окно, в котором вы можете рисовать. Пример применения класса Canvas будет приведен далее в настоящей книге 7 5 Часть II. Библиотека Работа с рамочными окнами После аплета тип окон, которые вам придется создавать чаще всего, унаследован от класса Fram e. Выбудете создавать дочерние окна внутри аплетов, а также окна верхнего уровня или дочерние окна для отдельно выполняемых приложений. Как упоминалось, это создает окна в стандартном стиле. Вот два конструктора класса Fram e. Fr a m e () throws HeadlessException Frame(String заголовок throws Первая форма создает стандартное окно без заголовка. Вторая форма — окно с заголовком, указанным параметром заголовок Обратите внимание на то, что вы не можете задать размеры окна. Вместо этого следует устанавливать размер окна после его создания. Исключение H e a d l e s s E x c e p ti o n передается при попытке создать экземпляр класса Fram e в среде, которая не поддерживает взаимодействие с пользователем. Существует несколько ключевых методов, которые выбудете использовать при работе с окнами класса Fram e. Сейчас мы их и рассмотрим. Установка размеров окна Метод s e t S i z e () используется для установки размеров окна. Его сигнатура показана ниже setSize(int новаяШирина, int новаяВысота) void setSize (Dimension новыйРазмер) Новый размер окна указан параметрами новаяШирина и новаяВысота или же в полях w id th и h e i g h t объекта класса D im en sio n , переданного в параметре новыйРазмер. Размеры задаются в пикселях. Метод g e t S i ze () применяется для получения текущего размера окна. Одна из его сигнатур выглядит следующим образом g e Этот метод возвращает текущий размер окна в полях w i d t h и h e i g h t объекта класса D im en sio n Сокрытие и отображение окна После того как рамочное окно создано, оно остается невидимым до тех пор, пока вы не вызовите метод s e t v i s b l e (). Его сигнатура такова setvisible(boolean флагВидимости) Компонент видим, если этому методу передается аргумент t r u e . В противном случае он скрыт. Установка заголовка окна Вы можете изменить заголовок рамочного окна, используя методе, который имеет следующую общую форму setTitle(String новыйЗаголовок) Здесь новыйЗаголовок — новый заголовок окна Глава 24. Введение в библиотеку AW T: работа с окнами, графикой и текстом 7 5 Закрытие рамочного окна При использовании рамочного окна ваша программа должна удалять окно с экрана после его закрытия, вызывая метод s e t V i s i b l e ( f a l s e ) . Чтобы перехватить событие закрытия окна, следует реализовать метод w in d o w C lo sin g () интерфейса W in d o w L iste n e r. Внутри метода w in d o w C lo sin g () следует удалить окно с экрана. Пример, приведенный в следующем разделе, иллюстрирует этот прием. Создание рамочного окна в аплете Хотя получить окно можно, создав экземпляр класса Frame, вам редко доведется поступать так, поскольку с таким окном не так много можно делать. Например, вы не сможете принимать или обрабатывать события, которые происходят в нем, или просто выводить в него информацию. В основном, вам придется создавать подклассы класса Frame. Это позволит переопределять методы класса Frame и обеспечивать обработку событий. Создать новое рамочное окно аплета достаточно просто. Для начала создается подкласс класса Frame. Затем переопределяется любой стандартный метод апле та, такой как init ( ), start () и stop (), чтобы отображать или скрывать фрейм по необходимости. И наконец, реализуется метод windowClosing (Как только определите подкласс класса Frame, сможете создать объект этого класса. Это приведет к появлению рамочного окна, которое, однако, изначально будет невидимым. Выделаете его видимым при помощи вызова метода setVis ible () . При создании окно получает высоту и ширину по умолчанию. Вы можете установить размеры окна явно с помощью метода set Size (Приведенный ниже аплет создает подкласс класса Fram e по имени Sam pleFram e. Экземпляр окна этого класса создается внутри метода i n i t () класса A p p le t Fram e. Обратите внимание на то, что класс S am pleFram e вызывает конструктор класса Fram e. Это позволяет создать стандартное рамочное окно с заголовком, переданным в параметре t i t l e . Этот пример переопределяет методы s t a r t () и s t o p () аплета так, что они, соответственно, отображают и скрывают дочернее окно. Это позволяет автоматически удалить окно, когда вы прерываете работу аплета, когда закрываете окно или, при использовании браузера, когда переходите на другую страницу. Это также вызывает отображение дочернего окна, когда браузер возвращается к аплету. // Создание дочернего окна из аплета, import java.awt.*; import j a v a .a w t .event.*; import java.applet.*; /* */ // Создание подкласса Frame. class SampleFrame extends Frame { SampleFrame(String title) { super(title); // создание объекта для обработки событий окна MyWindowAdapter adapter = new MyWindowAdapt'er (this) ; // регистрация его для получения событий 7 5 Часть II. Библиотека Java addWindowListener(adapter); } public void paint(Graphics g) { g.drawstring("This is in frame window", 10, 40) } } class MyWindowAdapter extends WindowAdapter { SampleFrame sampleFrame; public MyWindowAdapter(SampleFrame sampleFrame) { t his.sampleFrame = sampleFrame; } public void windowClosing(WindowEvent we) { sampleFrame.setVisible(false); } } // Создание рамочного окна class AppletFrame extends Applet { Frame f ; public void ini t () { f = new SampleFrame("A Frame Window"); f .setSize(250, 250); f .setVisible(true); } public void start() { f .setVisible(true); } public void stop() { f .setVisible(false) ; } |