Добавление в компонент новых событий
Поскольку мы наследуем компонент от класса JPanel, большинство необходимых событий он уже умеет генерировать. Но в ряде случаев может потребоваться другой тип событий. В ряде случаев имеется возможность использовать готовые интерфейсы слушателей. Например, мы хотим, чтобы возникло событие java.awt.event.TextEvent, связанное с изменением текста заголовка. “Обычная” панель JPanel не имела свойств, связанных с текстом, и это событие в ней не поддерживалось. Интерфейс java.awt.event.TextListener имеет всего один метод textValueChanged(TextEvent e), так что в адаптере нет необходимости.
Для создания такого события для нашего компонента требуется использовать добавление поддержки события через Bean Patterns.
В Java имеется два типа источников событий:
Unicast Event Source – источник порождают целевые объекты событий, которые передаются одному слушателю-приёмнику. “Cast” – список исполнителей, “Unit”- единичный, “Unicast” – от Unit и Cast - один обработчик, “Source” - источник. В этом случае список слушателей не создаётся, а резервируется место только для одного.
Multicast Event Source - источник порождают целевые объекты событий, которые передаются нескольким слушателям-приёмникам. “Multi” – много, “Multicast” – много обработчиков. В этом случае для событий данного типа создаётся список слушателей.
Очевидно, что для некоторых типов событий обязательно создавать список слушателей. Хотя в случае Unicast Event Source реализация оказывается проще. В нашем случае в списке нет необходимости, поэтому выберем первый вариант. В выпадающем списке диалога имеется возможность выбрать некоторые интерфейсы слушателей из пакетов java.awt.event и javax.swing.event. Однако нам нужен интерфейс, поддерживающий событие java.awt.event.TextEvent, который в нём отсутствует. Поэтому мы укажем имя интерфейса java.awt.event.TextListener вручную.
Задание в компоненте нового типа событий
При выборе варианта Generate Empty (“Генерировать Пустое”) в коде компонента появятся пустые реализации методов добавления и удаления слушателей. Это достаточно экзотический случай, поэтому мы выберем вариант Generate Implementation (“Генерировать Реализацию”).
Если выбрать опцию Generate Event Firing Methods (“Генерировать методы “выстреливания событиями” ”), происходит автоматическая генерация заготовок fire-методов fireИмяСобытия, предназначенных для оповещения зарегистрированных слушателей. В случае Unicast-источников обход списка слушателй не требуется, поэтому нам нет необходимости отмечать данный пункт. А вот в случае Multicast-источника это наиболее часто требующееся решение. При этом обычно бывает желательно передавать в методы событие как параметр – и для этого надо выбрать опцию Pass Event as Parameter (“Передавать событие как параметр”).
Если пункт Generate Event Firing Methods отмечен, а опция Pass Event as Parameter не выбрана, событие не будет передаваться в fire-методы, а будет создано в самом fire-методе. Именно так происходит в примере для свойства sampleProperty, где вызов
propertySupport.firePropertyChange(PROP_SAMPLE_PROPERTY,
oldValue, sampleProperty)
приводит к порождению внутри метода firePropertyChange события PropertyChange.
Генерация кода, поддерживающего интерфейс java.awt.event.TextListener, приведёт для Unicast-источника без генерации fire-методов к появлению следующего кода:
/**
* Utility field holding the TextListener.
*/
private transient java.awt.event.TextListener textListener = null;
/**
* Registers TextListener to receive events.
* @param listener The listener to register.
*/
public synchronized void addTextListener(java.awt.event.TextListener
listener) throws java.util.TooManyListenersException {
if (textListener != null) {
throw new java.util.TooManyListenersException ();
}
textListener = listener;
}
/**
* Removes TextListener from the list of listeners.
* @param listener The listener to remove.
*/
public synchronized void removeTextListener(java.awt.event.TextListener listener) {
textListener = null;
}
Но в этом случае добавлять код, обеспечивающий порождение события, должен программист.
Если выбрана опция генерации fire-методов без передачи события как параметра, появится следующий дополнительный код по сравнению с предыдущим вариантом:
/**
* Notifies the registered listener about the event.
*
* @param object Parameter #1 of the <CODE>TextEvent<CODE> constructor.
* @param i Parameter #2 of the <CODE>TextEvent<CODE> constructor.
*/
private void fireTextListenerTextValueChanged(java.lang.Object object,int i){
if (textListener == null) return;
java.awt.event.TextEvent e = new java.awt.event.TextEvent (object, i);
textListener.textValueChanged (e);
}
Этот код также не обеспечивает автоматической генерации события в нашем компоненте, но даёт возможность сделать это путём добавления одной строчки в код метода setTitle – перед вызовом метода repaint()мы напишем
fireTextListenerTextValueChanged(this,
java.awt.event.TextEvent.TEXT_VALUE_CHANGED);
В качестве первого параметра fire-метода идёт ссылка на объект-источник события, в качестве второго – идентификатор типа события. Найти, где задаётся идентификатор, просто – достаточно перейти мышкой по гиперссылке java.awt.event.TextEvent, появляющейся в среде разработке при нажатии клавиши <CTRL>, и посмотреть исходный код конструктора. – Данную гиперссылку можно получить в строке
java.awt.event.TextEvent e = new java.awt.event.TextEvent (object, i);
в теле метода fireTextListenerTextValueChanged, в которой, собственно, и используется этот не очень понятный с первого взгляда параметр.
Теперь после компиляции проекта мы можем назначать обработчики событий типа TextValueChanged нашему компоненту. К сожалению, для того, чтобы событие textValueChanged появилось в списке событий компонента в окне jTitledPanel1[JTitledPanel]-Properties/Events, требуется закрыть среду NetBeans и зайти в неё вновь. Для свойств этот баг отсутствует – они появляются в окне jTitledPanel1[JTitledPanel]-Properties/ Properties сразу после компиляции проекта.
Теперь для нашего компонента можно назначать и удалять обработчик события textValueChanged как непосредственно на этапе визуального проектирования, так и программным путём.
Покажем, каким образом это делается на этапе визуального проектирования. Выделим компонент jTitledPanel1 и выберем в окне jTitledPanel1[JTitledPanel]-Properties/Events событие textValueChanged. Нажмём кнопку с тремя точками, находящуюся рядом с полем – вызовется диалог добавления и удаления обработчиков событий. Вообще, имеется правило – если название на кнопке или пункте меню кончается на три точки, это означает, что при нажатии на кнопку или выборе пункта меню появится какой-нибудь диалог.
Создание обработчика события на этапе визуального проектирования
Введём в качестве имени обработчика события (event handler) в качестве примера “myHandler” и нажмём “OK”. В списке обработчиков Handlers формы “Handlers for textValueChanged” появится имя myHandler. При закрытии этой формы по нажатию “OK” в исходном коде приложения (а не компонента!) появится код
private void myHandler(java.awt.event.TextEvent evt) {
// TODO add your handling code here:
}
Вместо комментария “// TODO add your handling code here:”, как обычно, следует написать свой код обработчика. Например, такой:
javax.swing.JOptionPane.showMessageDialog( null,"Text="+
jTitledPanel1.getTitle() );
- Содержание
- Глава 1. Общие представления о языке Java 6
- Глава 2. Объектно-ориентированное проектирование и платформа NetBeans 26
- Глава 3. Примитивные типы данных и операторы для работы с ними 78
- Глава 4. Работа с числами в языке Java 95
- Глава 5. Управляющие конструкции 112
- Глава 6. Начальные сведения об объектном программировании 128
- Глава 7. Важнейшие объектные типы 175
- Введение
- Глава 1. Общие представления о языке Java
- 1.1. Java и другие языки программирования. Системное и прикладное программирование
- 1.2. Виртуальная Java-машина, байт-код, jit-компиляция. Категории программ, написанных на языке Java
- 1.3.Алфавит языка Java. Десятичные и шестнадцатеричные цифры и целые числа. Зарезервированные слова Алфавит языка Java
- Десятичные и шестнадцатеричные цифры и целые числа
- Зарезервированные слова языка Java
- 1.4. Управляющие последовательности. Символы Unicode. Специальные символы Управляющие последовательности
- Простые специальные символы
- Составные специальные символы
- 1.5.Идентификаторы. Переменные и типы. Примитивные и ссылочные типы
- Краткие итоги по главе 1
- Задания
- Глава 2. Объектно-ориентированное проектирование и платформа NetBeans
- 2.1.Процедурное и объектно-ориентированное программирование. Инкапсуляция
- 2.2. Работа со ссылочными переменными. Сборка мусора
- 2.3. Проекты NetBeans. Пакеты. Уровни видимости классов. Импорт классов
- 2.4. Базовые пакеты и классы Java
- 2.5. Создание в NetBeans простейшего приложения Java
- 2.6. Компиляция файлов проекта и запуск приложения
- 2.7. Структура проекта NetBeans
- 2.8. Создание в NetBeans приложения Java с графическим интерфейсом
- 2.9. Редактор экранных форм
- 2.10. Внешний вид приложения
- 2.11. Ведение проектов
- 2.11. Редактирование меню экранной формы
- 2.12. Создание нового класса
- 2.13. Документирование исходного кода в Java
- 2.14. Основные компоненты пакетов swing и awt
- 2.15. Технологии Java и .Net
- Краткие итоги по главе 2
- Задания
- Глава 3. Примитивные типы данных и операторы для работы с ними
- 3.1.Булевский (логический) тип
- 3.2.Целые типы, переменные, константы
- 3.3.Основные операторы для работы с целочисленными величинами
- 3.4.Вещественные типы и класс Math
- 3.5.Правила явного и автоматического преобразования типа при работе с числовыми величинами
- 3.6. Оболочечные классы. Упаковка (boxing) и распаковка (unboxing)
- 3.7.Приоритет операторов
- 3.8.Типы-перечисления (enum)
- Краткие итоги по главе 3
- Задания
- Глава 4. Работа с числами в языке Java
- 4.1 Двоичное представление целых чисел Позиционные и непозиционные системы счисления
- Двоичное представление положительных целых чисел
- Двоичное представление отрицательных целых чисел. Дополнительный код
- Проблемы целочисленной машинной арифметики
- Шестнадцатеричное представление целых чисел и перевод из одной системы счисления в другую
- 4.2. Побитовые маски и сдвиги
- 4.3. Двоичное представление вещественных чисел Двоичные дроби
- Мантисса и порядок числа
- Стандарт ieee 754 представления чисел в формате с плавающей точкой*
- Краткие итоги по главе 4
- Задания
- Глава 5. Управляющие конструкции Составной оператор
- Условный оператор if
- Оператор выбора switch
- Условное выражение …?... : …
- Оператор цикла for
- Оператор цикла while – цикл с предусловием
- Оператор цикла do...While – цикл с постусловием
- Операторы прерывания continue, break, return, System.Exit
- Краткие итоги по главе 5
- Задания
- Глава 6. Начальные сведения об объектном программировании
- Наследование и полиморфизм. Uml-диаграммы
- Функции. Модификаторы. Передача примитивных типов в функции
- Локальные и глобальные переменные. Модификаторы доступа и правила видимости. Ссылка this
- Передача ссылочных типов в функции. Проблема изменения ссылки внутри подпрограммы
- Наследование. Суперклассы и подклассы. Переопределение методов
- Наследование и правила видимости. Зарезервированное слово super
- Статическое и динамическое связывание методов. Полиморфизм
- Базовый класс Object
- Конструкторы. Зарезервированные слова super и this. Блоки инициализации
- Удаление неиспользуемых объектов и метод finalize. Проблема деструкторов для сложно устроенных объектов
- Перегрузка методов
- Правила совместимости ссылочных типов как основа использования полиморфного кода. Приведение и проверка типов
- Рефакторинг
- Reverse engineering – построение uml-диаграмм по разработанным классам
- Краткие итоги по главе 6
- Задания
- Глава 7. Важнейшие объектные типы Массивы
- Коллекции, списки, итераторы
- Работа со строками в Java. Строки как объекты. Классы String, StringBuffer и StringBuilder
- Работа с графикой
- Исключительные ситуации Обработка исключительных ситуаций
- Иерархия исключительных ситуаций
- Объявление типа исключительной ситуации и оператор throw
- Объявление метода, который может возбуждать исключительную ситуацию. Зарезервированное слово throws
- Работа с файлами и папками
- Краткие итоги по главе 7
- Задания
- Глава 8. Наследование: проблемы и альтернативы. Интерфейсы. Композиция Проблемы множественного наследования классов. Интерфейсы
- Отличия интерфейсов от классов. Проблемы наследования интерфейсов
- Пример на использование интерфейсов
- Композиция как альтернатива множественному наследованию
- Краткие итоги по главе 8
- Задания
- Глава 9. Дополнительные элементы объектного программирования на языке Java Потоки выполнения (threads) и синхронизация
- Преимущества и проблемы при работе с потоками выполнения
- Синхронизация по ресурсам и событиям
- Класс Thread и интерфейс Runnable. Создание и запуск потока выполнения
- Поля и методы, заданные в классе Thread
- Подключение внешних библиотек dll.“Родные” (native) методы*
- Краткие итоги по главе 9
- Задания
- Глава 10. Введение в сетевое программирование Краткая справка по языку html
- Апплеты
- Сервлеты
- Технология jsp – Java Server Pages
- Краткие итоги по главе 10
- Задания
- Глава 11. Встроенные классы Виды встроенных классов
- Вложенные (nested) классы и интерфейсы
- Внутренние (inner) классы
- Локальные (local) классы
- Анонимные (anonimous) классы и обработчики событий
- Анонимные (anonimous) классы и слушатели событий (listeners)
- Краткие итоги по главе 11
- Задания
- Глава 12. Компонентное программирование Компонентная архитектура JavaBeans
- Мастер создания компонента в NetBeans
- Пример создания компонента в NetBeans – панель с заголовком
- Добавление в компонент новых свойств
- Добавление в компонент новых событий
- Краткие итоги по главе 12
- Задания
- Литература
- Дополнительная литература
- 276 Курс подготовлен при поддержке Sun Microsystems