Class Listener extends MouseAdapter
{
// Выполнить предопределённый обработчик mousePressed мыши
Public void mousePressed (MouseEvent mE)
{
System.out.println ("Mouse: x= " + mE.getX ( )
+ " y= " + mE.getY( ));
}
}
public static void main ( ) // Главная функция
{
MainClass mC= new MainClass ( );
mC.show ( );
}
}
/*
Result:
При каждом нажатии на клавишу мыши в прикладном окне выдаётся на консоль строка вида
Mouse: x= 10 y= 55, где x, y - координаты носика мыши
*/
В программах языка Java для обработки событий широко применяется анонимный класс, который не имеет имени, поскольку объект этого класса используется в конкретном контексте один раз, то есть, нет необходимости объявлять для него ссылку, так как этот объект более нигде не применяется.
В программе примера 9.5.4.2 в качестве аргумента используется не ссылка на объект класса приёмника как в примере 9.5.4.1, а описан особым образом анонимный класс. Конструкция параметра функции addMouseListener() вида
new MouseAdapter ( )
{. . .}
указывает компилятору о том, что имеет место анонимный класс. Компилятор создаёт объект анонимного класса MouseAdapter и передаёт его в качестве аргумента в функцию addMouseListener(). Как видим в примере 9.5.4.2, анонимные классы упрощают программу.
Пример 9.5.4.2. Обработка событий мыши на Java, используя внутренний анонимный класс.
///////////////
// Javaи J# Вариант 8
import java.awt.*;
import java.awt.event.*;
// Класс прикладного окна
class MainClass extends Frame
{
public MainClass ( )
{
this.setSize (400, 200);
this.setTitle ("Hello");
// Примененить внутренний анонимный класс
this.addMouseListener (new MouseAdapter ( )
{
public void mousePressed (MouseEvent mE)
{
System.out.println ("Mouse: x= " + mE.getX ( )
+ " y= " + mE.getY( ));
}
});
}
public static void main ( ) // Главная функция
{
MainClass mC= new MainClass ( );
mC.show ( );
}
}
/*
Result:
При каждом нажатии на клавишу мыши в прикладном окне выдаётся на консоль строка вида
Mouse: x= 10 y= 55, где x, y - координаты носика мыши
*/
Обработка события закрытия окна
Применим класс WindowAdapter адаптера для обработки события закрытия окна. Дело в том, что иногда не удаётся закрыть окно, нажав на кнопку закрытия окна. Это возникает в тех случаях, когда событие закрытия окна не обрабатывается. Два варианта программы, приведённые в примере 9.5.5.1, используют наш класс OurWindowAdapter адаптера окна, наследующий класс WindowAdapter адаптера, и анонимный класс.
Пример 9.5.5.1. Обработка события закрытия окна.
///////////////
// Javaи J# Вариант 9
import java.awt.*;
import java.awt.event.*;
// Класс прикладного окна
class MainClass extends Frame
{
public MainClass ( )
{
this.setSize (400, 200);
this.setTitle ("Hello");
// Примененить внутренний анонимный класс
this.addMouseListener (new MouseAdapter ( )
{
public void mousePressed (MouseEvent mE)
{
System.out.println ("Mouse: x= " + mE.getX ( )
+ " y= " + mE.getY ( ));
}
});
this.addWindowListener (new OurWindowAdapter ());
}
public static void main ( ) // Главная функция
{
MainClass mC= new MainClass ( );
mC.show ( );
}
}
// Класс адаптера окна
Class OurWindowAdapter extends WindowAdapter
{
Public void windowClosing (WindowEvent wE)
{
System.exit (0);
}
}
///////////////
// Javaи J# Вариант 10
import java.awt.*;
import java.awt.event.*;
// Класс прикладного окна
class MainClass extends Frame
{
public MainClass ( )
{
this.setSize (400, 200);
this.setTitle ("Hello");
// Примененить внутренний анонимный класс
this.addMouseListener (new MouseAdapter ( )
{
Public void mousePressed (MouseEvent mE)
{
System.out.println ("Mouse: x= " + mE.getX ( )
+ " y= " + mE.getY( ));
}
});
// Примененить внутренний анонимный класс
this.addWindowListener (new WindowAdapter ( )
{
Public void windowClosing (WindowEvent wE)
{
System.exit(0);
}
});
}
public static void main ( ) // Главная функция
{
MainClass mC= new MainClass ( );
mC.show ( );
}
}
/*
Result:
При каждом нажатии на клавишу мыши в прикладном окне выдаётся на консоль строка вида
Mouse: x= 10 y= 55, где x, y - координаты носика мыши
При нажатии кнопки закрытия окна прикладное окно исчезает
*/
Для закрытия окна в варианте 9 программы примера 9.5.5.1 создан свой класс OurWindowAdapter адаптера, наследующий класс WindowAdapter
адаптера окна. Объект класса OurWindowAdapter передан функции addWindowListener() для подписки на событие окна. Вариант 10 программы применяет анонимные класс WindowAdapter адаптера окна и класс MouseAdapterадаптера мыши.
Графика
Рассмотрим классы .NET Framework, обеспечивающие рисование и вывод рисунков в область клиента окон (форм) и соответствующие им классы библиотеки языка Java. Множество этих классов представляют графический интерфейс устройства GDI++ (Graphic Device Interface).
Графические объекты
Графический интерфейс использует для рисования такие объекты как цвет (color), перья (pens), кисти (brushes), изображения (images) и шрифты (fonts).
Прежде чем рисовать фигуру или линию, надо создать графический объект класса Graphics. Графический объект связан с конкретным окном (формой, фреймом) и его функции выполняют рисование в этом окне, включая при необходимости в качестве аргументов перья, кисти, шрифты и т.д. Таким образом, вспомогательные объекты типа Color, Pen, SolidBrush, Image и Font обеспечивают функционирование объектов класса Graphics, занимающих центральное место в создании графического интерфейса. Объекты вспомогательных типов хранят необходимую для рисования информацию, а графический объект её использует.
При рисовании необходимо связать графический объект с контекстом устройства, на которое отображается информация. Обычно им является дисплей или принтер. Может выводиться не только текстовая информация, но и геометрические фигуры, залитые цветом, и изображения. Объект типа Graphics, например, на языках C# и C++/CLI связывается с устройством с помощью функции CreateGraphics(), а в языке Java(J#) – getGraphics().
.
Точка
C# и C++/CLI. Наиболее часто употребляемый тип – это тип Point, используемый для создания объекта – одиночной точки, обычно в области клиента окна.
Тип Point содержит открытые свойства – X и Y , определяющие координаты точки, конструктор, функцию Offset(dx, dy) смещения точки с приращениями dx и dy, операторы, позволяющие сравнивать объекты-точки и присваивать им значения.
Тип Point имеет конструктор следующего формата:
Point (int X, int Y);
Нижеследующие примеры понятны без пояснений:
C++/CLI.
Point *pP1= new Point (1, 2); // Создать в неуправляемой куче
// точку с pP1->X= 1 и pP1->Y= 2
pP1 -> Offset (1, 1); // Сдвинуть точку pP1
// pP1->X= 2 и pP1->Y= 3
Point p2 (3, 4); // Создать точку p2 в стеке
// с p2.X= 3 и p2.Y= 4
p2.Offset (5, 5); // Сдвинуть точку p2
// p2.X= 8 и p2.Y= 9
if (p2 != *pP1) p2= *pP1; // Неравные точки стали одинаковыми
Point ^pP3= gcnew Point (10, 20); // Создать точку в управляемой куче
// с pP3->X= 10 и pP3->Y= 20
if (p2 != *pP3) p2= *pP3; // Неравные точки стали одинаковыми
C#.
Point p1= new Point (1, 2); // Создать точку p1 с p1.X= 1 и p1.Y= 2
p1.Offset (1, 10); // p1.X= 2 и p1.Y= 12
Point p2= new Point ( ); // Создать точку p2 с p2.X= 0 и p2.Y= 0
p2.X= 30; p2.Y=50;
Java. Точки являются объектами класса Point. Конструктор класса Point имеет формат:
Point (int X, int Y);
Класс Point включает свойства x и y.
Point p= new Point (10, 20 ); // Создать точку p2 с p2.X= 10 и p2.Y= 20
p.x= 30; p.y=50;
Прямоугольник
C# и C++/CLI. Также часто употребляется тип Rectangle, используемый для создания объекта-прямоугольника с горизонтальными и вертикальными сторонами. Этот прямоугольник можно применять для рисования его пером (pen) или как область, подлежащую заливке некоторым цветом с помощью кисти (brush), или для указания области, занимаемой окном, и так далее.
Тип Rectangle содержит одиннадцать свойств и много функций. Свойство Location, включающее координаты левого верхнего угла (X и Y или Left и Top), определяет положение прямоугольника в окне или на экране, свойства Width и Height задают ширину и высоту прямоугольника, а свойства Right и Bottom - координаты правой нижней точки прямоугольника
Из множества функций нам понадобятся следующие: конструктор Rectangle , функция Offset() смещения, и функция Contains() выявления вхождения точки в прямоугольник. Они понятны из нижеследующих примеров:
C++/CLI.
Rectangle r1; // Создать прямоугольник в стеке
r1.X= 1; r1.Y=2; r1.Width= 10; r1.Height= 20;
Rectangle *r2= new Rectangle (21, 22, 210, 220); // Создать прямоугольник
// в неуправляемой куче
r2->Offset (100, 100);
Point ^p= gcnew Point (3, 4); // Создать точку p2 с p2.X= 3 и p2.Y= 4
if (r1.Contains (*p)) r1=*r2; // Если р2 в r1, то прямоугольник г1
// становится равным прямоугольнику г2
// r1.X= 121 r1.Y= 122 r1.Width= 210 r1.Height= 220;
C#.
Rectangle r1= new Rectangle (1, 2, 4, 5); // r1.X= 1, r1.Y= 2,
// r1.Left= 1, r1.Top= 2, r1.Right= 5, r1.Bottom= 7, r1. Width = 4, r1. Height = 5
r1.Offset (2, 1); // Теперь r1.X= 3, r1.Y= 3,
// r1.Left= 3, r1.Top= 3, r1.Right= 6, r1.Bottom= 8, r1. Width = 4, r1. Height = 5
Point p2= new Point (3, 4); // Создать точку p2 с p2.X= 3 и p2.Y= 4 [JScript] public function Point(int, int);
if (r1.Contains (p2)) { что-либо делаем}; // Если р2 в r1, то что-либо делаем
Java. Прямоугольники представляются объектами класса Rectangle. Конструктор класса Rectangle имеет различные форматы:
Rectangle ();
Rectangle (int x, int y, int w, int h );
Rectangle (Point p, Dimension d );
где х, у – координаты верхнего левого угла прямоугольника;
w, h – ширина и высота прямоугольника;
d – ссылка на объект класса Dimension, задающий размеры прямоугольника.
Среди свойств класса Rectangle выделим свойства x и y, определяющие координаты левого верхнего угла прямоугольника, свойства width и height, определяющие ширину и высоту прямоугольника.
Цвет
C# и C++/CLI.Типом Color представляется цвет. Среди конструкторов структуры Color имеется конструктор
Color (int tr, int r, int g, int b);
который создаёт объект с указанной прозрачностью tr (transparency of a color) и основными составляющими цвета: красный r (red), зелёный g (green) и синий b (blue). Значения прозрачности и составляющих цвета лежат в границах от 0 до 255. Большее их значение означает более плотный цвет и меньшую прозрачность.
Структура Color имеет огромный набор предопределённых цветов, представленных свойствами, например: Brown, Chocolate, Gold, Gray и т.д. Имеется статическая функция FromArgb(), позволяющая получить цвет по значениям трёх составляющих цвета и его интенсивности:
static Color FromArgb (int tr, int r, int g, int b);
Она создаёт структуру Color из компонентов ARGB цвета: прозрачности tr и основных цветов – красного r, зелёного g и синего b.
А другая перегруженная статическая функция
static Color FromArgb (int r, int g, int b);
создаёт структуру Color из компонентов ARGB цвета: прозрачности tr= 255 (непрозрачный цвет) и основных цветов – красного r, зелёного g и синего b. Примеры:
C++/CLI.
Color col (System::Drawing::Color::Gold); // Золотой цвет
Color col1 (Color::Gold); // Золотой цвет
Color col2 (Color::FromArgb (0, 0, 255)); // Синий непрозрачный цвет
Color col3;
col3= Color::FromArgb (0, 0, 255); // Синий цвет
Color col4;
col4= Color::Gold; // Золотой цвет
Color col5 (Color::FromArgb (100, 0, 0, 250)); // Синий полупрозрачный цвет
C#.
Color col3;
col3= Color.FromArgb (0, 0, 255); // Синий цвет
Color col4;
col4= Color.Gold; // Золотой цвет
Color col5= Color.Silver; // Серебренный цвет
Java. Цвет является объектом класса Color. Конструктор класса Color имеет формат:
Color (int r, int g, int b);
Color c= new Color (0, 200, 0); // c – синий цвет
Color c1=c; // c1 – тоже синий цвет
Color c2= new Color (0, 0, 255); // c2 – зелёный цвет
c2= с1; // c2 – теперь синий цвет
c1= Color.yellow; // c1- теперь жёлтый цвет
Класс Pen
C# и C++/CLI.Управляемый класс Pen используется для создания объектов-перьев (pens), определяющих стиль, толщину и цвет линий для рисования линий и кривых.
Конструкторы класса Pen
Pen (Color color); // C++/CLI и C#
Pen (Color color, float width)); // C++/CLI и C#
Pen ( Brush ^brush, float width, )); // C++/CLI
Pen ( Brush brush, float width, )); // C#
создают перья с заданным цветом color, шириной width (по умолчанию ширина равна 1). Цвет color может быть задействован из кисти brush - объекта класса Brush (Brush - базовый класс для кистей).
Класс Pen имеет ряд свойств, например, Color для установки или получения цвета пера и Width для установки и получения ширины пера.
Объекты класса Pen широко применяются в качестве аргументов функций рисования класса Graphics, например, в функции DrawEllipse().
Создать и модифицировать перо можно следующим образом:
С++/CLI
Pen ^pPen1= gcnew Pen (Color::Black); // Создать чёрное перо с шириной 1
pPen1 -> Color= Color::Green; // Перо стало зелёным
pPen1 -> Width= 5; // и с шириной, равной 5
Pen ^pPen2= gcnew Pen (Color::Green, 5);// Создать зелёное перо с шириной 5
Pen ^pPen3= gcnew Pen (gcnew SolidBrush(Color::Green), 5); // Создать
// зелёное перо с шириной 5
Color color= Color::Red;
Pen ^pPen4= gcnew Pen (color, 5); // Создать красное перо с шириной 5
С#.
Pen pen1= new Pen (Color.Black); // Создано чёрное перо с шириной 1
pen1.Color= Color.Green; // Перо стало зелёным
pen1.Width= 5; // и с шириной, равной 5
Pen pen2= new Pen (Color.Green, 5); // Создать зелёное перо с шириной 5
Класс имеет много свойств и функций.
Java. В языке Java перо не используется.
Класс SolidBrush
C++/CLI и C#.Управляемый класс SolidBrush, порождённый из базового класса Brush, используется для создания объектов-кистей, применяемых при закрашивании фона окон или внутри фигур.
Конструктор класса
SolidBrush (Color color);
имеет единственный параметр color типа Color, определяющий цвет созданной кисти.
Класс SolidBrush имеет свойство Color, позволяющее установить и получить цвет кисти:
C++/CLI.
SolidBrush ^pBrush= gcnew SolidBrush (Color::Black); // Создать чёрную кисть
pBrush -> Color= Color::Red; // и сделать красной
Pen ^pPen5= gcnew Pen (pBrush, 5); // Создать красное перо с шириной 5
C#.
SolidBrush brush= new SolidBrush (Color.Black); // Создать чёрную кисть
brush.Color= Color.Red; // и сделать красной
Java. В языке Java кисть не используется.
Класс Font
Объектами класса Font представляются шрифты с указанными названиями, размерами и стилями.
Класс Font содержит перегруженные конструкторы и, в частности:
C++/CLI.
Font (String ^name, float size);
Font (String ^name, float size, FontStyle style);
C#.
Font (string name, float size);
Font (string name, float size, FontStyle style);
Java.
Font (String name, int style, int size);
где
name - название шрифта,
size - размер шрифта,
style - стиль шрифта ( Bold -жирный, Italic– курсив и др.)
Шрифт можно задать так:
C++/CLI.
Font ^pFont= gcnew Font (“Verdana”, 15);
C#.
Font font= new Font (“Ariel”, 20, FontStyle.Italic);
Java.
Font f1= new Font ("Courier", Font.BOLD, 50);
Замечание: Обратите внимание на отличия в списке аргументов конструкторов языков C# (C++/CLI) и Java.
Класс Graphics
C++/CLI и C#.Объект класса Graphics является контекстом рисования, связанным с конкретным контекстом устройства и чаще всего с окном (формой). Класс Graphics предоставляет множество функций для рисования в этом окне строк (strings), прямоугольников (rectangles), эллипсов (ellipses) и т.д. Например:
C++/CLI.
void DrawString (String ^pS, Font ^pF, Brush ^pB, float x, float y);
void DrawRectangle (Pen ^pP, Rectangle r);
void FillEllipse (Brush ^pB, Rectangle r);
C#.
void DrawString (string s, Font f, Brush b, float x, float y);
void DrawRectangle (Pen p, Rectangle r);
void FillEllipse (Brush b, Rectangle r);
Можно создать графический объект класса Graphics непосредственно, используя функцию CreateGraphics().
Graphics graphics= CreateGraphics ( );
Но чаще всего используют параметр функции перерисовки OnPaint(). Это параметр типа структуры PaintEventArgs, которая одним из своих элементов содержит свойство Graphics.
C#.
Graphics gr= this.CreateGraphics ( ); // Непосредственное использование gr.DrawString (“Drawing”, Font, new SolidBrush (Color.Blue), 10, 10);
C++/CLI.
protected:
virtual void OnPaint (PaintEventArgs ^arg) override // Использование через
// аргумент arg
{
Color col (Color::FromArgb (250, 0, 250, 250));
Drawing::Font ^pFont= gcnew Drawing::Font ("Verdana", 20,
FontStyle::Italic);
arg ->Graphics ->DrawString ("Drawing", pFont, gcnew SolidBrush (col),
10, 30);
}
Java.ЯзыкJava использует пакет AWT, который содержит множество графических классов и функций. Среди классов есть и класс Graphics, содержащий, например, такие функции рисования как
void drawLine (int x1, int y1, int x2, int y2); // Рисовать линию
void drawOval (int x, inty, int w, int h); // Рисовать овал (эллипс)
void drawRect (int x, int y, int w, int h); // Рисовать прямоугольник
void drawString (String str, int x, int y); // Рисовать строку
void fillOval (int x, inty, int w, int h); // Залить овал (эллипс) цветом
void fillRect (int x, int y, int w, int h); // Залить прямоугольник цветом
void setColor (Color color); // Установить цвет
void setFont (Font font); // Установить шрифт
На языке Java также можно создать графический объект с помощью функции getGraphics() и затем воспользоваться функциями рисования, но рисование обычно осуществляется в теле предопределённой функции paint(), аргумент которой является ссылкой на объект графического класса Graphics.
Java.
public void paint (Graphics g) // Использование через аргумент arg
{
g.setColor(Color.magenta);
Font font= new Font ("Verdana", Font.ITALIC, 30);
g.setFont(font);
g.drawString ("Drawing", 10, 70);
}
Пример 9.6.1 иллюстрирует применение графики на языках C#, C++/CLI и Java(J#). В программах на языках C# и C++/CLI использовано пространство имён System.Drawing (System::Drawing), включающее графические классы. Прикладное окно программы представлено на рис. 9.6.1. Программа на языке Java(J#) применяет пакет java.awt.
Пример 9.6.1. Использование графического объекта.
///////////////
// C#
using System;
using System.Drawing;
using System.Windows.Forms;
class MainClass : Form
{
public MainClass ( )
{
Text= "Drawing"; // Заголовок прикладного окна
Show ( );// Показать окно
Graphics gr= this.CreateGraphics ( ); // Создать графический объект
gr.DrawString ("Drawing", Font, // Нарисовать строку
new SolidBrush (Color.Blue), 10, 50);
gr.DrawString ("Drawing", new Font ("Arial", 25), // Нарис-ть строку new SolidBrush (Color.FromArgb (100, 255, 0, 0)), 5, 40);
String drawStr = "Drawing"; // Создать строку
Font drawFnt = new Font ("Arial", 30);// Создать шрифт
SolidBrush drawBr = new SolidBrush (Color.Green);// и кисть
float x= 10.0F; // Координаты начала строки
float y= 40.0F;
gr.DrawString (drawStr, drawFnt, drawBr, x, y); // Нарис-ть строку
gr.DrawEllipse (new Pen(new SolidBrush (Color.DarkViolet), 2),
15, 15, 60, 70); // Нарисовать эллипс
}
static void Main ( )
{
Application.Run (new MainClass ( )); // Запустить программу
}
}
////////////////
// C++/CLI
#include "stdafx.h"
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
ref class MainClass : Form
{
public: MainClass ( )
{
Text= "Drawing"; // Заголовок прикладного окна
Show ( ); // Показать окно
Graphics ^gr= this->CreateGraphics ( ); // Создать графический
// объект
// Нарисовать строки
gr->DrawString ("Drawing", Font,
gcnew SolidBrush (Color::Blue), 10, 50);
gr->DrawString ("Drawing", gcnew Drawing::Font ("Arial", 25), gcnew SolidBrush (Color::FromArgb (100, 255, 0, 0)), 5, 40);
String ^drawStr = "Drawing";
Drawing::Font ^drawFnt = gcnew Drawing::Font ("Arial", 30);
SolidBrush ^drawBr = gcnew SolidBrush (Color::Green);
float x= 10.0F;
float y= 40.0F;
gr->DrawString (drawStr, drawFnt, drawBr, x, y);
// Нарисовать эллипс
gr->DrawEllipse (gcnew Pen (gcnew SolidBrush (Color::DarkViolet),
2), 15, 5, 60, 70);
}
};
void main ( )
{
Application::Run (gcnew MainClass ( ));
}
///////////////
// Java и J#
import java.awt.*;
class MainClass extends Frame
{
public MainClass ( )
{
this.setTitle ("Drawing"); // Заголовок прикладного окна
setSize (300, 200);
show ( ); // Показать окно
Graphics gr= this.getGraphics ( ); // Создать графический объект
// Нарисовать строку
gr.setColor (Color.blue);
gr.drawString ("Drawing",10, 80);
// Нарисовать ещё строку
gr.setFont(new Font ("Arial", Font.BOLD,25));
gr.drawString ("Drawing", 5, 70);
// Нарисовать еще строку
String drawStr = "Drawing"; // Создать строку
gr.setFont(new Font ("Arial", Font.BOLD, 30));
gr.setColor (Color.green);
int x= 10; // Координаты начала строки
int y= 40;
gr.drawString (drawStr, x, y); // Нарис-ть строку
gr.setColor (Color.darkGray);
gr.drawOval (15, 45, 60, 100); // Нарисовать эллипс
}
public static void main ( )
{
MainClass m= new MainClass ( );
}
}
Рис.9.6.1. Прикладное окно с графической информацией