Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Part6(9-прилож)+++а.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.82 Mб
Скачать

Классы UserControl и Panel

Объекты класса UserControl языка C# и объекты класса Panel языка Java своеобразны, поскольку представляют соответствующие управляющие элементы в окне в виде прямоугольных областей, каждая из которых обладает функциональностью окна. То есть в этой прямоугольной области можно выводить графическую информацию, применять свои потоки и события. Так в прикладном окне могут появиться прямоугольные области, самостоятельно функционирующие. Эти области (точнее, эти управляющие элементы) размещаются в окне так же, как и любые другие управляющие элементы – кнопки, редакторы и т.д. Обычно на базе классов UserControl и Panel создаются порождённые классы, в которых, воспользовавшись свойствами управляющего элемента, легко получаются координаты его левой верхней точки, размер элемента и другие свойства, а также многие функции базовых классов UserControl и Panel, включая функции OnPaint() или paint() и Invalidate() или repaint(). Такое необычное применение в порождённом классе свойств, установленных вне управляющего элемента, иллюстрируют программы примеров 9.8.4, 9.8.5 и 9.8.6.

C# и C++/CLI. Объектом класса UserControl представляется поле, обладающее свойствами и функциональностью окна. Объект создаётся конструктором:

UserControl ( );

При применении класса UserControl можно воспользоваться свойствами BackColor, ClientSize, Controls, Height, Location, Size, Visible, Width и другими, наследуемыми из класса Control, событиями Click, MouseDown, MouseUp и множеством других, наследуемых из того же класса Control. Также наследуются известные нам функции OnPaint() и Invalidate(), и масса других. Как видим, управляющий элемент типа UserControl может существенно обогатить интерфейс пользователя с программой.

Java. Также как и элемент типа UserControl, управляющий элемент типа Panel содержит сотни свойств и функций, наследуемых из базовых классов. Выделим, например, такие свойства, как getGraphics(), getSize(), getLocation(), и функции paint() и addMouseListener().

Сравните диаграммы классов рисунков 9.3.1.1 и 9.8.6. Сравнение показывает, что функциональность управляющего элемента типа UserControl и окна типа Form схожи. Что же касается управляющего элемента типа Panel и окна типа Frame, то здесь имеется отличие, как явствует из рисунков 9.3.1.2 и 9.8.7.

Рис. 9.8.6. Наследование базовых классов классом UserControl в C# и C++/CLI

Рис. 9.8.7. Наследование базовых классов классом Panel в Java

Пример 9.8.4. Программа с управляющим элементом типа UserControl на языке C# с рисованием в потоке.

Приложение имеет прикладное окно с элементом типа UserControl. В области клиента этого управляющего элемента рабочий поток рисует эллипсы со случайными цветами и размерами, сменяющие друг друга (см. рис.9.8.8).

Рис. 9.8.8. Прикладное окно программы примера 10.8.4

///////////////

// C#

using System;

using System.Drawing;

using System.Threading;

using System.Windows.Forms;

// Класс управляющего элемента типа UserControl

class User: UserControl

{

Thread t; // Ссылка на поток

bool life; // Признак жизни потока

Graphics g; // Ссылка на графический объект

Random rand; // Ссылка на случайное число

// Конструктор

public User ( )

{

g= this.CreateGraphics (); // Создать граф.объект

rand= new Random (); // Создать случайное число

// Создать и запустить поток рисования

life= true; // Пусть поток живёт

t= new Thread (new ThreadStart (F)); // Создать объект

t.Start ( ); // Запустить поток

}

// Выполнить рабочий поток

private void F ( )

{

while(life)

{

// Нарисовать случайный эллипс в области упр.элемента

g.FillEllipse (new SolidBrush (Color.FromArgb (rand.Next(255),

rand.Next(255), rand.Next(255))),

rand.Next (this.Width),

rand.Next (this.Height),

rand.Next (this.Width<this.Height?this.Width:this.Height),

rand.Next (this.Width<this.Height?this.Width:this.Height));

// Поспать

Thread.Sleep (50);

}

}

}

// Класс прикладного окна

class W: Form

{

User u; // Ссылка на объект управляющего элемента

//Конструктор

public W ( )

{

u= new User( ); // Создать объект управляющего элемента

u.Location= new Point (50, 40);// Разместить,

u.Size =new Size (140, 130); // установить размер

u.BackColor=Color.Coral; // и фон управляющего элемента

Controls.Add (u); // Включить управляющий элемент в

// коллекцию

}

// Выполнить основной поток

static void Main ( )

{

Application.Run (new W());

}

}

Обсуждение.

C#.

Читатель.

Изменится ли функционирование программы, если воспользоваться функцией перерисовки OnPaint()?

Автор.

В нижеследующей программе в области клиента управляющего элемента типа UserControl рабочий поток совместно с функцией OnPaint() рисует эллипсы со случайными цветами и размерами. Поскольку при рисовании каждого эллипса область клиента управляющего элемента перерисовывается заново, в отличие от примера 9.8.4, в котором текущий эллипс рисуется на предыдущих эллипсах, в нижеследующем примере 9.8.5 каждый рисуемый эллипс сменяет предыдущий.

// Пример 9.8.5. Обсуждение. C# программа с управляющим элементом типа UserControl

// и функцией OnPaint().

using System;

using System.Drawing;

using System.Threading;

using System.Windows.Forms;

// Класс управляющего элемента типа UserControl

class User: UserControl

{

Thread t; // Ссылка на поток

bool life; // Признак жизни потока

Graphics g; // Ссылка на графический объект

Random rand; // Ссылка на случайное число

// Конструктор

public User ( )

{

g= this.CreateGraphics (); // Создать граф.объект

rand= new Random (); // Создать случайное число

// Создать и запустить поток рисования

life= true; // Пусть поток живёт

t= new Thread (new ThreadStart(F)); //Создать объект потока

t.Start ( ); // Запустить поток

}

// Выполнить рабочий поток

private void F ( )

{

while (life)

{

// Перерисовать область клиента управляющего элемента

Invalidate ( );

// Поспать

Thread.Sleep (50);

}

}

protected override void OnPaint (PaintEventArgs e)

{

base.OnPaint (e);

// Нарисовать случайный эллипс в области упр.элемента

e.Graphics.FillEllipse (new SolidBrush(Color.FromArgb(rand.Next(255),

rand.Next (255),rand.Next(255))),

rand.Next (this.Width),

rand.Next (this.Height),

rand.Next (this.Width<this.Height?this.Width:this.Height),

rand.Next (this.Width<this.Height?this.Width:this.Height));

}

}

// Класс прикладного окна

class W: Form

{

User u; // Ссылка на объект управляющего элемента

//Конструктор

public W ( )

{

u= new User ( ); // Создать объект управляющего элемента

u.Location= new Point (50, 40); // Разместить,

u.Size =new Size (140, 130); // установить размер

u.BackColor=Color.LightGray; // и фон управляющего элемента

Controls.Add (u); // Включить управляющий элемент в

// коллекцию окна

}

// Выполнить основной поток

static void Main ( )

{

Application.Run (new W());

}

}

Пример 9.8.6. Программа с управляющим элементом типа Panel на языке Java с применением потока и функции paint()

Как и в программе примера 9.8.5 в данной программе рисование случайных эллипсов в пределах управляющего элемента типа Panel осуществляется функцией paint(), вызываемой посредством функции repaint() из потока. В области клиента управляющего элемента рисуются эллипсы со случайными координатами, размерами и цветами.

///////////////

// Java и J#

import java.awt.*;

import java.awt.event.*;

import java.util.*;

// Класс управляющего элемента типа UserControl

class User extends Panel implements Runnable

{

Thread t; // Ссылка на поток

boolean life; // Признак жизни потока

Graphics g; // Ссылка на графический объект

Random rand; // Ссылка на случайное число

// Конструктор

public User ( )

{

show();

this.setVisible (true); // Показать управляющий элемент

g= this.getGraphics (); // Создать графический объект

rand= new Random (); // Создать случайное число

// Создать и запустить поток рисования

life= true; // Пусть поток живёт

t= new Thread (this); // Создать объект потока

t.start ( ); // Запустить поток

}

// Завершить поток

public void Finish ( )

{

life= false;

try

{

t.join ( );

}

catch (InterruptedException e) { }

}

// Выполнить рабочий поток

public void run ( )

{

while (life)

{

System.out.println ("-----I'm working");

repaint ( );

// Поспать

try

{

Thread.sleep (50);

}

catch (InterruptedException e) { }

}

}

public void paint (Graphics g)

{

g.setColor (new Color (rand.nextInt(255),

rand.nextInt(255), rand.nextInt(255)));

// Нарисовать случайный эллипс в области упр.элемента

g.fillOval (

rand.nextInt (this.getSize().width),

rand.nextInt (this.getSize().height),

rand.nextInt (this.getSize().width<this.getSize().height?

this.getSize().width:this.getSize().height),

rand.nextInt (this.getSize().width<this.getSize().height?

this.getSize().width:this.getSize().height));

}

}

// Класс прикладного окна

class W extends Frame

{

User u; // Ссылка на объект управляющего элемента

//Конструктор

public W ( )

{

setLayout(null);

setSize (340, 230); // Установить размер

u= new User( ); // Создать объект управл. элемента

u.setLocation(50, 40); // Разместить,

u.setSize (140, 130); // установить размер

u.setBackground (Color.lightGray); // и фон управляющего

// элемента

add(u); // Включить управляющий элемент в

// коллекцию

// Применить внутренний анонимный класс

// для закрытия окна

this.addWindowListener (new WindowAdapter ( )

{

public void windowClosing (WindowEvent wE)

{

System.exit (0);

}

});

show();

}

// Выполнить основной поток

static public void main ( )

{

W w= new W ();

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]