Материал: Портянкин И. Swing

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

XVI

Введение

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

Благодарность команде Sun (или Oracle)

Хочется выразить свою огромную благодарность команде разработки библиотеки Swing компании Sun (впрочем, на момент окончания книги она уже стала частью компании Oracle). Большая часть этой команды находится у нас в России, в Санкт-Петер- бурге, ее участники рецензировали самые важные и сложные части этой книги и внесли множество неоценимых предложений и замечаний, а также помогли автору с некоторыми затруднениями. Особенно хочется поблагодарить Александра Поточкина, который к тому же ведет свой дневник о разработке приложений Swing в Интернете и является автором прекрасного инструмента JXLayer, который стал частью JDK и описан в этой книге в главе 6. Адрес его дневника, где размещено множество полезной информации, вы можете узнать на сайте книги.

Книга в Интернете

Свои отзывы о материале книги, предложения о дополнениях, комментарии, информацию о найденных ошибках вы сможете разместить на сайте www.IPSoftware.ru. Там же вы сможете задать свои вопросы автору, получить необходимые консультации, найти все исходные тексты данной книги, вспомогательные инструменты для работы с компонентами Swing, а также узнать о будущих планах и новых разработках в области Swing и Java Foundation Classes. Сайт книги к тому же описывает список самых интересных на данный момент дневников (блогов), библиотек, дополнительных внешних видов и инструментов, посвященных библиотеке, зная которые можно немало добавить к своим приложениям Swing.

Глава 1. Основные концепции

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

Итак, что же такое Swing? Если говорить кратко, то это набор графических компонентов для создания пользовательских интерфейсов приложений и апплетов, а также вспомогательные классы и инструменты для работы с этими компонентами. В принципе, это лаконичное заявление довольно точно описывает библиотеку Swing, но оно не должно вводить вас в заблуждение. Легкость программирования, мощь тогда, когда она нужна, и возможность настроить все по своему вкусу — все это относится к Swing как к никакой другой библиотеке.

Обычно, если кто-то заявляет о безграничных возможностях новой библиотеки, это значит, что ее изучение, освоение и последующая работа будут непростыми. Это правило не срабатывает в случае с библиотекой Swing — работать с ней можно, не зная ровным счетом ничего о том, как она устроена, а ведь внутри нее скрыты совсем непростые механизмы. Например, внешний вид компонентов Swing можно легко изменить одной строчкой кода, и для этого не нужно знать подробностей. Только если вы соберетесь придать компонентам некий особенный (нестандартный) внешний вид, вам потребуются детали. Можно годы работать с библиотекой Swing, просто создавая компоненты, добавляя их в окна и обрабатывая события, и ничего не знать о скрытом в ней мощном механизме программирования моделей. Одним словом, Swing соответствует уровню каждого: и новичку, и опытному программисту будет казаться, что эта библиотека создана специально для него.

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

Поначалу библиотеки Swing в Java вообще не было. Вместо нее использовалась библиотека AWT, общая идея которой была весьма неплохой. Но вот реализация этой идеи подразумевала довольно ограниченный набор компонентов, что очень сильно вредило Java как языку создания настольных приложений (desktop applications). Многие решения, принятые разработчиками Swing, были направлены на то, чтобы расширить излишне лаконичный набор компонентов AWT и сделать библиотеку Swing пригодной для создания с минимальными усилиями современных пользовательских интерфейсов. По признанию большинства программистов, команде Swing это удалось с блеском. Впрочем, по прошествии некоторого времени «шишки» AWT забылись, и сама она теперь лишь является верной помощницей Swing.

2

ГЛАВА 1

Важнейшим отличием Swing от AWT является то, что компоненты Swing вообще не нуждаются в поддержке операционной системы и поэтому гораздо более стабильны и быстры. Такие компоненты в Java называются легковесными (lightweight), и понимание основных принципов их работы во многом объяснит работу Swing. К сожалению, в документации и большей части изданных книг этим компонентам уделяется очень мало внимания (чаще всего определение легковесных компонентов состоит в том, что они «не используют код, зависящий от платформы»). Мы постараемся увидеть и «пощупать» легковесные компоненты, чтобы понять, почему же они появились в Java.

Также мы узнаем о таком «волшебном» свойстве Swing, как подключаемые внешний вид и поведение. Это свойство позволяет компонентам Swing вести себя максимально гибко, приспосабливаясь к любым условиям, принимать необходимый вид, а также предоставляет программистам такой удобный инструмент, как модели. Реализованы подключаемые внешний вид и поведение в Swing на основе уже ставшей классической архитектуры MVC (см. далее). После этого мы узнаем об еще одном «секретном оружии» Swing — поддержке специальных средств для пользователей с ограниченными возможностями, причем поддержка эта полностью реализована в самой библиотеке и не требует от программиста дополнительных усилий. Итак, начнем.

В начале было... AWT

Основой библиотеки Swing, тем тонким слоем, что лежит между ней и зависящим от платформы кодом, является библиотека AWT (Abstract Window Toolkit — инструментарий для работы с различными оконными средами). В отличие от библиотеки Swing, которая появилась в Java версии 1.1 как нестандартное дополнение и стала частью платформы только с выходом Java 2, пакет java.awt входил в Java с самого первого выпуска. Поначалу именно он предназначался для помощи в создании пользовательских интерфейсов.

Исходное назначение AWT — предоставить набор графических компонентов, который вобрал бы в себя наиболее характерные черты современных элементов управления и позволил бы однократно создавать пользовательские интерфейсы, подходящие для любой платформы. Компоненты AWT на самом деле не выполняют никакой работы и очень просты — это просто «Java-оболочки» для элементов управления той операционной системы, на которой работает пользователь. Все запросы к этим компонентам незаметно перенаправляются к операционной системе, которая и выполняет всю работу. Чтобы сделать классы AWT независимыми от конкретной платформы, каждому из них соответствует своеобразный помощник1 (peer), который и работает с этой платформой. Для того чтобы встроить в AWT поддержку новой платформы, нужно просто переписать код этих помощников, а интерфейс основных классов остается неизменным2.

На рис. 1.1 показана иерархия классов AWT. Диаграмма следует формату унифицированного языка моделирования (Unified Modeling Language, UML): сверху располагаются базовые классы, а ниже классы, унаследованные от базовых.

1 Дословный перевод слова «peer» — «равный, имеющий те же права», и так оно и есть — классы AWT и их помощники разделяют обязанности поровну: первые предоставляют услуги программис- там-клиентам Java, а вторые незаметно связывают эти услуги с операционной системой. Но с точки зрения программиста-клиента (а мы стоим именно на такой позиции) удобнее использовать слово «помощник».

2 Эту концепцию, использованную в AWT, можно описать и языком шаблонов проектирования. Это не что иное как мост (bridge) — программист взаимодействует с одной иерархией классов, а работа фактически выполняется в другой, параллельной иерархии. Последняя часто скрывается от глаз программиста, что позволяет легко изменять ее.

Основные концепции

3

Component

java.awt

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Button

 

Container

 

 

Canvas

 

Label

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Window

Panel

Dialog

Frame

Applet

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

Как видно, базовые свойства и поведение всех графических компонентов описаны в абстрактном классе Component, который является ядром библиотеки AWT. Почти все компоненты пользовательского интерфейса (за исключением меню) унаследованы от этого класса. Важным частным случаем компонента в AWT является так называемый контейнер, отличительные черты которого описаны в классе Container (также абстрактном). Контейнер отличается от обычных компонентов тем, что может содержать в себе другие компоненты (а значит и другие контейнеры, что позволяет организовывать пользовательские интерфейсы любой сложности). Одним из самых необычных свойств AWT можно назвать способность контейнеров располагать компоненты по определенному алгоритму, определяемому менеджером расположения (layout manager)3. Контейнерами высшего уровня, то есть контейнерами, содержащими все остальные элементы пользовательского интерфейса, служат окна с рамкой, диалоговые окна, а также апплеты, запускаемые из браузера. Они представлены классами Frame, Dialog и Applet.

Классы AWT, представляющие собой компоненты пользовательского интерфейса, такие как кнопки (Button) и надписи (Label), — очень небольшие и простые в использовании, как того и хотели создатели AWT. Вы можете смело работать с ними, зная, что на любой платформе компоненты вашего пользовательского интерфейса будут выглядеть так, как решит операционная система, то есть неотличимо от других ее приложений. Как мы уже знаем, об этом заботятся помощники компонентов. Их обязанности описаны в соответствующих интерфейсах (имя каждого можно получить, добавив к имени компонента слово «Peer», например ButtonPeer). Для поддержки библиотекой AWT новой платформы оставается только написать реализующие эти интерфейсы классы, работающие с данной платформой (например, в пакете JDK для Windows кнопки создаются с помощью класса WButtonPeer, реализующего интерфейс ButtonPeer). Такой механизм позволяет обеспечить переносимость графических приложений, написанных на Java.

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

3 Менеджер расположения — это особая служба, даже «стратегия», если думать на языке шаблонов, мы подробно обсудим, как и почему она используется в Java, в главе 7, которая полностью посвящена этому вопросу.

4

ГЛАВА 1

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

Почему же AWT является основой Swing? Связующим звеном, соединяющим Swing с реальным миром, являются легковесные компоненты AWT. Сами компоненты AWT имеют связь с операционной системой, на которой работает ваше приложение. Даже если вы создаете собственный компонент, наследуя от любого класса компонента AWT, вы все равно остаетесь в жестких рамках этих взаимоотношений, потому что ваш компонент представляет собой маленькое окно, полностью принадлежащее операционной системе. Как мы уже знаем, это влечет за собой массу проблем, прежде всего в плане гибкости ваших компонентов. Однако Java — полноценный и весьма мощный язык программирования, и для создания чего-либо на нем вовсе не обязательно обращаться к ресурсам операционной системы. Итак, легковесный компонент — это просто область в пространстве экрана, занимаемом вашим Java-приложением. Главные его атрибуты — это координаты в окне и размер. Для операционной системы легковесный компонент вообще не существует, потому что представляет собой всего лишь часть какого-то окна. Всю работу по поддержке легковесных компонентов берут на себя библиотека AWT и виртуальная машина Java. Для программиста не существует никакого отличия между легковесными и обычными компонентами, которые по аналогии стали называть тяжеловесными (heavyweight), то есть имеющими связь с операционной системой и представленными в своем собственном окне. Программирование абсолютно одинаково как для первых, так и для вторых. Конечно, где-то сказка должна заканчиваться, и связь с системой все же существует. Связь эту стали обеспечивать тяжеловесные контейнеры (обычно окна

иапплеты), в которых вы размещали свои легковесные компоненты. Именно они и встали на конце цепочки, прорисовывая легковесные компоненты в своем пространстве

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

Благодаря избавлению от сомнительных связей с разнообразными операционными системами легковесные компоненты полностью находятся во власти программиста на Java и могут следовать всем его указаниям. Они не ограничены тем или иным набором функций извне. Конечно, мы лишаемся части уже реализованной функциональности операционных систем (уж кнопки-то были написаны не один десяток лет назад) и вынуждены переписать базовые основы с нуля (точнее компания Sun была вынуждена это сделать при написании Swing), даже скопировать внешний вид компонентов4, но гибкость и 100% реализация на Java полностью оправдывает затраты, позволяя придать компонентам любой внешний вид и предоставить самый современный, широчайший набор функций.

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

4Представьте, насколько увлекательно было перерисовывать уже давно нарисованные кнопки

идиалоги Windows и Solaris на языке Java. Работа не из приятных, поэтому до сих пор трудно сказать, что имитация внешнего вида операционных систем в Swing верна на все сто.

Источник: https://studfile.net/preview/15935977/