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

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

20

ГЛАВА 1

придется прикладывать титанических усилий, чтобы оставаться многократно используемым и полезным элементом системы, способным работать с любой моделью. Вид четко знает, какой элемент он представляет на экране, то есть данные модели, как бы она ни была реализована, он выведет на экран надлежащим образом (с видом вообще нет проблем). Находящийся теперь с ним в «одном флаконе» контроллер может проще решить свою задачу обработки событий пользователя: когда нужно, он сразу изменяет вид (это необходимо для смены каких-либо аспектов вида, не связанных с данными модели, как правило, эстетических, во имя удобства пользователя). Взаимодействие контроллера

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

Надо сказать, что разделение функций компонента только на две части (UI-представи- теля и модель) как нельзя лучше подходит для Swing. Разработчики Swing не стремились создать какой-то новый тип пользовательского интерфейса, они, прежде всего, должны были обеспечить поддержку компонентами всех известных платформ таким образом, чтобы Java-приложения по возможности внешне не отличались от приложения для конкретной платформы. UI-представители позволяют легко реализовать такое поведение. Оставляя функции компонента и модели данных в стороне, нужно лишь изменить UIпредставителя, чтобы он реагировал на действия, характерные для какой-то платформы,

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

создатели Swing сумели сохранить ее основные достоинства: простое изменение внешнего вида и поведения компонентов (это осуществляется заменой UI-представителя компонента), а также мощь модельного программирования (программист по-прежнему может использовать различные модели для одного компонента, менять данные и манипулировать ими, не заботясь об обновлении вида и о типе компонента, описывать данные в терминах решаемой задачи). Не совсем правильно говорить, что в Swing задействована архитектура MVC (в библиотеке реализована архитектура из двух частей, а не из трех), поэтому часто говорят об использовании в Swing отношения модель-представитель (modeldelegate), или об архитектуре с разделенной моделью (separable model architecture).

Как все работает

Кажется, мы дошли до сути механизма, обеспечивающего компонентам Swing различные поведение и внешний вид. Имеется UI-представитель, обрабатывающий события пользователя и рисующий компонент на экране; есть модель, хранящая данные компонента. Непонятно одно — как этот механизм взаимодействует с классами библиотеки Swing, такими как кнопки (JButton) или списки (JList). Работать с ними просто — вы создаете экземпляр класса кнопки и добавляете его в контейнер. Где же UI-представитель? Очевидно, что не в классах компонентов, иначе менять их внешний вид и поведение было бы невозможно (пришлось бы переписывать все эти классы для поддержки другого внешнего вида).

Рисунок 1.5 иллюстрирует роль, которую играет класс компонента во взаимоотношениях UI-представителя, модели и конечных пользователей (к ним относятся прог- раммисты-клиенты Swing). Можно сказать, что класс компонента — это точка приложения сил архитектуры «модель-представитель», в нем сосредотачивается информация о том, как UI-представитель взаимодействует с некоторой моделью. Модель не знает, с каким UI-представителем она сотрудничает и какой компонент ее использует, все что известно о модели — это то, что она есть. Раз модель существует, на нее должна быть

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

21

ссылка. Хранится эта ссылка в классе компонента. UI-представитель связывается с моделью только через класс компонента. Прямой связи нет, и это главное условие гибкости и взаимозаменяемости. Таким образом осуществляется обмен данными между видом и моделью. Программисту, намеревающемуся использовать некоторый компонент, не придется думать о том, какой UI-представитель задействован в данный момент и как его соединить с моделью. От него требуется лишь настроить модель (или применить модель по умолчанию) и передать ее компоненту. Компонент знает, какого UI-предста- вителя нужно использовать (он получает эту информацию от менеджера внешнего вида UIManager, о котором мы вскоре поговорим), и готов к работе10.

Компонент

Представитель

UI

 

Ссылка на

 

представителя

 

UI

 

Ссылка на

UIManager

модель

 

(или

 

модели)

 

Модель

 

Рис. 1.5. Взаимоотношения UI-представителя и модели

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

Управление внешним видом и поведением программы

В библиотеке Swing довольно много компонентов, и каждый из них имеет своего UI-представителя, ответственного за обработку событий и прорисовку компонента на экране. Рано или поздно настает момент, когда внешний вид и поведение вашего Javaприложения приходится менять (например, чтобы оно выглядело одинаково с приложениями той платформы, на которой ему приходиться работать). Если бы разработчику

10 Если использовать терминологию шаблонов проектирования, то можно сказать, что с точки зрения UI-представителей и моделей классы компонентов Swing действуют как посредники (mediators), обеспечивая слабую связанность системы. С точки же зрения программистов-клиентов Swing классы компонентов являются фасадами (facade) для архитектуры «модель-представитель» (применяя компонент, не обязательно задумываться о том, что происходит внутри него).

22

ГЛАВА 1

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

Поэтому в Swing управление внешним видом осуществляется в специальном классе UIManager. Он позволяет вам установить внешний вид и поведение для всех компонентов библиотеки сразу. Для этого нужно лишь вызвать статический метод этого класса setLookAndFeel() и передать в него объект класса LookAndFeel. Объект LookAndFeel — это хранитель информации об определенном внешнем виде и поведении программы, в нем содержится информация о UI-представителях, название внешнего вида, а также методы, упрощающие работу класса UIManager. По умолчанию компоненты автоматически «выбирают» себе UI-представителя именно с помощью класса UIManager.

Внешние виды для компонентов Swing, которые поставляются c пакетом разработки JDK 1.6 последних ревизий (и список не планируется дополнять в новой версии 1.7), перечислены в табл. 1.1.

Таблица 1.1. Доступные внешние виды компонентов Swing

Название

Местонахождение

Предназначение

Внешний вид и поведение приложений на Java

(внешний вид Metal, его

современный подвид называется Ocean, или внешний вид, не зависящий от платформы)

Пакет javax.swing.plaf.metal

Класс MetalLookAndFeel

Именно этот внешний вид используется в Swing по умолчанию в верси-

ях до 1.7 (если вы явно не установи-

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

ственный уникальный вид. Подхо-

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

для этого предназначены так назы-

ваемые «темы».

Полностью настраиваеПакет javax.swing.plaf.synth мый внешний вид Synth

Класс SynthLookAndFeel

Пакет, позволяющий менять внешний вид приложений с помощью изменяемых «обоев» (skins) или цветов. Сам он не определяет никакого вида, это система для под-

держки реализации внешнего вида

с помощью изображений или цве-

тов. Может быть настроен как через

классы, так и через файл настроек в формате XML.

Платформенно-независи-

Пакет com.sun.java.swing.plaf.

мый внещний вид Nimbus,

nimbus

предположительно замена

 

для Metal

Класс NimbusLookAndFeel

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

вида Synth. Преимуществом данного

вида без сомнения является возмож-

ность легко и самыми малыми штри-

хами менять внешний вид компонен-

тов, «подгоняя» их под свои нужды. Внешне более тяготеет к Unix-стилю.

Еще одним плюсом является исполь-

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

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

 

23

Таблица 1.1 (продолжение)

 

 

 

 

Название

Местонахождение

Предназначение

Внешний вид и поведение

Пакет com.sun.java.swing.plaf.

Windows-приложений

windows

 

Класс WindowsLookAndFeel

Этот внешний вид предназначен

для эмуляции Windows-приложе- ний. Его можно использовать толь-

ко при работе под Windows. Отли-

чается при работе на Windows XP

и других версиях некоторыми визуальными отличиями и эффектами. Внешний вид Windows Vista пока

что не реализован.

Внешний вид и поведение

Пакет com.sun.java.swing.plaf.

Unix-приложений

motif

 

Класс MotifLookAndFeel

Позволяет приложениям на Java

выглядеть аналогично Unix-прило- жениям с использованием среды CDE/Motif. Подходит для любых платформ (не только для Unix)

Кроме перечисленных внешних видов, входящих в стандартный инструментарий JDK, компании Apple и Sun также разработали внешний вид Macintosh (Mac Look & Feel). Если ваше приложение будет работать на платформе Mac, и вы хотите, чтобы оно выглядело соответственно, то можно загрузить этот внешний вид с сайта java.sun.com, либо он по умолчанию будет включен в пакете JDK для Macintosh. Однако внешний вид Mac, так же как и внешний вид Windows, можно использовать только на соответствующей платформе (таковы требования корпораций Apple и Microsoft). Специально для получения внешнего вида, соответствующего платформе, на которой работает приложение, в классе UIManager определен метод getSystemLookAndFeel(). При работе под управлением Windows этот метод вернет вам внешний вид Windows, а при работе под Unix — внешний вид Unix.

Лучше всего менять внешний вид и поведение перед тем, как на экране появится окно вашего приложения. Хотя никто не запрещает вам менять внешний вид прямо во время работы программы, в таком случае компоненты не изменятся автоматически, и вам придется вызывать специальный метод класса SwingUtilities, чтобы обновить их. К тому же при изменении внешнего вида прямо во время работы программы могут возникнуть проблемы с размерами компонентов и их расположением в контейнере — разные внешние виды придают компонентам разные размеры, и то, что прекрасно смотрится во внешнем виде Metal, может выглядеть ужасным при переходе к внешнему виду Motif. Кстати, это типичная ситуация для начинающих работать со Swing программистов: они настолько воодушевляются возможностью тасовать внешние виды и менять поведение своего приложения, что поначалу только этим и занимаются, не обращая внимания на то, что в результате внешний вид приложения сильно страдает.

В принципе, оптимальным для приложения является использование одного внешнего вида и одного варианта поведения. Такое заявление может показаться странным: как же отказываться от великолепного механизма, позволяющего одной строчкой кода полностью сменить внешность и реакцию приложения? Разнообразие еще никому не вредило, но как показывают время и уже созданные Java-приложения, широкий выбор внешних видов не позволяют получать по-настоящему эффектные приложения. Дело в том, что при разработке пользовательского интерфейса первоклассных программ учитываются рекомендации создателей компонентов этого интерфейса, что дает возможность добиваться наилучших результатов. Но невозможно сделать то же самое с помощью внешних видов для конкретных платформ: если вы создадите эффектное приложение с внешним видом Windows, полностью следуя рекомендациям Microsoft, вы не

24

ГЛАВА 1

сможете перенести его на Unix, потому что использовать внешний вид Windows на других платформах запрещено (а рекомендации Microsoft для интерфейса Unix не подходят, и это еще мягко сказано). Разрабатывая приложение под Mac, вы будете следовать рекомендациям Apple, и, сменив внешний вид приложения, можете сильно удивиться результатам.

Здесь на передний план выходит независимый от платформы внешний вид, Nimbus или Metal, специально созданный для Java-приложений. Компания Sun разработала для него ряд рекомендаций, выполняя которые, можно получить по-настоящему красивые интерфейсы. Мы подробно рассмотрим эти рекомендации и этапы воплощения их в жизнь в главе 7, когда будем говорить о размещении компонентов в контейнере. Создав интерфейс специально для независимого внешнего вида, вы с легкостью перенесете его на любую платформу. Все сказанное не стоит воспринимать как совет отказаться от внешних видов, эмулирующих известные платформы, но, как показывает практика, их использование все равно не обеспечивает полного соответствия «родным» приложениям этих платформ. Дело в том, что Swing всегда находится на шаг позади (сначала меняется интерфейс конкретной платформы, команда Swing разрабатывает внешний вид, эмулирующий этот интерфейс, обновленный внешний вид выходит в новом пакете JDK, а в это время интерфейс конкретной платформы опять меняется, пусть даже и ненамного). За изменения же внешнего вида Java можно не беспокоиться, потому что он меняется одновременно со Swing.

Некоторые вопросы вызывает внешний вид компонентов в стиле Nimbus и особенно Metal. Многие, мягко говоря, не находят их привлекательными (следует признать, что причины для недовольства имеются — слишком уж «топорно» выглядит этот лаконичный интерфейс по сравнению с современными системами пользовательских интерфейсов). Но вы вовсе не ограничены внешними видами, созданными в Sun. На данный момент имеется умопомрачительное количество разнообразных внешних видов, некоторые их которых определенно стоят того, чтобы на них обратили внимание. Вы вполне можете задействовать вместо него один из интерфейсов от стороннего производителя, по-прежнему выполняя рекомендации для интерфейсов от Sun, потому что большинство сторонних внешних видов являются просто производными от Metal/Synth/ Nimbus, оставляя без изменения поведение, размеры компонентов и пр. и меняя лишь изображения. Для начала можно зайти на сайт http://www.javootoo.com/, где найдутся все наиболее популярные внешние виды для Swing, например очень популярный и используемый во многих коммерческих продуктах с применением Swing внешний вид JGoodies Looks (при использовании в интерфейсе рекомендаций для внешнего вида Metal и компонентов во внешнем виде JGoodies Looks получаются приложения, способные «обставить» самые продуманные и изысканные пользовательские интерфейсы). В качестве неплохой и бесплатной замены внешнему виду Metal/Nimbus хорошо подходит внешний вид Substance, Liquid и многие другие.

С другой стороны, новый внешний вид Nimbus, который возможно станет внешним видом по умолчанию в версии JDK 1.7, намного приятнее и современнее своего предшественника Metal. Его цветовая гамма очевидно стремится к Unix, однако, как легко узнать из его документации, цвета Nimbus легко меняются несколькими настройками (управляют основными эффектами три базовых цвета), а тот факт, что Nimbus построен на Synth, позволяет подменять изображения, цвета или процедуру прорисовки любого компонента. Это может помочь создать намного более приятный внешний вид, чем тот, что доступен по умолчанию, с достаточно маленькими затратами.

Но в целом, подключаемые внешний вид и поведение (Pluggable Look And Feel, PLAF) — одно из самых мощных свойств Swing. Никакая другая библиотека или операционная система не позволяет осуществить подобные масштабные действия настолько просто и быстро. Вы можете разработать для своего приложения любой вид, не задумываясь о платформах и их различиях, создать совершенно особый колорит, подчерки-

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