Создание GUI с помощью пакета Swing
Java Foundation Classes, основные концепции. Исходная иерархия классов Abstract Window Toolkit. Представители пользовательского интерфейса. Обработка событий в JavaBeans. Элементы управления, многострочное поле JText. Листинг программы TextEditor.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 26.06.2013 |
Размер файла | 220,6 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
ВВЕДЕНИЕ
Важнейшую часть любой программы составляет ее пользовательский интерфейс. Собственно говоря, пользователя мало интересуют те сложные алгоритмы обработки данных и удачные находки, реализованные внутри программы, также мало его занимают и технологии, примененные для создания самого приложения и его пользовательского интерфейса. Пользователь видит только то, что видит, и, отталкиваясь от этого факта, нам следует решать все задачи по проектированию и созданию пользовательского интерфейса. Интерфейс должен быть максимально удобным для пользователя и максимально быстрым; само собой, не последнее место занимает эстетическое удовлетворение, получаемое от работы с вашей программой.
Первые Java программы страдали бедностью интерфейсов. Более того, создание интерфейса, который запускался бы на любой платформе, часто было сложной задачей. Однако библиотека Swing изменила все. Благодаря Swing приложения могут прекрасно выглядеть и прекрасно работать и под Windows, и под Linux, и на любой другой платформе.
Swing - библиотека для создания графического интерфейса для программ на языке Java. Была разработана компанией Sun Microsystems. Содержит ряд графических компонентов, таких как кнопки, поля ввода, таблицы и т. д. Относится к библиотеке классов JFC, которая представляет собой набор библиотек для разработки графических оболочек. К этим библиотекам относятся Java 2D, Accessibility-API, Drag & Drop-API и AWT. Технология Swing - это пользовательский интерфейс Java-платформы. Она выступает как программное обеспечение, управляющее всем взаимодействием пользователя и компьютера.
1. SWING. ОСНОВНЫЕ КОНЦЕПЦИИ
1.1 Java Foundation Classes
Одной из самых больших и самых важных частей платформы J2SE является набор библиотек под общим названием Java Foundation Classes (JFC). Именно эти библиотеки предназначены для создания эффектных и отточенных пользовательских интерфейсов. Ниже перечислены библиотеки, входящие в набор Java Foundation Classes.
Swing. Важнейшая часть JFC; содержит компоненты для создания пользовательского интерфейса, такие как таблицы и текстовые поля, и инструменты для работы с этими компонентами. Библиотека Swing хорошо спланирована и реализована и способна воплотить все, что только может пожелать разработчик пользовательского интерфейса.
Java2D. Вторая по важности в JFC библиотека, позволяющая применять в своем приложении современную двухмерную графику, в том числе аффинные преобразования, дробные координаты, сглаживание, расширенные операции с растрами и многое другое. Библиотека Java2D встроена в Swing - все компоненты последней используются для вывода своих данных на экран.
Accessibility. Набор классов и интерфейсов, следующих промышленному стандарту и наделяющих приложения средствами поддержки пользователей с ограниченными возможностями. С помощью Accessibility вы сможете, к примеру, передать текстовое описание интерфейса системе синтеза речи, что позволит работать с вашей программой пользователям с нарушениями зрения. Замечательно то, что во всех компонентах Swing интерфейсы Accessibility уже реализованы, и после небольшой настройки самый обычный интерфейс моментально превращается в специализированный, ориентированный на пользователей с ограниченными возможностями.
Drag'n'Drop. Дополнение, позволяющее приложению взаимодействовать с приложениями операционной системы пользователя или другими Java-приложениями с помощью технологии перетаскивания (drag and drop). Подобная возможность очень удобна для пользователя и позволяет ему сразу же забыть о том, что приложение написано на Java и не имеет практически никаких связей с его операционной системой.
Ядром Java Foundation Classes без всяких сомнений является библиотека Swing - все остальные части набора классов так или иначе встроены в нее или предоставляют для компонентов этой библиотеки дополнительные возможности.
1.2 Swing и AWT
1.2.1 Swing
Если говорить кратко, то Swing - это набор графических компонентов для создания пользовательских интерфейсов приложений и апплетов, а также вспомогательные классы и инструменты для работы с этими компонентами. Легкость программирования, мощь тогда, когда она нужна, и возможность настроить все по своему вкусу - все это относится к Swing как к никакой другой библиотеке.
Обычно, если кто-то заявляет о безграничных возможностях новой библиотеки, это значит, что ее изучение, освоение и последующая работа будут непростыми. Это правило не срабатывает в случае с библиотекой Swing - работать с ней можно, не зная ровным счетом ничего о том, как она устроена, а ведь внутри нее скрыты совсем непростые механизмы. Например, внешний вид компонентов Swing можно легко изменить одной строчкой кода, и для этого не нужно знать подробностей. Только если вы соберетесь придать компонентам некий особенный (нестандартный) внешний вид, вам потребуются детали. Можно годы работать с библиотекой Swing, просто создавая компоненты, добавляя их в окна и обрабатывая события, и ничего не знать о скрытом в ней мощном механизме программирования моделей. Одним словом, Swing соответствует уровню каждого: и новичку, и опытному программисту будет казаться, что эта библиотека создана специально для него.
Поначалу библиотеки Swing в Java вообще не было. Вместо нее использовалась библиотека AWT, общая идея которой была относительно неплохой. Но вот реализовать эту идею толком не удалось, что очень сильно вредило Java как языку создания настольных приложений. Когда разработчики Java спохватились, было уже поздно, и с той поры о Java больше знают как о языке, используемом в мобильных устройствах и на стороне сервера, что при наличии такой библиотеки, как Swing, просто непростительно. Многие решения, принятые разработчиками Swing, были направлены на то, чтобы не допустить ошибок AWT и сделать библиотеку Swing пригодной для создания с минимальными усилиями современных пользовательских интерфейсов. По признанию большинства программистов, это команде Swing удалось с блеском.
Важнейшим отличием Swing от AWT является то, что компоненты Swing вообще не нуждаются в поддержке операционной системы и потому гораздо более стабильны и быстры. Такие компоненты в Java называются легковесными (lightweight), и понимание основных принципов их работы во многом объяснит работу Swing.
1.2.2 AWT
Основой библиотеки Swing, тем тонким слоем, что лежит между ней и зависящим от платформы кодом, является библиотека AWT (Abstract Window Toolkit - инструментарий для работы с различными оконными средами). В отличие от библиотеки Swing, которая появилась в Java версии 1.1 как нестандартное дополнение и стала частью платформы только с выходом Java 2, пакет java.awt входил в Java с самого первого выпуска. Поначалу именно он предназначался для создания пользовательских интерфейсов. Исходное назначение AWT - предоставить набор графических компонентов, который вобрал бы в себя наиболее характерные черты современных элементов управления и позволил бы однократно создавать пользовательские интерфейсы, подходящие для любой платформы. Компоненты AWT на самом деле не выполняли никакой работы и были очень простыми - это были просто «Java-оболочки» для элементов управления той операционной системы, на которой работал пользователь. Все запросы к этим компонентам незаметно перенаправлялись к операционной системе, которая и выполняла всю работу. Чтобы сделать классы AWT независимыми от конкретной платформы, каждому из них был сопоставлен своеобразный помощник (peer), который и работал с этой платформой. Для того чтобы встроить в AWT поддержку новой платформы, нужно было просто переписать код этих помощников, а интерфейс основных классов оставался неизменным. На рисунке 1.1 показана исходная иерархия классов AWT. Сверху располагаются базовые классы, а ниже классы, унаследованные от базовых.
Рисунок 1.1 - Исходная иерархия классов AWT
Как видно, базовые свойства и поведение всех графических компонентов были описаны в абстрактном классе Component, который таким образом стал ядром библиотеки AWT. Почти все компоненты пользовательского интерфейса (за исключением меню) были унаследованы от этого класса (это можно видеть на диаграмме наследования). Важным частным случаем компонента в AWT являлся так называемый контейнер, отличительные черты которого были описаны в классе Container (также абстрактном). Контейнер отличался от обычных компонентов тем, что мог содержать в себе другие компоненты (а значит, и другие контейнеры, что позволяло организовывать пользовательские интерфейсы любой сложности).
Однако неплохая на первый взгляд идея AWT провалилась. Этому способствовало множество причин:
* Чрезвычайно плохо была реализована схема обработки событий, благодаря чему пакет AWT надолго стал объектом нападок и насмешек. Создатели AWT не смогли придумать ничего лучшего, как сообщать обо всех событиях в метод handleEvent() из базового класса Component, и чтобы обработать эти события, приходилось наследовать от класса компонента (обычно от класса окна) и использовать огромный оператор switch (или if), распределяя их по обработчикам. Программисты, которые уже надеялись на избавление от этой адской процедуры, порядком поднадоевшей им еще со времен программирования для Windows, были сильно разочарованы. Более того, если в Windows они могли хотя бы быстро сопоставить пришедшее событие и адрес его обработчика, то в Java, из-за отсутствия в этом языке указателей, сделать даже это было невозможно. Все это делало заявления Sun о лучшем в мире языке программирования просто смешными. Вдобавок создание собственных типов событий оказывалось практически невозможным.
* Еще одной проблемой, пусть и не самой острой, стало отсутствие в AWT четкого механизма, позволяющего программистам создавать собственные компоненты и использовать их в средах визуального построения графического пользовательского интерфейса. Хотя такие средства и не замедлили появиться с выходом первой версии Java, возможности их оставляли желать много лучшего. Обычно все заканчивалось десятком компонентов AWT и в лучшем случае несколькими дополнительными компонентами. Добавить же в свою палитру компонентов новый элемент от стороннего производителя было почти невозможно, так как отсутствовал стандарт, способный обеспечить взаимодействие компонентов и средств от разных производителей. С другой стороны, создавать пользовательский интерфейс вручную было очень тяжело - задание для компонентов абсолютных экранных позиций противоречило концепции переносимости приложений, а имеющиеся в выпуске JDK 1.0 менеджеры расположения были либо очень простыми, либо чрезмерно сложными. Из-за этого процесс создания интерфейса AWT-приложений требовал слишком много времени и усилий.
* Множество неудобств доставляла также низкая скорость выполнения программ, написанных с помощью AWT, особенно программ, использующих графику и анимацию. Это было неудивительно - для выполнения любого действия над графическим компонентом виртуальной машине Java приходилось обращаться к операционной системе, то есть несколько раз переключаться в режим ядра и обратно. Учитывая дороговизну такой операции (сотни процессорных тактов), можно было сказать, что добиться нормальной скорости выполнения от Java-приложения было почти невозможно.
Недоработки AWT, перечисленные выше, делали почти невозможным создание качественных современных приложений на Java. Программисты вернулись к старым способам разработки приложений, а о Java-приложениях было составлено примерно такое мнение: «Крайне ограничены в функциональности и управляемости. Стоит использовать только там, где жизненно важным фактором является переносимость между платформами». К сожалению, мнение это было справедливо, и винить в этом создатели Java могли только себя.
Впрочем, программирование не ограничивается созданием приложений, и в остальных его областях, особенно в тех из них, что были связаны с сетевым и распределенным программированием, язык Java взял свое. Количество разработчиков на Java и фирм, лицензировавших новый язык, росло в геометрической прогрессии, и большинство признавало, что Java как никакой другой язык подошел бы для создания приложений и во много раз упростил и убыстрил бы этот процесс. Дело было лишь за хорошо спроектированной и продуманной библиотекой для создания пользовательских интерфейсов.
Когда прошло некоторое время после выпуска пакета JDK 1.1, начали появляться первые бета-версии новой библиотеки, получившей кодовое название «Swing». И даже эти первые версии, полные ошибок и недоработок, произвели ошеломляющее впечатление. Ничего подобного до сих пор в мире Java-приложений не было.
1.3 Представители пользовательского интерфейса
Разработчики Swing, для простоты в реализации и дальнейшем использовании, решили совместить вид и контроллер в одно целое (рисунок 1.2).
Рисунок 1.2 - Организация представителей
Как видно из рисунка, разработчики Swing объединили вид и контроллер в новый элемент, который назвали представителем (delegate) пользовательского интерфейса (User Interface, UI). Теперь все действия пользователя поступают не в контроллер, определяющий реакцию на них, а в этот новый элемент, в котором происходит значительная часть работы. Он определяет, нужно ли реагировать на них (так как контроллер теперь находится внутри, исчезает необходимость переделывать его, чтобы отключить реакцию на действия пользователя - свойство «включено/выключено» стало свойством представителя), и если нужно, то сразу же без генерации каких-либо событий и изменения данных меняет вид (это происходит быстро - вид и контроллер находятся в одном месте и имеют исчерпывающую информацию друг о друге, благодаря этому пользовательский интерфейс быстро реагирует на любые изменения и позволяет легко воспроизвести самые сложные операции по изменению данных), а уже после этого представитель говорит модели о том, что данные изменились и их необходимо обновить. Модель обновляет хранящиеся в ней данные и оповещает заинтересованных субъектов (чаще всего того же представителя) об изменениях. В ответ внешний вид компонента окончательно обновляется, чтобы соответствовать новым данным.
2. СОЗДАНИЕ GUI-ПРИЛОЖЕНИЯ В SWING
2.1 События
Графический пользовательский интерфейс (GUI) относится к системам, управляемым по событиям (event-driven systems). При запуске программы создается пользовательский интерфейс, а затем программа ждет наступления некоторого события: нажатия клавиши, движения мыши или изменения компонента системы. При наступлении события программа выполняет необходимые действия, а затем снова переходит к ожиданию. Программа, использующая для создания пользовательского интерфейса библиотеку Swing, не является исключением.
Событие (event) в пользовательском интерфейсе - это либо непосредственное действие пользователя (щелчок или движение мыши, нажатие клавиши), либо изменение состояния какого-либо компонента интерфейса (например, щелчок мыши может привести к нажатию кнопки). Источником события (event source) в Swing может быть любой компонент, будь то кнопка, надпись с текстом или диалоговое окно. Для того чтобы узнавать в своей программе о происходящих в компоненте событиях, необходимо сообщить компоненту о своей заинтересованности. Сделать это можно, передав компоненту слушателя (listener) определенного события.
Система обработки событий в Swing является частью архитектуры JavaBeans, которая позволяет создавать переносимые и легко используемые графические компоненты для визуальных средств разработки программ. Основой JavaBeans является соглашение об именах, которое позволяет визуальным средствам легко узнавать, какими свойствами обладает компонент. Для этого компонент определяет набор методов со специальными именами get/set. Методы эти служат для считывания и записи значений свойств компонента.
События в JavaBeans обрабатываются с помощью слушателей. Нетрудно понять, что для того, чтобы визуальное средство смогло определить, какие события могут возникать в компоненте, также необходим какой-то механизм для выявления этих событий. Таким механизмом является специальная схема именования событий и обрабатывающих их слушателей.
У каждого события есть имя. Например, слово «Key» (клавиша) - событие происходит при нажатии клавиш на клавиатуре. События, которые происходят в окнах, называются «Window» (окно); в общем случае будем считать, что названием события являются просто символы XXX. Чтобы событие стало доступно визуальному средству разработки, необходимо проделать описанную ниже процедуру.
1. Определить класс, в котором будет храниться информация о произошедшем событии (что это будет за информация, определяет создатель события). Класс должен быть унаследован от базового класса Java.util.EventObject и иметь название вида XXXEvent, где XXX - это название нашего события.
2. Создать интерфейс слушателя, в который будет приходить информация о событии. Это должен быть именно интерфейс, а не класс. Название интерфейса должно иметь следующий вид: XXXListener (например, KeyListener). Этот интерфейс должен быть унаследован от базового интерфейса всех слушателей событий Java.util.EventListener (это пустой интерфейс без методов, он просто помечает то, что унаследованный от него интерфейс является слушателем). В интерфейсе может быть определено сколько угодно методов, единственное требование к этим методам - наличие параметра типа XXXEvent. Никаких других параметров у методов быть не должно.
3. Включить поддержку события в класс компонента, в котором это событие может происходить. Чтобы сделать это, необходимо определить два метода: один для присоединения слушателей, другой для их отсоединения. Названия методов должны выглядеть следующим образом: addXXXListener() - для метода, присоединяющего слушателей, и removeXXXListener() - для метода, отсоединяющего слушателей.
Если данные требования выполнены, то визуальное средство легко найдет все типы событий, поддерживаемые компонентом, соответствующих им слушателей и определит методы для работы с этими слушателями. Гораздо важнее то, что, зная правила, по которым создаются события JavaBeans (а компоненты Swing используют именно эти события), можно очень просто определить всю интересующую информацию о событии, не перерывая документацию.
Надо сказать, что события в Java условно разделяются на низкоуровневые (low-level events) и высокоуровневые (high-level events). К низкоуровневым событиям относят те, что происходят непосредственно в результате действий пользователя: это движения мыши, передача фокуса ввода от одного приложения другому, нажатия клавиш и т. п. Они поступают в Java-программу от операционной системы или от внутренних механизмов виртуальной машины. Высокоуровневые события происходят в результате изменения состояния компонента. Такие события поступают не от операционной системы, а создаются самим компонентом. Процесс создания события еще называют запуском (fire). Во многих компонентах Swing можно увидеть методы с именами вида fireXXX(); именно в таких методах создаются объекты с информацией о событиях, которые затем рассылаются слушателям. Часто события высокого уровня возникают после того, как происходят несколько событий низкого уровня (например, кнопка сообщает о своем нажатии, после того как над ней была нажата и отпущена кнопка мыши).
Низкоуровневые события могут возникать в любом графическом компоненте, унаследованном от класса java.awt.Component. Однако есть несколько высокоуровневых событий, которые очень часто используются в компонентах. Это, прежде всего, события, которые позволяют компонентам сообщать об изменениях своих свойств.
События PropertyChangeEvent и ChangeEvent в обычных программах почти не используются, однако именно с их помощью происходит взаимодействие между компонентами, их UI-представителями и моделями. Событие PropertyChangeEvent - это основополагающее событие архитектуры JavaBeans, оно позволяет следить за тем, как и какие свойства меняются в компоненте (так называемые привязанные свойства). Событие ChangeEvent - это более простое событие, которое также дает знать об изменениях состояния компонента или модели. Довольно часто модели запускают это событие, сообщая об изменениях в данных. Событие ActionEvent встречается практически в каждом приложении, в основном благодаря тому, что почти в каждом приложении есть кнопки и/или меню. Впрочем, это событие возникает не только при щелчке на кнопке, оно часто используется и тогда, когда нужно сообщить о каком-то важном действии (выбор элемента в раскрывающемся списке, конец ввода в текстовом поле, срабатывание таймера и т. п.).
2.2 Элементы управления
2.2.1 Многострочное поле JTextArea
Многострочное текстовое поле JTextArea представляет собой более расширенную версию обычного текстового поля JTextField. Как и обычное поле JTextField, многострочное поле JTextArea предназначено для ввода простого неразмеченного различными атрибутами текста, но в отличие от обычных полей, позволяющих вводить только одну строку текста, многострочные поля дают пользователю возможность вводить произвольное количество строк текста. Кроме того, поле JTextArea часто используется для вывода разного рода подробной информации о работе приложения, отображать которую в диалоговых окнах или в консоли неудобно. Вывод информации в многострочное текстовое поле позволяет пользователю без труда просмотреть ее, как бы много ее ни было, и при необходимости скопировать или изменить. Работают с многострочными полями так же, как с обычными, отличие лишь в том, что для них приходится задавать не только ширину (максимальное количество символов), но и высоту (максимальное количество строк). Многострочные текстовые поля следует размещать в панелях прокрутки JScrollPane, иначе при вводе множества строк текста они «расползутся» но контейнеру и испортят вид остальных компонентов.
// Использование многострочных полей
import javax.swing.*;
import java.awt.Font;
public class UsingTextArea extends JFrame {
public UsingTextArea() {
super("UsingTextArea");
setDefaultCloseOperation(EXIT_ON_CLOSE);
// создаем пару многострочных полей
JTextArea area1 = new JTextArea("Многострочное поле", 5, 10);
area1.setFont(new Font("Dialog", Font.PLAIN, 14)); // шрифт
area1.setTabSize(10); // табуляция
JTextArea area2 = new JTextArea(15, 10);
area2.setLineWrap(true); // параметры переноса слов
area2.setWrapStyleWord(true);
JPanel contents = new JPanel(); // добавим поля в окно
contents.add(new JScrollPane(area1));
contents.add(new JScrollPane(area2));
setContentPane(contents);
setSize(400, 300); // выводим окно на экран
setVisible(true);
}
public static void main(String[] args) {
new UsingTextArea();
} }
В примере мы размещаем в окне пару многострочных текстовых полей JTextArea, для которых были изменены свойства, чаще других использующиеся в приложениях. Первое текстовое поле создается с помощью довольно функционального конструктора, задающего для поля находящийся в нем текст, количество строк и символов. Количество строк идет в списке параметров перед количеством символов. Задаваемые в конструкторе количества строк и символов поля определяют его размер в контейнере, но не накладывают каких-либо ограничений на объем вводимого текста, который может быть произвольным. Для первого поля был изменен шрифт и задано нестандартное значение для табуляции, вызывая метод setTabSize(). Данный метод позволяет указать, какое количество символов будет замещать символ табуляции (вставляемый нажатием клавиши Tab, по умолчанию - 8). Это может быть полезным в текстах с большим количеством отступов. Второе текстовое поле создается с помощью конструктора, принимающего в качестве параметров только количества строк и символов; поначалу текста в таком поле не будет. Для второго поля мы меняем свойства, управляющие процессом переноса текста на новые строки, именно эти свойства наиболее полезны при работе с многострочными полями. Метод setLineWrap() включает автоматический перенос текста на новую строку. Длинные слова будут переноситься на следующие строки, так что в таком многострочном поле никогда не потребуется горизонтальная прокрутка. Метод setWrapStyleWord() изменяет стиль переноса длинных слов на новые строки. При передаче в этот метод значения true, слова, не умещающиеся в строке, будут целиком переноситься на строку новую. По умолчанию значение этого свойства равно false, это означает, что текст переносится, как только ему перестает хватать места в строке, независимо от того, в каком месте слова приходится делать перенос. В заключение текстовые поля добавляются в панель содержимого окна, которое затем выводится на экран.
2.2.2 Главное меню JMenuBar
В арсенале компонентов графического интерфейса пользователя библиотеки Java Swing есть такой компонент, как главное меню JMenuBar. Оно, как правило, располагается в верхней части окна приложения в виде горизонтальной полоски, может иметь произвольную вложенность. При клике на пункте меню могут происходить определенные действия, предусмотренные разработчиком.
При организации меню на Java Swing используется не только класс JMenuBar, но и JMenu и JMenuItem. Скорее даже JMenuBar практически не используется - основная работа при конструировании меню происходит с JMenu и JMenuItem. В самом простом случае мы создаем экземпляр JMenuBar, добавляем к нему необходимый набор JMenu и JMenuItem (иногда, обычно только JMenu), а затем говорим JFrame использовать в качестве главного меню наше при помощи метода setJMenuBar. Параметр у метода setJMenuBar один - ссылка на JMenuBar.
Для реализации меню используются следующие классы:
* JMenuBar - панель меню, каждое меню определяется объектом JMenu;
* JPopupMenu - контекстное меню;
* JSeparator - разделитель меню;
* JMenuItem - базовый класс для следующих трех;
* JMenu - объект меню, используется для вложенных меню или как элемент для панели меню;
* JCheckboxMenuItem - элемент меню в виде флажка;
* JRadioButtonMenuItem - элемент меню в виде радио-кнопки.
2.2.3 Окно с рамкой JFrame
Окно с рамкой JFrame унаследовано от класса JWindow и представляет собой наиболее часто используемое в приложениях окно «общего назначения». В отличие от окон JWindow окна JFrame обладают рамкой (которая позволяет пользователям легко изменять их размер), заголовком с названием приложения, иногда системным меню (позволяющим проводить манипуляции с этим окном) и кнопками для управления окном. Именно класс JFrame применяется в подавляющем большинстве приложений для размещения компонентов пользовательского интерфейса.
// FrameClosing.java
// Использование окна с рамкой
import javax.swing.*;
public class FrameClosing extends JFrame {
public FrameClosing() {
super("Заголовок Окна");
setDefaultCloseOperation(EXIT_ON_CLOSE); //операция при закр. окна
setIconImage(getToolkit().getImage("icon.gif")); // значок для окна
setSize(300, 100); // вывод на экран
setVisible(true); }
public static void main(String[] args) { new FrameClosing(); }}
В этом примере создается подкласс JFrame, указывается заголовок окна (в конструкторе базового класса, хотя можно было бы использовать и метод setTitle()) и, прежде чем задать размеры окна и вывести его на экран, вызываем метод setDefaultCloseOperation(). Он позволяет указать, какое действие будет произведено в методе предварительной обработки событий processWindowEvent() при закрытии окна. По умолчанию применяется константа HIDE_ON_CLOSE, убирающая с экрана окно при его закрытии. В данном примере было использовано значение EXIT_ON_CLOSE, которое указывает, что при закрытии окна необходимо закончить работу приложения. Метод setIconImage() позволяет задать значок для окна. Из дополнительных возможностей окна с рамкой JFrame можно упомянуть о его способности «прятать» свои «украшения»: рамку и элементы управления окном. Делает это метод setUndecorated(true). После его вызова окно JFrame будет без рамки. Также стоит упомянуть метод setExtendedState(), который позволяет задать состояние окна, например, свернуть его, но работает на разных платформах по-разному (к примеру, с Windows и JDK 1.4 оно позволяет только свернуть окно, но не позволяет развернуть его на весь экран).
2.2.4 Выбор файлов в компоненте JFileChooser
Выбор файлов требуется в любом более или менее приличном приложении: в самом деле, все, что пользователями делается, чаще всего сохраняется в файлах, даже если расположены они на удаленных серверах. Тем удивительнее, что до выхода Java версии 2 да и некоторое время после этого в Swing с выбором файлов были проблемы. Компонент JFileChooser поддерживался в Swing с самого первого выпуска, вот только работал он с перебоями и странно, так что программистам приходилось использовать плохо управляемый, но зато работоспособный класс FileDialog библиотеки AWT. К примеру, с помощью компонента JFileChooser в Windows нельзя было выбрать файл с другого диска, так как поначалу этот компонент учитывал только особенности файловой системы Unix с одним корнем.
Впрочем, начиная с выпуска JDK 1.3, все проблемы остались позади, и теперь имеется отличный и легко настраиваемый инструмент для выбора файлов и, при необходимости, каталогов. Особенности различных файловых систем скрыты в подклассах абстрактного класса FileSystemView, и беспокоиться об этом больше не придется: выбранный для приложения внешний вид отобразит файловую структуру как подобает, соответственно текущей операционной системе.
// SimpleFileChooser.java
// Создание простых диалоговых окон открытия и сохранения файлов
import javax.swing.*;
import java.awt.event.*;
public class SimpleFileChooser extends JFrame {
JFileChooser fc = new JFileChooser(); // общий экземпляр JFileChooser
public SimpleFileChooser() {
super("SimpleFileChooser");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton open = new JButton("Открыть...");
open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fc.setDialogTitle("Выберите каталог");
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int res = fc.showOpenDialog(SimpleFileChooser.this);
if ( res == JFileChooser.APPROVE_OPTION ) // если файл выбран, покажем его
JOptionPane.showMessageDialog(
SimpleFileChooser.this, fc.getSelectedFile());
}});
JButton save = new JButton("Сохранить...");
save.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fc.setDialogTitle("Сохранение файла");
fc.setFileSelectionMode(JFileChooser.FILES_ONLY); // настройка режима
int res = fc.showSaveDialog(SimpleFileChooser.this);
// сообщим об успехе
if ( res == JFileChooser.APPROVE_OPTION )
JOptionPane.showMessageDialog(
SimpleFileChooser.this, "Файл сохранен");
}});
JPanel contents = new JPanel();// добавим кнопки и выведем окно на экран
contents.add(open);
contents.add(save);
setContentPane(contents);
setSize(300, 200);
setVisible(true);
}
public static void main(String[] args) {
new SimpleFileChooser();
}}
В примере создается небольшое окно с двумя кнопками. После щелчков на этих кнопках на экране появляются диалоговые окна для открытия и сохранения файлов. На весь пример всего один экземпляр компонента для выбора файлов JFileChooser, хотя мы и сохраняем файлы и открываем их. Более того, эти действия можно делать многократно, поскольку, как уже отмечалось, JFileChooser представляет собой обычный компонент, и его можно создать один раз, а затем после соответствующей настройки снова и снова выводить в подходящих диалоговых окнах. При щелчке на первой кнопке на экран выводится диалоговое окно открытия файлов. Соответствующий заголовок для диалогового окна можно задать методом setDialogTitle(). Перед выводом диалогового окна для выбора файлов на экран нужно настроить режим выбора. Компонент JFileChooser может работать в одном из трех режимов (режим выбора хранится в свойстве fileSelectionMode). Доступные режимы работы JFileChooser:
FILES_ONLY - Пользователю для выбора (независимо от того, сохраняется файл или открывается) будут доступны только файлы, но не каталоги. По умолчанию JFileChooser работает именно в этом режиме и правильно делает, поскольку подобный режим необходим чаще остальных. Именно в этом режиме пользователь сохраняет свою работу в файлах.
FILES_AND_DIRECTORIES - В этом режиме пользователь может выбирать и каталоги, и файлы. Как правило, этот режим хорош там, где нужно изменить общие свойства файловой системы.
DIRECTORIES_ONLY - Этот весьма ценный режим разрешает пользователю выбирать исключительно каталоги. Особенно хорош он там, где нужно выбирать каталоги под временные файлы, указывать каталоги с исходными текстами и т. п.
Щелкнув на второй кнопке, на экран вызовется диалоговое окно для сохранения файлов. Разница между ним и создаваемым первой кнопкой окном для открытия файлов невелика, всего лишь в надписях, используемых для компонентов JFileChooser. В примере режим выбора файлов установлен в FILES_ONLY, задан собственный заголовок для создаваемого окна методом setDialogTitle(). Выводится диалоговое окно на экран методом showSaveDialog(). Так же как и в случае окна для открытия файлов, для этого требуется только один параметр - «родительский» компонент. Если выбор файла для сохранения проходит успешно (возвращается значение APPROVE_OPTION), на экране появляется краткое сообщение, подтверждающее успешное сохранение файла.
2.2.5 Простые панели инструментов JToolBar
Создание панели инструментов в Swing не таит в себе никаких трудностей. Вы создаете компонент JToolBar, добавляете в него свои кнопки или другие компоненты (особенно удобно использовать для панелей инструментов «команды» Action, которые позволяют в одном месте указать и параметры внешнего вида кнопки, и описать то, что должно происходить при щелчке на ней) и выводите панель инструментов на экран. Проиллюстрирует сказанное следующий пример.
// SimpleToolbars.java
// Простые панели инструментов
import javax.swing.*;
import java.awt.event.*;
public class SimpleToolbars extends JFrame {
public SimpleToolbars() {
super("SimpleToolbars");
setDefaultCloseOperation(EXIT_ON_CLOSE);
// первая панель инструментов
JToolBar toolbar1 = new JToolBar();
// добавим кнопки
toolbar1.add(new JButton(new ImageIcon("images/New16.gif")));
toolbar1.add(new JButton(new ImageIcon("images/Open16.gif")));
// разделитель
toolbar1.addSeparator();
// добавим команду
toolbar1.add(new SaveAction());
// вторая панель инструментов
JToolBar toolbar2 = new JToolBar();
// добавим команду
toolbar2.add(new SaveAction());
// раскрывающийся список
toolbar2.add(new JComboBox(new String[] {"Жирный", "Обычный" }));
// добавим панели инструментов в окно
getContentPane().add(toolbar1, "North");
getContentPane().add(toolbar2, "South");
// выводим окно на экран
setSize(400, 300);
setVisible(true);
}
// команда для панели инструментов
class SaveAction extends AbstractAction {
public SaveAction() {
// настроим значок команды
putValue(AbstractAction.SMALL_ICON, new ImageIcon("images/Save16.gif"));
// текст подсказки
putValue(AbstractAction.SHORT_DESCRIPTION, "Сохранить документ...");
}
public void actionPerformed(ActionEvent e) {
}}
public static void main(String[] args) {
new SimpleToolbars();
}}
Создаются две панели инструментов, которые разместятся в небольшом окне JFrame. Сначала демонстрируется наиболее распространенный способ использования панели инструментов: создав компонент JToolBar, в него добавляются кнопки JButton, как правило, с небольшим значком (кнопки с надписями или большими значками выглядят непривычно и подходят только под определенный стиль пользовательского интерфейса). После двух кнопок добавляется разделитель, вызывая специальный метод addSeparator(). Используется разделитель в панели инструментов примерно так же, как в меню: для визуального отделения групп компонентов, выполняющих различные действия.
Третья кнопка добавляется не в виде компонента JButton, а как экземпляр команды Action, добавить команду позволяет специальная перегруженная версия метода add(). Это особенно верно для панелей инструментов: в классе команды задается значок и текст подсказки и тут же описывается действие, которое должна будет выполнить команда. После этого остается только добавить команду в панель инструментов.
Вторая панель инструментов демонстрирует, что храниться в ней могут не только кнопки, но и любые другие компоненты. Сначала в панель добавляется команда, а затем раскрывающийся список JComboBox, созданный на основе массива строк. Раскрывающиеся списки довольно часто «гостят» в панелях инструментов, и не зря: они занимают немного места и позволяют организовать гибкий выбор одного варианта из многих.
Созданные панели инструментов добавляются в «пограничные» области панели содержимого, в которой по умолчанию используется полярное расположение BorderLayout. Первая панель размещается на севере, а вторая - на юге окна. Расположение BorderLayout специально создано для главных окон приложения с панелями инструментов.
ВЫВОДЫ
программа листинг интерфейс java
В данной курсовой работе были рассмотрены основные компоненты библиотеки Swing (которая представляет собой набор графических компонентов для создания пользовательских интерфейсов приложений) с подробным их описанием и примерами реализации, наиболее значимые отличия Swing от AWT, система обработки событий. Так же была разработана программа TextEditor (листинг которой наведен в приложении А), с целью наглядно показать пример использования основных компонентов библиотеки. В данной программе пользователь имеет возможность создать, открыть, изменить и сохранить текстовый документ. Особенностью является то, что реализована возможность выбора отображаемого шрифта из пяти доступных, а так же указания его вида (жирный, курсив). Для большего удобства имеется панель инструментов с кнопками «Новый», «Открыть», «Сохранить».
ПРИЛОЖЕНИЕ
Листинг программы TextEditor
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
public class TextEditor extends JFrame {
public static final String FONTS[] = {"Lucida Console", "Courier New", "Comic Sans MS", "Arial", "Calibri"};
protected Font m_fonts[];
protected JTextArea my_text_area;
protected JMenuItem[] m_fontMenus;
protected JCheckBoxMenuItem m_bold;
protected JCheckBoxMenuItem m_italic;
protected JFileChooser my_file_chooser;
protected JToolBar m_toolBar;
public TextEditor()
{
super("Курсовая работа. Java Swing.");
setSize(700, 600);
setIconImage(getToolkit().getImage("img/ukraine.gif"));
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
this.setLocation (100, 100);
m_fonts = new Font[FONTS.length];
for (int k=0; k<FONTS.length; k++) m_fonts[k] = new Font(FONTS[k], Font.PLAIN, 12);
my_text_area = new JTextArea();
my_text_area.setLineWrap(true);
my_text_area.setWrapStyleWord(true);
JScrollPane ps = new JScrollPane(my_text_area);
getContentPane().add(ps, BorderLayout.CENTER);
my_text_area.append("Введите текст...");
JMenuBar menuBar = createMenuBar();
setJMenuBar(menuBar);
my_file_chooser = new JFileChooser();
my_file_chooser.setCurrentDirectory(new File("."));
WindowListener wndCloser = new WindowAdapter()
{
public void windowClosing(WindowEvent e) {
int res = JOptionPane.showConfirmDialog(null, "Закрыть программу?");
if ( res == JOptionPane.YES_OPTION ) System.exit(0); }
};
addWindowListener(wndCloser);
updateMonitor();
setVisible(true);
}
protected JMenuBar createMenuBar()
{
final JMenuBar menuBar = new JMenuBar();
JMenu mFile = new JMenu("Файл");
ImageIcon iconNew = new ImageIcon("img/new.gif");
Action actionNew = new AbstractAction("Новый", iconNew)
{
public void actionPerformed(ActionEvent e)
{
my_text_area.setText("");
}
};
JMenuItem item = mFile.add(actionNew);
mFile.add(item);
ImageIcon iconOpen = new ImageIcon("img/open.gif");
Action actionOpen = new AbstractAction("Открыть...", iconOpen)
{
public void actionPerformed(ActionEvent e)
{
TextEditor.this.repaint();
if (my_file_chooser.showOpenDialog(TextEditor.this) !=
JFileChooser.APPROVE_OPTION)
return;
Thread runner = new Thread() {
public void run() {
File fChoosen = my_file_chooser.getSelectedFile();
try{
FileReader in = new FileReader(fChoosen);
my_text_area.read(in, null);
in.close();
}
catch (IOException ex) { ex.printStackTrace(); }
}};
runner.start();
}
};
item = mFile.add(actionOpen);
mFile.add(item);
ImageIcon iconSave = new ImageIcon("img/save.gif");
Action actionSave = new AbstractAction("Сохранить...", iconSave)
{
public void actionPerformed(ActionEvent e)
{
TextEditor.this.repaint();
if (my_file_chooser.showSaveDialog(TextEditor.this)
!= JFileChooser.APPROVE_OPTION)
return;
Thread runner = new Thread() {
public void run() {
File fChoosen = my_file_chooser.getSelectedFile();
try
{
FileWriter out = new FileWriter(fChoosen);
my_text_area.write(out);
out.close();
}
catch (IOException ex) {ex.printStackTrace();}
}};
runner.start();
}};
item = mFile.add(actionSave);
mFile.add(item);
mFile.addSeparator();
Action actionExit = new AbstractAction("Выход")
{
public void actionPerformed(ActionEvent e)
{ System.exit(0); }
};
item = mFile.add(actionExit);
menuBar.add(mFile);
m_toolBar = new JToolBar();
JButton btn1 = m_toolBar.add(actionNew);
btn1.setToolTipText("Новый");
JButton btn2 = m_toolBar.add(actionOpen);
btn2.setToolTipText("Открыть");
JButton btn3 = m_toolBar.add(actionSave);
btn3.setToolTipText("Сохранить");
ActionListener fontListener = new ActionListener() {
public void actionPerformed(ActionEvent e)
{ updateMonitor(); }
};
JMenu mFont = new JMenu("Шрифт");
ButtonGroup group = new ButtonGroup();
m_fontMenus = new JMenuItem[FONTS.length];
for (int k=0; k<FONTS.length; k++)
{
int m = k+1;
m_fontMenus[k] = new JRadioButtonMenuItem(FONTS[k]);
boolean selected = (k == 0);
m_fontMenus[k].setSelected(selected);
m_fontMenus[k].setMnemonic('1'+k);
m_fontMenus[k].setFont(m_fonts[k]);
m_fontMenus[k].addActionListener(fontListener);
group.add(m_fontMenus[k]);
mFont.add(m_fontMenus[k]);
}
Размещено на Allbest.ru
Подобные документы
Описание пакета прикладной программы Net Beans 8.1. Разработка пользовательского интерфейса апплета. Создание рамочных окон на базе фреймов библиотеки java.swing. Изменение цвета текстовых данных. Проектирование и создание инфологической модели апплета.
контрольная работа [1,8 M], добавлен 11.07.2016Характеристика библиотеки java.awt. Обработка событий управляющими компонентами и менеджерами размещения. Основные виды компонентов. Написание программы–калькулятора, реализующую графический интерфейс. Спецификация класса Calc и иерархия классов AWT.
методичка [643,8 K], добавлен 30.06.2009Основа пользовательского интерфейса. Возможности пакетов java.awt.geom, java.awt, классов java.awt.Graphics и java.awt.Graphics2D. Основные графические примитивы и работа с потоками. Листинг программы и составление композиции аффинных преобразований.
методичка [525,3 K], добавлен 30.06.2009Написание алгоритма в среде Microsoft Foundation Classes, который приводит окружности к их перемещению слава направо с последующим появлением окружностей в левой части экрана, при достижении ими правой границы. Листинг и результаты работы программы.
курсовая работа [294,2 K], добавлен 25.05.2015Структура организации графического интерфейса, объявление и создание слушателей событий с помощью анонимных классов. Представление данных для таблицы – класс AbstractTableModel. Визуализация ячеек таблицы. Два основных типа потоков ввода-вывода в Java.
лекция [685,3 K], добавлен 01.05.2014Создание приложения для контроля знаний студентов, программ-тестов, созданных с помощью пакета прикладных программ Microsoft Office. Основные требования к его структуре и функциональности, взаимосвязь компонентов. Составление и листинг программы.
курсовая работа [900,3 K], добавлен 03.06.2014Понятие пакета как объединения классов (java.awt, java.lang). Способы импорта, проблема конфликта (пакеты содержат классы с одинаковым именем). Особенности реализации интерфейса, его поля. Понятие наследования интерфейса. Общие методы классов-оболочек.
презентация [140,1 K], добавлен 21.06.2014Сетевые возможности языков программирования. Преимущества использования Java-апплетов. Классы, входящие в состав библиотеки java.awt. Создание пользовательского интерфейса. Сокетное соединение с сервером. Графика в Java. Значения составляющих цвета.
курсовая работа [508,1 K], добавлен 10.11.2014Принципы написания консольных приложений на языке Java в среде Eclipse. Составление программы завтрака на основе списка продуктов, передаваемых в качестве параметров в командной строке. Создание пакета для классов, интерфейса, базового класса иерархии.
лабораторная работа [1,2 M], добавлен 01.05.2014Диаграмма консольного приложения табулирования функции. Отличие консольного приложения и приложения и GUI. Диаграмма классов для JFrameи JPanel. Создание простейшего фрейма в Java. Компоновка элементов интерфейса внутри фрейма. Цикл обработки событий.
лекция [693,8 K], добавлен 01.05.2014