Смекни!
smekni.com

Общие представления о языке Java 5 (стр. 65 из 68)

e.getX()+" y="+e.getY()

);

}

}

);

В качестве параметра метода addMouseMotionListener выступает анонимный класс типа java.awt.event.MouseMotionAdapter, переопределяющий метод mouseDragged.

В интерфейсе MouseMotionListener имеется два метода:

mouseDragged(MouseEvent e);

mouseMoved(MouseEvent e)

Поскольку мы не переопределили заглушку “ mouseMoved ”, наш объект-обработчик событий типа MouseEvent (движение мыши порождает события именно такого типа) не будет ничего делать для обычного движения. А вот метод mouseMoved в нашем объекте-обработчике переопределён, поэтому при перетаскиваниях (когда идёт движение мыши с нажатой кнопкой) будет выводиться текст в консольное окно.

Допустим, мы поместили код с добавлением слушателя в обработчик события нажатия на какую-либо кнопку (например, jButton1). После срабатывания обработчика наш компонент (главная форма приложения, если мы добавили слушателя ей), станет обрабатывать события типа MouseMotion. При этом на каждое такое событие в консольное окно будет осуществляться вывод позиции мыши, но только в том случае, если идёт перетаскивание – когда в пределах формы мы нажали кнопку мыши и не отпуская её перетаскиваем. Причём неважно, какая это кнопка (их можно при необходимости программно различить).

Если мы расположим на форме панель jPanel1, и заменим вызов addMouseMotionListener (реально это вызов this.addMouseMotionListener) на jPanel1.addMouseMotionListener – слушатель расположится не в форме (объект this), а в панели. В этом случае события перетаскивания будут перехватываться только панелью. При этом важно, в какой области началось перетаскивание, но не важно, в какой области оно продолжается – события от перетаскивания, начавшегося внутри панели, будут возникать даже при перемещении курсора мыши за пределы окна приложения.

Если нажать на кнопку добавления слушателя два раза – в списке слушателей станет два объекта-обработчика событий MouseEvent. Объекты из списка слушателей обрабатывают события по очереди, в порядке их добавления. Поэтому каждое событие будет обрабатываться дважды. Если добавить ещё объекты слушателей - будет обрабатываться соответствующее число раз. Конечно, в реальных ситуациях если добавляют более одного объекта-слушателя для события, они не повторяют одни и те же действия, а по-разному реагируют на это событие. Либо они являются экземплярами одного класса, но с разными значениями полей данных, либо, что чаще – экземплярами разных классов. Например, для события MouseEvent существует интерфейc MouseListener и реализующий его адаптер MouseAdapter, имеющий четыре метода:

mouseClicked(MouseEvent e)

mouseEntered(MouseEvent e)

mouseExited(MouseEvent e)

mouseReleased(MouseEvent e)

Экземпляры классов-наследников MouseAdapter будут совсем по-другому обрабатывать события MouseEvent. Аналогично, можно создать экземпляр наследника MouseMotionListener, который будет реагировать не на перетаскивание, а на простое движение мыши.

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

Краткие итоги по главе 11

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

  • Вложенные (nested) классы и интерфейсы – используются для задания совершенно самостоятельных классов и интерфейсов внутри классов. Должны при задании иметь модификатор static. Имя класса верхнего уровня используется в качестве квалификатора в пространстве имён, во всём остальном они ведут себя как обычные классы.
  • Внутренние (inner) классы – служат для создания экземпляров, принадлежащих экземплярам класса верхнего уровня. То есть их экземпляры не могут существовать вне объектов верхнего уровня. Не допускается создания методов класса или переменных внутреннего класса. Внутренний класс задаётся так же, как вложенный, но только без модификатора static перед именем этого класса. Использование внутренних классов позволяет реализовать в Java большинство возможностей модулей из процедурных языков программирования – в этом случае в качестве модуля выступает внешний класс.
  • Локальные (local) классы – задаются внутри блоков программного кода в методах или блоках инициализации. Они носят вспомогательный характер, и область видимости и жизни экземпляров этих классов ограничивается соответствующим блоком программного кода. Как и в случае внутренних классов, это позволяет реализовать в Java возможности модулей из процедурных языков программирования. И в этом случае в качестве модуля также выступает внешний класс.
  • Анонимные (anonimous) классы – совмещают декларацию, реализацию и вызов. Не имеют ни имени, ни конструктора. Их обычно используют в обработчиках событий.

- Анонимный класс объявляется без задания имени класса и переменных данного безымянного типа – задаётся только конструктор класса вместе с его реализацией. У анонимного класса может быть только один экземпляр, причём он создаётся сразу при объявлении класса. Поэтому перед объявлением анонимного класса следует ставить оператор new. Безымянный класс должен быть наследником какого-либо класса или интерфейса, и соответствующий тип должен быть указан перед списком параметров конструктора.

- Синтаксис задания безымянного класса таков:

new ИмяПрародителя(список параметров конструктора) {

тело конструктора

}

- Программные события в Java – объекты, имеющие тип, зависящий от того, какое физическое событие наступило. Обработчики событий – подпрограммы, которые выполняют некоторый код при наступлении программного события.

- В Java обработчики событий являются объектами – экземплярами специальных классов Listeners (“слушателей”). В этих классах заданы методы, реагирующие на соответствующий тип событий. Объекты обработчиков можно добавлять к компонентам, способным перехватывать соответствующие типы событий.

- Классы и интерфейсы для работы с событиями заданы в пакетах java.awt, java.awt.event и javax.swing.event.

- Классы, отвечающие за прослушивание событий, реализуют соответствующие интерфейсы - наследники интерфейса java.util.EventListener. Для того, чтобы упростить реализацию интерфейсов, в Java для многих интерфейсов событий существуют так называемые адаптеры (adapters) – классы, в которых все необходимые методы интерфейсов слушателей уже реализованы в виде ничего не делающих заглушек. Так что в наследнике адаптера требуется только переопределение необходимых методов, не заботясь о реализации всех остальных. Обычно эти классы делают анонимными, совмещая декларацию, реализацию и вызов.

Задания

  • Написать приложение, иллюстрирующее работу вложенных, внутренних и локальных классов.
  • Написать приложение, иллюстрирующее работу анонимных классов в обработчиках событий.

Глава 12. Компонентное программирование

Компонентная архитектура JavaBeans

Компонент – это:

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

· подключение к этим программам осуществляется с помощью интерфейсов;

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

Технология JavaBeans предоставляет возможность написания компонентного программного обеспечения на языке Java. Beans по-английски означает “зёрна” – обыгрывается происхождение названия “Java” от любимого создателями языка Java сорта кофе. Компоненты JavaBeans в литературе по языку Java часто упоминаются просто как Beans.

Компонент JavaBeans может быть включен в состав более сложных (составных) компонентов, приложений, сервлетов, пакетов, модулей. Причём обычно это делается с помощью сред визуального проектирования.

Компоненты JavaBeans предоставляют свои общедоступные методы и события для режима визуального проектирования. Доступ к ним возможен в том случае, когда их названия соответствуют особым шаблонам проектирования (bean design patterns). Для задания свойства требуется, чтобы существовали геттер и сеттер для этого свойства. Пример будет приведён в следующем параграфе.

Компонент может быть установлен в среду разработки, в этом случае кнопки доступа к компонентам выносятся на палитру (palette) или панель инструментов (toolbox). Вы можете создать экземпляр компонента на проектируемой экранной форме в режиме Design (“дизайн”) путём выбора его кнопки на панели и перетаскивания на форму. Затем можно изменять его свойства , писать обработчики событий, включать в состав других компонентов и т. д.

Компонент JavaBeans является классом Java и имеет три типа атрибутов:

  • Методы компонента JavaBeans не отличаются от других методов объектов в Java. Они описывают поведение компонента. Общедоступные методы компонента могут вызываться из других компонентов или из обработчиков событий.
  • Свойства (Properties) компонента JavaBeans характеризуют его внешний вид и поведение и могут быть изменены в процессе визуального проектирования. Это можно сделать с помощью редактора свойств (Property Editor), а некоторые из свойств – вручную (положение компонента, его размер, текст). Свойство задаётся комбинацией геттера и сеттера (метода по чтению и метода по записи).
  • События (Events) используются для связи между компонентами. При помещении компонента на экранную форму среда разработки исследует компоненты и определяет, какие программные события данный компонент может порождать (рассылать) и какие - получать (обрабатывать).

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

В NetBeans существует несколько способов создания компонента JavaBeans.