
- •9. Библиотека .Net Framework и библиотеки языка Java
- •9.1. Приложение
- •9.2. Классы, объекты и элементы приложения
- •9.3. Простейшие приложения
- •9.4. Сообщения Windows, события и делегаты
- •9.4.1. Обработка событий мыши на языке c#
- •9.4.3. Обработка событий мыши на языке Java с использованием предопределённого обработчика mouseDown
- •9.4.4. Связь события с несколькими объектами на языке c#
- •Ещё раз о событиях и уведомлении в языке Java
- •9.5.1. Обработка событий элементов интерфейса пользователя в языке Java
- •Обработка событий мыши на языке Java, используя интерфейс MouseListener
- •9.5.3. Обработка событий мыши на языке Java, используя классы адаптеров
- •9.5.4. Обработка событий мыши на языке Java, используя внутренние классы адаптеров и анонимные классы
- •9.5.5. Обработка события закрытия окна
- •Графика
- •9.6.1. Графические объекты
- •Прямоугольник
- •Класс Pen
- •Класс SolidBrush
- •Класс Font
- •Класс Graphics
- •9.7. Событие Paint и его обработчик
- •9.8. Управляющие элементы
- •Класс Button
- •Классы TextBox и TextField
- •Классы UserControl и Panel
- •9.9. Дочерние окна
- •9.10. Исключения
9.4. Сообщения Windows, события и делегаты
Важно понять, что Windows - операционная система с управляемой сообщениями архитектурой. Windows находится в постоянном ожидании того, когда же пользователь подведёт указатель мыши к элементу в прикладном окне приложения и нажмёт на левую клавишу мыши или передвинет ползунок, или нажмёт клавишу клавиатуры и т. д. Windows тотчас генерирует соответствующее сообщение и помещает его в системную очередь сообщений приложения. Каждое сообщение имеет свой идентификатор и с ним может быть связана какая-либо информация (например, координаты указателя мыши в прикладном окне). Имеется более сотни стандартных сообщений Windows.
Для каждого стандартного сообщения (события) есть обработчик сообщения (события) по умолчанию – специальная функция, которая обычно ничего не делает. Но мы можем реализовать свою обработку сообщения, переопределив требуемую функцию–обработчика для этого сообщения.
C# и C++/CLI. Сообщения выполняются в рамках окон, то есть форм, и для связи функций-обработчиков с сообщениями используется механизм событий и делегатов. Посредством делегатов к событиям привязывают требуемые функции-обработчики определённого формата.
Каждая форма или управляющий элемент (который также является формой, но специализированной) имеет фиксированный набор предопределённых событий с предопределёнными делегатами, которые определяют формат функций-обработчиков этих событий.
При желании для простоты можно воспользоваться предопределёнными обработчиками событий. В этом случае не требуется их подписка на события.
Java и J#. Обработка событий основана на делегировании обработчиков с помощью интерфейсов. Вместо делегатов используются предопределённые интерфейсы и включённые в них обработчики.
Итак, реализация обработки событий в языках C# и Java отличаются; она рассмотрена в разделах 9.4.1 и 9.4.2 на примере обработки события от мыши.
9.4.1. Обработка событий мыши на языке c#
Для события MouseDown, возникающего при нажатии на клавишу мыши, используют делегат MouseEventHandler.
Событие определено в классе System.Windows.Forms.Control, из которого порождён класс Form, следующим образом:
public event MouseEventHandler MouseDown;
С событием MouseDown. можно с помощью оператора “+=” связать один или несколько объектов делегата MouseEventHandler события с инкапсулированными в них обработчиками, допустим, обработчик OurMouseDown():
MouseDown += new MouseEventHandler (OurMouseDown);
Разумеется, формат обработчика определяется делегатом MouseEventHandler и должен быть следующим:
void OurMouseDown (object sender, MouseEventArgs args);
где
sender - ссылка на объект-источник события,
args - ссылка на объект типа MouseEventArgs, содержащий данные, относящиеся к свершившемуся событию.
Обработчик OurMouseDown() получает аргумент типа MouseEventArgs, содержащий данные, относящиеся к обрабатываемому событию и представленные следующими свойствами класса MouseEventArgs, специфичными для события MouseDown:
Button, указывающее, какая клавиша нажата;
Clicks, указывающее, сколько раз была нажата и отпущена клавиша;
Delta, указывающее, сколько раз было повёрнуто колёсико мыши;
X, указывающее значение координаты х носика мыши и
Y, указывающее значение координаты у носика мыши.
Пример 9.4.1 содержит C# программу с событием, происходящим при нажатии на клавишу мыши. При каждом нажатии на клавишу появляется строка на консоли.
Пример 9.4.1. Программа обработки события мыши на C#.
Приложение создаёт прикладное окно и ожидает нажатия клавиши мыши в этом окне (точнее, в области клиента окна). При нажатии на клавишу в консольное окно выдаётся строка с координатами носика курсора мыши.
Рис. 9.4.1. При нажатии на клавишу мыши появилась очередная строка на консоли
Ниже приводятся три варианта реализации этого приложения на языке C#.
///////////////
// C# Вариант 1
using System;
using System.Drawing;
using System.Windows.Forms;
class MainClass : Form // Класс прикладного окна
{
// Использовать предопределённый обработчик OnMouseDown мыши
protected override void OnMouseDown (MouseEventArgs e)
{
Console.WriteLine ("Mouse: x= " + e.X + " y= " + e.Y);
}
static void Main ( ) // Главная функция
{
MainClass mC= new MainClass ( ); // Создать прикладное окно
mC.Size= new Size (400, 200);
mC.Text= "Hello";
Application.Run (mC); // Выполнить приложение
}
}
/*
Result:
При каждом нажатии на клавишу мыши в прикладном окне выдаётся на консоль строка вида
Mouse: x= 10 y= 55, где x, y - координаты носика мыши
*/
///////////////
// C# Вариант 2
using System;
using System.Windows.Forms;
public class MainClass: Form // Класс прикладного окна
{
// Использовать наш обработчик OurMouseDown мыши
private void OurMouseDown (object sender, MouseEventArgs e)
{
Console.WriteLine ("Mouse: x= " + e.X + " y= " + e.Y);
}
static void Main ( ) // Главная функция
{
MainClass mC= new MainClass ( ); // Создать прикладное окно
// Подписать наш обработчик на событие MouseDown
mC.MouseDown += new MouseEventHandler
(mC.OurMouseDown);
Application.Run (mC); // Выполнить приложение
}
}
///////////////
// C# Вариант 3
using System;
using System.Windows.Forms;
public class MainClass : Form // Класс прикладного окна
{
public MainClass ( ) // Конструктор
{
// Подписать наш обработчик на событие MouseDown
MouseDown += new MouseEventHandler (OurMouseDown);
}
// Использовать наш обработчик OurMouseDown мыши
private void OurMouseDown (object sender, MouseEventArgs e)
{
Console.WriteLine ("Mouse: x= " + e.X + " y= " + e.Y);
}
static void Main ( ) // Главная функция
{
Application.Run (new MainClass ( )); // Выполнить приложение
}
}
C#. В C#-программах примера 9.4.1 рассмотрены три варианта применения обработчиков мыши.
Предопределённый обработчик protected override void OnMouseDown (MouseEventArgs e) уже описан в базовом классе Form и в первом варианте нашей программы он переопределяется для выдачи координат носика мыши на консоль.
Во втором и третьем вариантах программы используется наш обработчик OurMouseDown, формат которого соответствует делегату MouseEventHandler события мыши. Во втором варианте программы подписка обработчика на объект событие MouseDown мыши осуществляется в теле функции Main(), а в третьем варианте – в теле конструктора MainClass() прикладного окна.
Достоинством второго и третьего вариантов является то, что на одно событие можно подписать много обработчиков различных объектов. В нашем случае подписывается один обработчик объекта, являющегося самим окном, поэтому вариант первый предпочтителен.
В первом варианте приложения задаётся размер и заголовок прикладного окна. В двух других вариантах размеры окна берутся по умолчанию, поэтому в них отсутствует using System.Drawing, поскольку отпала необходимость в использовании класса Size из этого пространства имен.
.
9.4.2. Обработка событий мыши на языке C++/CLI
Пример 9.4.2 иллюстрирует один из вариантов обработки события мыши на языке C++/CLI.
Пример 9.4.2. Программа обработки события мыши на C++/CLI.
///////////////
// C++/CLI
#include "stdafx.h"
#using<System.dll>
#using<System.Windows.Forms.dll>
#using<System.Drawing.dll>
using namespace System;
using namespace System::Windows::Forms;
using namespace System::Drawing;
ref class Form1 : public Form
{
public:
Form1 (void)
{
this->Size = Drawing::Size (300,300);
this->Text = "Form1";
this->MouseDown += gcnew MouseEventHandler (this,
&Form1::OurMouseDown);
}
protected:
void OurMouseDown (Object^ sender, MouseEventArgs ^e)
{
Console::WriteLine ("Mouse: x= " + e->X + " y= " + e->Y);
}
};
void main ( )
{
System::Windows::Forms::Application::Run (gcnew Form1());
}
С++/CLI. Программа на языке C++/CLI примера 9.4.2 соответствует третьей версии обработки события мыши на языке C# примера 9.4.1. Подписка нашего обработчика OurMouseDown() мыши на событие MouseDown осуществляется в конструкторе управляемого класса Form1 окна. В программе, оперирующей с управляемыми классами, активно применяются дескрипторы и стрелки. Обратим внимание, – в соответствии с грамматикой языка C++/CLI конструктор делегата MouseEventHandler включает два аргумента, указывающих на объект (this), в котором находится обработчик, и сам обработчик OurMouseDown.
Правила использования делегатов, событий и классов библиотеки .NET Framework на языках C++/CLI и C# схожи и делают похожим программирование на этих языках, поэтому в дальнейшем языку C++/CLI будет уделяться меньшее внимание, чем языкам Java и C#. При программировании на Java и C# мы намеренно применим разные библиотеки, что облегчит в дальнейшем читателю освоение существенно различающихся Java и .NET технологий программирования.