Графические интерфейсы пользователя Java
Қосымшада ыңғайлырақҚосымшаны жүктеуге арналған QRRuStore · Samsung Galaxy Store
Huawei AppGallery · Xiaomi GetApps

автордың кітабын онлайн тегін оқу  Графические интерфейсы пользователя Java

Тимур Машнин

Графические интерфейсы пользователя Java






12+

Оглавление

Введение

Любое приложение, требующее взаимодействия с пользователем, должно иметь интерфейс пользователя или GUI Graphical User Interface.

От интерфейса пользователя зависит привлекательность и удобство работы с программой.

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

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

Самой первой графической библиотекой платформы Java была библиотека AWT набора JDK 1.0.

Далее библиотека AWT была дополнена библиотекой Java 2D двухмерной графики и изображений.

Библиотека AWT обеспечивает для разработчика приложений возможность использования таких основных компонентов GUI-интерфейса как кнопка, флажок, список выбора, прокручивающийся список, метка, диалоговое окно, окно выбора файла, меню, панель с прокруткой, текстовая область и текстовое поле, использования функции Drag-and-Drop, возможность обработки событий UI-компонентов, компоновки компонентов в рабочей области, работы с цветом, шрифтом, графикой, рисования и печати.

Библиотека AWT считается тяжеловесной, так как она содержит нативную библиотеку java.awt.peer, через которую взаимодействует с операционной системой компьютера таким образом, что AWT-компоненты имеют своих двойников, реализованных для конкретной операционной системы, с которыми они связаны интерфейсами пакета java.awt.peer.

Поэтому отображение AWT GUI-интерфейса зависит от операционной системы, в которой приложение развернуто.

Для расширения набора GUI-компонентов библиотеки AWT, устранения ее тяжеловесности и возможности выбора внешнего вида и поведения (Look and Feel) GUI-компонентов была создана графическая библиотека Swing.

Библиотека Swing основывается на библиотеке AWT и напрямую не связана, как библиотка AWT, с операционной системой, в которой она работает.

Поэтому библиотека Swing является уже легковесной.

Кроме того, библиотека Swing дополняет библиотеку AWT такими компонентами GUI-интерфейса как панель выбора цвета, индикатор состояния, переключатель radio button, слайдер и спиннер, панель с закладками, таблицы и деревья, расширенными возможностями компоновки GUI-компонентов, таймером, возможностью отображения HTML-контента.

С помощью библиотеки Swing стало возможным создать набор отображений Look and Feel, которые разработчик может выбирать, не оглядываясь на операционную систему, и изменять внешний вид GUI-интерфейса.

Также библиотека Swing реализует архитектуру MVC (Model-View-Controller) и потоковую модель Event Dispatch Thread (EDT).

Библиотека SWT (Standard Widget Toolkit) является альтернативой библиотекам AWT/Swing, однако она не включена в официальный релиз JRE/JDK.

Библиотека SWT была создана в процессе работы над проектом Eclipse и является попыткой взять лучшее из архитектур библиотек AWT и Swing и предоставить возможность создания быстрых GUI-интерфейсов с отображением Look and Feel, как можно более полно соответствующим операционной системе, в которой они работают.

Архитектура системы SWT построена таким образом, что SWT-компоненты представляют собой лишь Java-оболочки GUI-компонентов конкретной операционной системы.

Для операционной системы, в которой отсутствует реализация какого-либо компонента, система SWT обеспечивает Java-эмуляцию.

Так в системе SWT достигается скорость работы и полное соответствие внешнему виду и поведению операционной системе.

Для создания GUI-интерфейса система SWT предоставляет такие GUI-компоненты как кнопка, включая флажок и переключатель, список, метка, меню, текстовая область, диалоговое окно, индикатор прогресса, панель с прокруткой, слайдер и спиннер, таблица и дерево, панель с вкладками, панель выбора даты, панель инструментов, встроенный Web-браузер, гиперссылка, а также обеспечивает компоновку SWT-компонентов, встраивание AWT-компонентов, отображение OpenGL-контента, печать, поддержку операций Drag and Drop, 2D-графики, технологии Win32 OLE.

Библиотека JFace дополняет библиотеку SWT и создана на основе библиотеки SWT с реализацией архитектуры MVC (Model-View-Controller), предоставляя такие MVC GUI-компоненты как таблица, дерево, список, текстовая область и диалоговое окно, обеспечивая определение пользовательских команд независимо от их представления в GUI-интерфейсе, управление шрифтами и изображениями, помощь пользователю в выборе соответствующего содержания для полей в GUI-компонентах, выполнение длительных задач.

Библиотека Java 3D была создана как высокоуровневая библиотека для создания 3D графики, включая анимацию 3D-объектов.

Библиотека Java 3D не включена в официальный релиз JRE/JDK и требует отдельной установки.

Библиотека Java 3D оперирует объектами, размещаемыми в графе сцены, который представляет собой дерево 3D-объектов и предназначен для визуализации.

Java3D-приложение может работать как настольное приложение, как апплет или как настольное приложение и апплет.

По сути, библиотека Java 3D является оберткой графических библиотек OpenGL и DirectX.

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

Кроме того, данные библиотеки не обеспечивают возможность декларативного создания GUI-интерфейса на основе языка XML.

Библиотека JavaFX была создана как универсальная платформа, предоставляющая современные GUI-компоненты с возможностью их декларативного описания, богатый набор библиотек для работы с медиаконтентом и 2D/3D графикой, а также высокопроизводительную среду выполнения приложений.

Первоначально, с 2007 по 2010 год, версии 1.1, 1.2 и 1.3 платформы JavaFX содержали:

— Декларативный язык программирования JavaFX Script создания UI-интерфейса.

— Набор JavaFX SDK, обеспечивающий компилятор и среду выполнения.

— Плагины для сред выполнения NetBeans IDE и Eclipse.

— Плагины для Adobe Photoshop и Adobe Illustrator, позволяющие экспортировать графику в код JavaFX Script, инструменты конвертации графического формата SVG в код JavaFX Script.

Платформа JavaFX версии 2.0 выпуска 2011 года кардинально отличалась от платформы JavaFX версии 1.х.

Платформа JavaFX 2.х больше не поддерживала язык JavaFX Script, а вместо этого предлагала новый программный интерфейс JavaFX API для создания JavaFX-приложений полностью на языке Java.

Для альтернативного декларативного описания графического интерфейса пользователя платформа JavaFX 2.х предлагала новый язык FXML.

Кроме того, платформа JavaFX 2.х обеспечивала новые графический и медиа движки, улучшающие воспроизведение графического и мультимедийного контента, обеспечивала встраивание HTML-контента в приложения, новый плагин для Web-браузеров, широкий выбор GUI-компонентов с поддержкой CSS3, 2D графику, создание отчетов с диаграммами, интеграцию с библиотекой Swing.

При этом платформа JavaFX версии 2.х содержала:

— Набор JavaFX SDK, предоставляющий инструмент JavaFX Packager tool компиляции, упаковки и развертывания JavaFX-приложений, Ant-библиотеку для сборки JavaFX-приложений, библиотеки JavaFX API и документацию.

— Среду выполнения JavaFX Runtime для работы настольных JavaFX-приложений и JavaFX-апплетов.

— Поддержку платформы JavaFX 2.х для среды выполнения NetBeans IDE 7.

— Примеры JavaFX-приложений.

— Приложение JavaFX Scene Builder 1.х для визуальной компоновки GUI-компонентов в GUI-интерфейс с использованием языка FXML.

В дальнейшем платформа JavaFX была полностью интегрирована в платформу Java 8, и перестала требовать отдельной инсталляции.

Кроме того, платформа JavaFX 8 была дополнена программным интерфейсом CSS API создание стилей, интеграцией с библиотекой SWT, программным интерфейсом Printing API, 3D графикой, программным интерфейсом SubScene API.

Также платформа JavaFX 8 предлагает улучшенный инструмент JavaFX Scene Builder 2.х для визуальной компоновки GUI-компонентов в GUI-интерфейс на основе языка FXML, дополненный поддержкой новых возможностей платформы JavaFX 8, программным интерфейсом JavaFX Scene Builder Kit для встраивания инструмента в Java приложения, возможностью добавлять пользовательские GUI-компоненты и др.

В настоящее время технология JavaFX обеспечивает создание мощного графического интерфейса пользователя (Graphical User Interface (GUI)), 2D и 3D графику для крупномасштабных приложений, ориентированных на обработку данных, насыщенных медиа-приложений, поставляющих разнообразный медиа-контент пользователю, Mashup-приложений, объединяющих различные Web-ресурсы для пользователя, обеспечивает создание компонентов высококачественной графики и анимации для Web-сайтов, различного рода пользовательских программ, насыщенных графикой, анимацией и интерактивными элементами.

Библиотека AWT

Итак, самой первой графической Java-библиотекой была создана библиотека AWT (Abstract Window Toolkit).

Она была включена в первую версию JDK 1.0.

Затем библиотека AWT была дополнена библиотекой Java 2D API, расширяющей возможности работы с двухмерной графикой и изображениями.

Так как технология Java является платформо-независимой, то соответственно и графическая Java-библиотека должна быть платформо-независимой.

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

Поэтому библиотека AWT была создана так, что каждый AWT-компонент имеет своего двойника-пира peer — интерфейс, обеспечивающий взаимодействие с конкретной операционной системой.

Таким образом, переносимость графической библиотеки AWT обусловлена наличием реализации пакета java.awt.peer для конкретной операционной системы.

Вследствие этого, AWT-компоненты называют тяжеловесными.

Все AWT-компоненты, кроме элементов меню, представлены подклассами класса java.awt.Component.

Для элементов меню суперклассом является класс java.awt.MenuComponent.

Архитектура AWT устроена таким образом, что компоненты размещаются в контейнерах (суперкласс java.awt.Container) с помощью менеджеров компоновки — классов, реализующих интерфейс java.awt.LayoutManager.

Для настольных приложений корневое окно графического интерфейса пользователя представляет контейнер java.awt. Window, который в свою очередь должен содержать окно java.awt.Frame с заголовком и границами или диалоговое окно java.awt. Dialog, также имеющее заголовок и границы.

AWT-компоненты добавляются в панель java.awt.Panel — контейнер, который может содержать как компоненты, так и другие панели.

Для апплетов класс java. applet. Applet, расширяющий класс java.awt.Panel, является корневым контейнером для всех графических компонентов.

Создаваемые на основе платформы Java SE апплеты представляют собой программы, написанные на языке Java и работающие в среде браузера, который загружает их и запускает виртуальную машину JVM для их выполнения.

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

Это означает, что апплет не может быть запущен, как настольное приложение, одной только виртуальной машиной JVM.

Для его работы необходим браузер, который распознает тэги <APPLET> или <OBJECT> и <EMBED>, включающие апплет в HTML-страницу.

Главный класс апплета должен быть подклассом класса java. applet. Applet, при этом класс Applet служит интерфейсом между апплетом и браузером.

Жизненным циклом апплета управляет компонент Java Plug-in среды выполнения JRE.

Настольные приложения платформы Java SE — это независимые Java-приложения, которые выполняются виртуальной машиной JVM, при этом точкой входа в приложение является главный класс приложения, содержащий статический метод main.

Начиная с версии Java SE 7 с апреля 2013 года все Java-апплеты и приложения Web Start должны подписываться доверенным сертификатом.

Это фактически уничтожило свободную разработку и распространение апплетов, так как приобретение доверенного сертификата является платной и не дешевой услугой.

Более того, Java 9 вообще запрещает использование апплетов, которые теперь уходят в историю.

Java Web Start

Java Web Start (JWS) — это технология, основанная на протоколе Java Network Launching Protocol (JNLP), позволяет загружать и запускать приложения с сайта, с помощью браузера.

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

Вся площадка для загрузки и старта приложения находится на сервере сайта.

Настольное Java приложение можно распространять двумя способами.

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

Или можно использовать технологию Java Web Start.

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

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

Пользователи могут загружать и запускать приложения, не выполняя сложные процедуры установки.

С помощью Java Web Start пользователи запускают приложения, перейдя по ссылке на веб-странице.

Если приложение отсутствует на компьютере, Java Web Start автоматически загружает все необходимые файлы.

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

Независимо от того, какой метод используется для запуска приложения, всегда отображается самая последняя версия приложения.

Технология, лежащая в основе Java Web Start, — это протокол Java Network Launching Protocol & API (JNLP).

Java Web Start — это эталонная реализация для спецификации JNLP.

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

С технологической точки зрения Java Web Start имеет ряд преимуществ.

Технология Java Web Start построена исключительно для запуска приложений, написанных на платформе Java, Standard Edition.

Таким образом, одно приложение может быть доступно на веб-сервере, а затем развернуто на самых разных платформах, включая Windows, Linux и macOS.

Java Web Start поддерживает несколько версий платформы Java Standard Edition.

Таким образом, приложение может запрашивать определенную версию требуемой платформы, например, Java SE 9.

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

Java Web Start позволяет запускать приложения независимо от веб-браузера.

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

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

Java Web Start использует функции безопасности платформы Java.

Приложения запускаются в защитной среде или песочнице с ограниченным доступом к локальным дисковым и сетевым ресурсам.

Пользователи также должны давать согласие на запуск приложения при первом запуске.

Приложения, запущенные с помощью Java Web Start, локально кэшируются.

Таким образом, уже загруженное приложение запускается аналогично традиционно установленному приложению.

Java Web Start входит в состав платформы Java Platform, Standard Edition (JDK) и Java Runtime Environment (JRE) и поддерживает функции безопасности платформы Java.

Это означает, что приложение, запускаемое с помощью Java Web Start, должно быть подписано доверенным сертификатом.

Что значительно сужает применение Java Web Start, так как получение доверенного сертификата является платным.

Таким образом, с помощью Java Web Start приложение можно запустить тремя способами:

Из веб-браузера, нажав ссылку.

Из значка на рабочем столе или в меню «Пуск».

Из Java Cache Viewer.

Независимо от того, какой путь используется, Java Web Start будет подключаться к веб-серверу каждый раз при запуске приложения, чтобы проверить, доступна ли обновленная версия приложения.

При запуске из веб-браузера используется HTML-ссылка, которая вместо того, чтобы указывать на другую веб-страницу, ссылается на специальный файл конфигурации, называемый JNLP-файлом.

Веб-браузер проверяет расширение файла или тип MIME файла и видит, что он принадлежит Java Web Start.

Поэтому браузер запускает Java Web Start с загруженным файлом JNLP в качестве аргумента.

Далее уже Java Web Start работает с загрузкой, кэшированием и запуском приложения, как это описано в файле JNLP.

Также технология Java Web Start может автоматически создавать ярлыки для вашего приложения на рабочем столе и в меню «Пуск».

Вы можете использовать панель управления Java для управления настройками ярлыков, которая находиться в панели управления компьютером.

Ярлыки также можно добавить с помощью Java Web Start Cache Viewer.

При первой загрузке приложения c помощью технологии JWS все необходимые файлы сохраняются в компьютере пользователя в специальной папке cache, поэтому повторно запустить приложение можно без использования браузера и соединения с интернетом, с помощью Java Cache Viewer.

Интерфейс Java Cache Viewer позволяет запустить приложение, просмотреть JNLP-файл приложения, инсталлировать ярлык приложения на рабочем столе компьютера, удалить приложение с компьютера и перейти на домашнюю страничку приложения.

Интерфейс Java Cache Viewer отражает в качестве названия приложения заголовок главного окна приложения, а не имя JAR-файла.

Открыть интерфейс Java Cache Viewer можно с помощью контрольной панели Java, которая находиться в панели управления компьютером.

JNLP-файл представляет собой XML-файл, содержащий инструкции для JWS-инструмента javaws как загружать и запускать приложение.

Именно расширение файла. jnlp, при инсталляции JRE, связывается с Java-инструментом javaws, поэтому при открытии JNLP-файла автоматически запускается загрузчик javaws.

В среде разработки NetBeans включить использование технологии Java Web Start можно в свойствах проекта, при этом в процессе сборки проекта будут созданы все необходимые артефакты.

Зачем же Java уничтожила апплеты?

Современные браузеры работают над ограничением или уменьшением поддержки плагинов, таких как Flash, Silverlight и Java, и поэтому разработчикам приложений, которые полагались на Java плагин для браузера, необходимо рассмотреть альтернативные варианты.

Они должны рассмотреть возможность перехода с Java-апплетов на технологию Java Web Start без плагинов или просто настольные приложения.

Поддержка Java в браузерах возможна только до тех пор, пока поставщики браузеров будут поддерживать плагин.

К концу 2015 года многие поставщики браузеров либо удалили, либо объявили временные рамки для удаления поддержки Java плагина.

Поэтому, Oracle решила отказаться от Java плагина браузера в JDK 9.

Однако приложения Java Web Start не полагаются на плагин браузера и не будут затронуты этими изменениями.

Архитектура AWT

Вернемся к библиотеке AWT.

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

Суперклассом, представляющим все AWT-события, является класс java.awt.AWTEvent.

Для обработки событий компонента необходимо создать класс-слушатель, реализующий интерфейс java.awt.event.ActionListener, и присоединить его к данному компоненту.

Кроме пакетов java.awt и java.awt. event библиотека AWT включает в себя:

Пакет java.awt.color используется для создания цвета.

Пакет java.awt. datatransfer используется для передачи данных внутри приложения и между приложениями.

Пакет java.awt. dnd реализует технологию Drag-and-Drop.

Пакет java.awt.font обеспечивает поддержку шрифтов.

Пакет java.awt.geom реализует двухмерную геометрию.

Пакет java.awt.im обеспечивает поддержку нестандартных методов ввода текста.

Пакет java.awt.image используется для создания и редактирования графических изображений.

Пакет java.awt.print обеспечивает поддержку печати.

Так как AWT-компоненты основываются на peer-объектах, то использование библиотеки AWT является потоково-безопасным (thread safe), поэтому не нужно беспокоиться о том, в каком потоке обновляется состояние графического интерфейса.

Однако беспорядочное использование потоков может замедлять работу AWT-интерфейса.

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

Такое прямое взаимодействие с конкретной операционной системой является и основным недостатком AWT, так как графический интерфейс, созданный на основе AWT, в операционной системе Windows выглядит как Windows-подобный, а в операционной системе Macintosh выглядит как Mac-подобный.

Казалось бы, при наличии таких графических Java-библиотек, как Swing, SWT, Java3D, JavaFX, библиотека AWT должна потерять свою актуальность.

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

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

Вернемся к иерархии классов AWT.

Класс Component находится наверху иерархии AWT.

Component — это абстрактный класс, который инкапсулирует все атрибуты визуального компонента.

Объект Component отвечает за запоминание текущих цветов переднего плана и фона, выбранного шрифта текста, а также размеров и местоположения.

Container — это компонент AWT, который содержит другие компоненты, такие как кнопка, текстовое поле, таблицы и т. д.

Контейнер является подклассом класса компонентов.

Класс контейнера отслеживает и компонует добавляемые компоненты.

Класс Panel — это конкретный подкласс класса Container.

Панель не содержит строку заголовка, строку меню или границу.

Это контейнер, который используется для содержания компонентов.

Класс Window создает окно верхнего уровня. Окно не имеет границ и меню.

Frame является подклассом класса Window и имеет заголовок и границы, а также изменяемый пользователем размер.

Таким образом, для создания AWT приложения, в первую очередь, нужно создать объект Frame как окно верхнего уровня.

Здесь мы создаем объект Frame, устанавливаем его размеры и делаем его видимым.

В результате получаем окно с заголовком и кнопками минимизации и закрытия окна.

Однако закрыть такое окно мы не сможем.

Для этого мы должны добавить слушателя событий окна.

Абстрактный класс WindowAdapter реализует интерфейсы слушателя событий окна и предназначен для получения событий окна.

Метод windowClosing вызывается при нажатии кнопки закрытия окна.

И мы определяем этот метод, вызывая в нем метод exit системы.

Таким образом, теперь мы можем закрыть это окно.

Так как Frame — это контейнер, мы можем добавлять в него меню и другие элементы графического интерфейса пользователя, кнопки, метки, поля и т. д.

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

Каждый регион называется панелью.

Окно Frame и каждая панель могут иметь свою собственную компоновку LayoutManager.

Панели не имеют видимых ограничивающих линий.

Вы можете разграничить их разными цветами фона.

Метод setLayout класса Container устанавливает компоновку LayoutManager, которая отвечает за расположение элементов контейнера.

Существует пять стандартных AWT компоновок — классов, реализующих интерфейс LayoutManager, это FlowLayout, BorderLayout, CardLayout, GridLayout, и GridBagLayout.

Компоновка FlowLayout является компоновкой по умолчанию для панели, поэтому мы могли бы ее не устанавливать для панели методом setLayout.

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

Метод setSize работать не будет.

Эта компоновка помещает компоненты в строки слева направо, сверху вниз, обеспечивая по умолчанию 5 пикселей между элементами в строке и между строками.

Компоненты в строках по умолчанию находятся в центре.

Выравнивание компонента в строке можно изменить с помощью константы FlowLayout. LEFT или FlowLayout. RIGHT в конструкторе класса FlowLayout.

Компоновка BorderLayout является компоновкой по умолчанию для окон Frame и Dialog, поэтому мы можем ее не устанавливать для окна методом setLayout.

Эта компоновка разделяет контейнер на пять регионов.

Каждый регион идентифицируется соответствующей константой BorderLayout — NORTH, SOUTH, EAST, WEST, и CENTER

NORTH и SOUTH изменяют размер компонента до его предпочтительной высоты.

EAST и WEST изменяют размер компонента до его предпочтительной ширины.

Центру предоставляется оставшееся пространство.

При добавлении компонента в контейнер, указывается регион, куда добавлять компонент.

По умолчанию, компонент будет добавляться в центр.

Компоновка GridLayout разделяет окно на прямоугольники равного размера на основе количества указанных строк и столбцов.

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

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

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

При создании компоновки указывается количество строк и столбцов.

По умолчанию создается одна строка с одним столбцом.

Компоновка устанавливается для контейнера методом setLayout и затем компоненты добавляются в контейнер методом add.

Компоновка CardLayout работает как стек, помещая компоненты друг поверх друга, и связывает имя с каждым компонентом в окне.

Эта компоновка хорошо подходит для размещения единственного компонента в окне.

Компоновка GridBagLayout разделяет окно на ячейки сетки, не требуя, чтобы компоненты были одного размера.

При этом каждый компонент, управляемый компоновкой, ассоциируется с экземпляром GridBagConstraints.

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

Для использования этой компоновки сначала создается экземпляр GridBagLayout, который устанавливается для контейнера методом setLayout.

Затем создается экземпляр GridBagConstraints, параметры которого изменяются для каждого компонента.

gridx и gridy указывают номер ячейки для компонента.

gridwidth и gridheight указывают количество столбцов и строк, которые компонент занимает.

fill указывает что делать с компонентом, который меньше, чем размер ячейки.

ipady и ipadx указывают отступ.

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

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

Для этого нужно точно указывать координаты компонента и его размеры, например, с помощью метода setBounds.

До сих пор мы рассматривали окно Frame.

Однако помимо окна Frame, библиотека AWT позволяет создавать диалоговые окна с помощью класса Dialog.

Для создания диалогового окна, которое открывается из окна Frame, нужно создать экземпляр класса Dialog, указав в его конструкторе родительское окно, из которого будет открываться данное диалоговое окно.

Также можно указать заголовок окна и будет ли окно модальным, то есть будет ли оно блокировать все входные данные для окон верхнего уровня.

Далее можно наполнить диалоговое окно содержимым, напомним, что по умолчанию компоновка диалогового окна — это BorderLayout.

Для закрытия окна, к его компоненту нужно присоединить слушателя, в обработчике которого нужно вызвать метод setVisible (false) окна, сделав его невидимым.

Далее в основном окне, к его компоненту нужно присоединить слушателя, в обработчике которого нужно вызвать метод setVisible (true) диалогового окна, сделав его видимым.

И наконец, методом add нужно добавить диалоговое окно в основное окно, как обычный компонент.

Модель событий AWT

Мы уже несколько раз сталкивались со слушателями событий и обработчиками событий.

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

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

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

Процедурное программирование, которое рассматривается как традиционное программирование, определяет процесс программирования как разработку процедур, которые прямо управляют потоком данных и элементами контроля.

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

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

В AWT существуют две разные модели событий или способы обработки событий.

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

Сами события были инкапсулированы в один класс Event.

Для обработки таких событий нужно было переопределить метод action или handleEvent компонента, который вызывался при получении события компонентом.

Таким образом, в этой ранней модели обработчики событий, такие как action и handleEvent, были реализованы классом Component.

И версии этих методов по умолчанию ничего не делали и возвращали false.

Эта модель событий была заменена моделью Java 1.1.

Java 1.1 реализует модель делегирования, в которой события передаются только объектам, зарегистрированным для получения события.

Эта модель позволяет любому объекту получать события, генерируемые компонентом.

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

В модели событий Java 1.1 вся функциональность обработки событий содержится в пакете java.awt. event.

Внутри этого пакета подклассы абстрактного класса AWTEvent представляют собой различные виды событий.

Класс AWTEvent и его подклассы заменяют Event предыдущей модели событий.

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

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

Пакет также содержит ряд классов адаптеров.

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

Эти классы удобны для создания объектов-слушателей.

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

Эта модель требует, чтобы объекты регистрировались для получения событий.

Затем, когда происходит событие, об этом уведомляются только те объекты, которые были зарегистрированы.

Эта модель называется «делегирование».

Она реализует шаблон проектирования Observer.

Таким образом, эта модель обеспечивает четкое разделение между компонентами GUI и обработкой событий.

Важно, чтобы любой объект, а не только компонент, мог получать события.

Таким образом, вы можете отделить свой код обработки событий от вашего графического интерфейса.

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

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

Модель делегирования важна для JavaBeans, которые позволяют взаимодействовать между Java и другими платформами.

Чтобы обеспечить такое взаимодействие, необходимо было отделить источник события от получателя.

В модели делегирования события могут передаваться нескольким получателям; любое количество классов может быть зарегистрировано для получения события.

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

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

В Java 1.1 это не требуется.

Событие будет передано каждому объекту, зарегистрированному в качестве слушателя для этого события, независимо от того, что другие объекты делают с событием.

Наконец, эта модель событий представляет идею очереди событий.

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

В Java 1.1 каждый компонент является источником события, который может генерировать определенные типы событий, которые являются подклассами класса AWTEvent.

Объекты, которые интересуются событием, называются слушателями.

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

Чтобы получить событие, объект должен реализовать соответствующий интерфейс слушателя и должен быть зарегистрирован в источнике события, путем вызова метода «add listener» компонента, который генерирует событие.

И мы это уже видели.

Здесь мы создаем кнопку и присоединяем к ней слушателя, как экземпляр анонимного класса, который реализует интерфейс слушателя.

В этом классе мы переопределяем обработчик событий, метод интерфейса слушателя.

Как только объект зарегистрирован, метод actionPerformed будет вызываться всякий раз, когда пользователь делает что-либо в компоненте, который генерирует событие действия.

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

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

Некоторые интерфейсы слушателей предназначены для работы с несколькими типами событий.

Например, интерфейс MouseListener объявляет пять методов обработки различных типов событий мыши: мышь вниз, мышь вверх, щелчок, вход мыши в компонент и выход мыши.

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

Это звучит как создание излишнего кода; большую часть времени вас интересует только одно или два из этих событий.

К счастью, вам этого делать не нужно.

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

И если вы хотите написать класс обработки событий, который имеет дело только с щелчками мыши, вы можете объявить, что ваш класс расширяет MouseAdapter.

И ваша единственная задача программирования состоит в том, чтобы переопределить единственный метод, который вам нужен — это mouseClicked.

Таким образом, резюмируя.

Компоненты генерируют AWTEvents, когда что-то происходит.

Различные подклассы AWTEvent представляют различные типы событий.

Например, события мыши представлены классом MouseEvent.

И каждый компонент может генерировать определенные подклассы класса AWTEvent.

Обработчики событий регистрируются для приема событий с помощью метода «add listener» в компоненте, который генерирует событие.

Существуют различные методы «add listener» для каждого вида событий AWTEvent, которые может генерировать компонент.

Например, чтобы заявить о своем интересе к событию мыши, вы вызываете метод addMouseListener компонента.

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

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

Например, MouseListener определяет методы, вызываемые при возникновении событий мыши.

Большинство типов событий также имеют класс адаптера.

Например, события MouseEvent имеют класс MouseAdapter.

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

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

Например, вместо реализации всех пяти методов интерфейса MouseListener класс может расширить класс MouseAdapter и переопределить один или два метода, которые нужны.

Класс EventQueue позволяет напрямую управлять событиями Java 1.1.

Обычно вам не нужно самостоятельно управлять событиями; система сама заботится о доставке событий.

Однако, если вам нужно, вы можете получить очередь событий системы, вызвав Toolkit.getSystemEventQueue, затем вы можете заглянуть в очередь событий, вызвав peekEvent или опубликовать новые события, вызвав postEvent.

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

Данный класс обеспечивает диспетчеризацию событий, т.е. извлечение событий из очереди и отправки их вызовом внутреннего метода dispatchEvent (AWTEvent event), который в качестве параметра принимает объект класса AWTEvent, представляющий собой AWT события.

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

Метод dispatchEvent класса EventQueue определяет, к какому графическому компоненту относится данное событие и производит вызов метода dispatchEvent соответствующего компонента.

Метод dispatchEvent наследуется каждым компонентом от базового класса java.awt.Component.

Далее событие передается из метода dispatchEvent методу processEvent (AWTEvent e), который в свою очередь передает событие методу process <event type> Event, определенному для каждого класса событий.

После этого метод process <event type> Event передает событие объекту интерфейса <event type> Listener, зарегистрированному соответствующим слушателем add <event type> Listener, где событие и обрабатывается методом, определенном в интерфейсе.

Объект класса EventQueue автоматически создается виртуальной машиной Java, когда приложением создается объект — наследник класса java.awt.Component.

При этом автоматически создается также объект класса java.awt. EventDispatchThread, который представляет собой поток, работающий параллельно основному потоку программы.

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

Методом pumpEvents класса EventDispatchThread события извлекаются из очереди и передаются методу dispatchEvent класса EventQueue.

Таким вот образом события передаются от источника слушателю.

Компоненты управления AWT

Каждый пользовательский интерфейс состоит из трех основных аспектов.

Это элементы пользовательского интерфейса.

Они являются основными визуальными элементами, которые пользователь в конечном итоге видит и взаимодействует с ними.

Макеты или компоновки.

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

И поведение.

Это события, которые происходят, когда пользователь взаимодействует с элементами пользовательского интерфейса.

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

Класс Button представляет кнопку, элемент управления, который имеет метку и генерирует событие при нажатии.

Когда кнопка нажата и отпущена, AWT отправляет экземпляр ActionEvent события к кнопке, вызывая метод processEvent кнопки.

Метод processEvent кнопки получает все события для кнопки, и он передает событие, вызывая собственный метод processActionEvent.

Этот метод передает событие любому слушателю, который зарегистрировал свой интерес к событиям, сгенерированным этой кнопкой.

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

Элемент Сheckbox используется для включения опции (true) или ее выключения (false).

Для каждого флажка есть метка, обозначающая, что делает флажок.

И состояние флажка можно изменить, щелкнув по нему.

Объект флажка создается с помощью конструктора, которому передается метка флажка.

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

Здесь используется слушатель ItemListener, а не ActionListener.

Он слушает изменение состояния компонента, а не действия, предоставляя метод itemStateChanged.

Превратить флажок в радио кнопку, можно создав группу флажков.

При создании каждого флажка, эта группа передается в конструктор, тем самым добавляя флажок в группу флажков.

Радио кнопка отличается от флажка тем, что одновременно может быть выбрана только одна радио кнопка, а флажки могут быть отмечены сразу несколько.

Класс CheckboxGroup имеет метод getSelectedCheckbox, который возвращает выбранную радио кнопку.

Компонент выбора Choice используется для отображения всплывающего меню выбора.

Выбранный элемент отображается в верхней части меню.

Класс Choice имеет метод getSelectedItem, который возвращает выбранный элемент в виде строки.

Label — это пассивный элемент управления, так как он не создает никакого события пользователя.

Метка просто отображает одну строку текста, доступную только для чтения.

Текст метки может быть изменен программным способом, но никак не может быть изменен конечным пользователем.

Список List представляет собой список текстовых элементов.

Список может быть настроен так, что пользователь может выбрать один или несколько элементов, с помощью второго аргумента конструктора.

В этом отличие списка от выбора Choice.

Также List — это статический список, а не выпадающий список выбора, как Choice.

Компоненты List, TextArea и ScrollPane поставляются с готовыми полосами прокрутки.

Однако, если вы хотите прокрутить любой другой объект, вам придется использовать полосу прокрутки Scrollbar.

Полосы прокрутки в большинстве случаев используются для перемещения видимой области.

Они также могут использоваться для установки значения между двумя числами.

Или они могут использоваться для пролистывания нескольких экранов.

В этом примере мы создаем пользовательский компонент, который расширяет панель и реализует интерфейс AdjustmentListener, для получения событий прокрутки Scrollbar.

При создании пользовательского компонента мы должны расширить класс Component или один из его подклассов.

Также мы должны определить методы расчета размеров компонента и метод paint отрисовки компонента.

В конструкторе этого класса мы создаем горизонтальную и вертикальную полосы прокрутки.

Устанавливаем их размеры на основе размеров пользовательского компонента.

И добавляем эти полосы прокрутки в пользовательский компонент.

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

Полоса прокрутки генерирует событие настройки, когда изменяется значение полосы прокрутки.

Для обработки этого события определяется метод adjustValueChanged интерфейса AdjustmentListener.

В этом методе мы получаем значения полос прокрутки и перерисовываем наш компонент.

В методе paint мы рисуем круг с диаметром, на основе значений полос прокрутки.

Таким образом, перемещая ползунки полос прокрутки, мы изменяем диаметр круга.

Элемент управления TextArea в AWT предоставляет многострочную область редактора.

Пользователь может вводить здесь столько, сколько он хочет.

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

При создании компонента TextArea указывается количество строк и столбцов видимой области текста.

Компонент TextField позволяет пользователю редактировать одну строку текста.

Когда пользователь вводит символ в текстовое поле, в поле отправляется событие нажатия клавиши.

Событие нажатия клавиши передается зарегистрированному слушателю KeyListener.

Также можно обрабатывать событие ActionEvent, которое запускается нажатием клавиши enter.

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

При создании поля можно указать количество видимых символов.

Метод setEchoCharacter указывает символ, который будет отображаться вместо символов, вводимых пользователем.

Этот метод используется для ввода паролей.

Обычно, окно верхнего уровня имеет связанную с ним панель меню.

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

Для создания меню, пакет java.awt предоставляет четыре основных класса — MenuBar, Menu, MenuItem и CheckboxMenuItem.

Все эти четыре класса не являются компонентами AWT, поскольку они не являются подклассами класса Component.

На самом деле, они являются подклассами класса MenuComponent, который никак не связан в иерархии с классом Component.

Панель меню MenuBar содержит само меню.

MenuBar добавляется к Frame с помощью метода setMenuBar.

По умолчанию, панель меню добавляется сверху окна Frame.

MenuBar не может быть добавлена к другим сторонам окна.

Меню Menu содержит пункты меню.

Меню добавляется в панель меню с помощью метода add.

В меню можно добавить подменю.

Элемент MenuItem отображает опцию, которую может выбрать пользователь.

Элементы меню добавляются в меню с помощью метода addMenuItem.

Между пунктами меню может быть добавлен разделитель с помощью метода addSeparator.

Элемент CheckboxMenuItem отличается от элемента MenuItem тем, что он отображается вместе с флажком.

В этом примере сначала мы создаем панель меню.

Затем создаем меню.

Далее создаем элементы меню и присоединяем к ним слушателей событий.

Метод setActionCommand устанавливает имя команды для события действия, которое генерируется этим пунктом меню.

По умолчанию для команды действия, имя устанавливается как метка элемента меню.

Затем элемент меню добавляется в меню.

Меню добавляется в панель меню.

А панель меню устанавливается для окна верхнего уровня.

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

Для этого класс PopupMenu предоставляет метод show, который в качестве аргумента получает компонент, в котором отображается всплывающее меню, и координаты позиции для отображения меню.

В этом примере мы создаем всплывающее меню.

И в слушателе клика мыши панели, показываем всплывающее меню.