Файл: 14. Компонентная разработка приложений. Введение в компонентные модели.pdf
ВУЗ: Университет управления «ТИСБИ»
Категория: Учебное пособие
Дисциплина: Объектно-ориентированное программирование
Добавлен: 20.10.2018
Просмотров: 1304
Скачиваний: 9
Этот тип используется для обработки так называемых уведомляющих
событий, обычно возникающих при выборе управляющих кнопок формы,
пунктов меню и т.д. Более сложные процедурные типы предусмотрены для
обработки событий от мыши и клавиатуры:
TKeyEvent = procedure (Sender : TObject; var Key : word;
Shift : TShiftState) of object;
TMouseEvent = procedure (Sender : TObject; Button : TMouseButton;
Shift : TShiftState; x,y : integer) of object;
Как правило, стандартных процедурных типов и событий вполне хватает
для решения большинства задач. При необходимости легко можно ввести и
нестандартные события. Для этого надо:
объявить новый процедурный тип:
TNewEventProc = procedure (параметры) of object;
ввести новый класс с объявлением в нем свойств-событий с
использованием упрощенной схемы описания свойств (без объявления
методов доступа):
TNewClass = class (КлассРодитель)
private FOnNewEvent : TNewEventProc; // поле процедурного типа
published property OnNewEvent : TNewEventProc
read FOnNewEvent write FOnNewEvent;
объявить и реализовать обработчик события OnNewEvent в полном
соответствии с процедурным типом TNewEventProc
procedure NewEventHandler ( параметры как у типа TNewEventProc )
ввести переменную-объект класса TNewClass (например – NewObj) и
присвоить свойству-событию имя метода-обработчика этого события
(например – имя NewEventHandler)
NewObj. OnNewEvent := NewEventHandler;
Еще один важный момент в реализации компонентной модели связан с
ее поддержкой в рамках стандартной библиотеки классов. Для использования
компонентов как строительных блоков при создании приложений, в
библиотеке VCL предусмотрено большое число классов. Несколько из них,
расположенных на верхних уровнях иерархии, обеспечивают наиболее общие
свойства всех компонентов. К этим классам прежде всего относятся классы
TPersistent и TComponent.
Класс TPersistent является непосредственным потомком базового класса
TObject. Важность данного класса определяется тем, что он вводит механизм
потоковости или сериализуемости (serializable), т.е. все его потомки (в том
числе абсолютно любые компоненты) могут сохранять свои свойства во
внешних файлах-потоках и восстанавливать свойства из файлов. Для этого
в классе вводится метод Assign, с помощью которого поля одного объекта
могут быть присвоены полям другого объекта.
Класс TComponent, как следует из его имени, является базовым классом
для всех компонентов. Он происходит непосредственно от класса TPersistent
и вводит несколько наиболее общих свойств и методов, наследуемых всеми
компонентами. Наиболее важными из них являются те, что отвечают за
поддержку механизма владения: каждый компонент имеет своего владельца
и сам может владеть другими компонентами. Механизм владения очень
важен для создания и уничтожения объектов-компонентов с точки зрения
выделения и освобождении динамической памяти. Например, форма как
визуальная единица приложения владеет всеми размещенными на ней
компонентами, т.е. является специализированным контейнером. При
закрытии формы это позволяет легко и корректно освободить память,
выделенную для всех компонентов формы.
Механизм владения поддерживается в классе TComponent с помощью
трех основных свойств:
свойство Components представляет собой массив указателей на
подчиненные компоненты;
свойство ComponentCount определяет текущее число подчиненных
компонентов;
свойство Owner содержит указатель на хозяина компонента.
Методы класса TComponent обеспечивают стандартные операции
добавления, удаления и поиска в контейнере.
Использование компонентов при визуальном создании приложений
заключается в следующем. Каждый компонент регистрируется в Delphi и
становится доступным для выбора в палитре компонентов. Этот выбор с
помещением значка компонента на форму приводит к созданию
соответствующего объекта, после чего в Инспекторе Объектов становятся
доступными для редактирования все опубликованные свойства компонента,
включая список обработчиков событий.
Всех потомков класса TComponent можно разделить на две группы –
визуальные и невизуальные компоненты. Визуальные компоненты имеют
видимое графическое представление на форме как в процессе разработки
приложения, так и при его выполнении. Базовым классом визуальных
компонентов является потомок класса TComponent – класс TControl. В нем
вводятся такие общие свойства, как положение компонента, его текущее
состояние и стиль, а также определяются все основные обработчики
событий. Основными невизуальными компонентами являются компоненты
доступа к базам данных, компоненты-диалоги, компонент-таймер и другие.
Далее кратко рассмотрим компонентную модель языка Java.
Компоненты многократного использования объединены в языке Java общим
названием Beans. Идеологически технология Beans близка компонентной
технологии Borland Delphi. Пожалуй, наибольшее отличие этих технологий
касается механизма обработки событий.
Для описания компонентных классов разработаны простые правила, с
помощью которых определяются свойства (в том числе и видимые
разработчиком приложения), методы и выполняется обработка событий. Что
касается свойств, то общее правило их объявления и использования
аналогично свойствам компонентной модели Delphi: свойство – это
внутреннее закрытое поле, доступ к которому реализуется только через
обращение к соответствующим методам доступа. При этом методы доступа
обязательно именуются с помощью префиксов set и get, за которыми идет
имя свойства: setName(параметр) и getName( ). Как обычно, set-метод
принимает один входной параметр типа внутреннего поля, а get-метод
возвращает значение поля. Фрагмент описания компонентного класса:
class MyBeansClass
{ private int Field1; // закрытые поля
private String Field2;
public int getField1( ) {return Field1;} // методы доступа
public void setField1(int aField1) { Field1 = aField1;}
public String getField2( ) {return Field2;} // методы доступа
public void setField2(String aField2) { Field2 = aField2;};
public void SomeMethod(параметры) { реализация }; // просто метод
};
Отдельно надо хотя бы кратко остановиться на механизме обработки
событий. Поскольку язык Java не поддерживает указатели на функции,
разработчикам языка пришлось использовать другие подходы. Как и все
остальное в языке Java, обработка событий выполняется на объектном
уровне с помощью специальных классов, в том числе и интерфейсных (это
еще раз подтверждает значение интерфейсов для технологии Java!).
Любое событие генерируется объектом-источником при изменении его
внутреннего состояния. Все основные события классифицированы и им
поставлены в соответствие некоторые классы. Родоначальником иерархии
событий является класс EventObject, от которого порождены следующие
основные классы событий:
ActionEvent – обработка нажатий кнопок или выбор пунктов меню.
ComponentEvent – общие события при манипуляциях с компонентом.
ContainerEvent – события при добавлении/удалении компонента из
контейнера.
KeyEvent – события ввода с клавиатуры.
MouseEvent – «мышиные» события.
WindowEvent – оконные события.
ItemEvent – выбор элементов в списках.
TextEvent – любые изменения в текстовых полях.
Обработку того или иного события выполняет специальный объект-
слушатель (listener). Этот объект является экземпляром класса,
реализующего некоторый интерфейс, характерный для данного типа
события. Для каждого класса событий существует свой интерфейс
слушателя, определяющий один или несколько специфических методов
обработки данного события. В качестве примера приведем несколько
наиболее важных интерфейсов слушателя и определяемых ими методов:
KeyListener: keyPressed, keyReleased, keyTyped
MouseListener: mouseClicked, mouseEntered, mouseExited,
mousePressed, mouseReleased
MouseMotionListener: mouseMoved, mouseDragged
ItemListener: itemStateChanged
WindowListener: windowOpened, windowClosing, windowActivated
ActionListener: actionPerformed
Для
обработки
события
надо
создать
объект-слушатель
и
зарегистрировать его в компоненте, который генерирует данное событие.
Для регистрации слушателей используются специальные методы
add***Listener() и remove***Listener(), где звездочки *** заменяют тип
события. Например: addActionListener, addKeyListener, addMouseListener,
addItemListener и т.д. Компонент может зарегистрировать несколько
слушателей-обработчиков разных событий. Например, если ранее описанный
класс MyBeansClass должен обрабатывать события от мыши и клавиатуры,
он должен зарегистрировать соответствующих слушателей, для чего в
описание класса надо добавить следующие методы: