Рис. 5.3.7.1. Диаграмма классов Balls–приложения седьмого этапа
Пример 5.3.7.1. Реализация седьмого этапа разработки Balls–приложения на языке C#.
////////////////////
// C# File BallsCs7.cs
// Файл BallsCs7.cs полностью включает файл BallsCs6.cs, дополнив его новым
// классом SpecialBall специального объекта. Модифицирован класс Ball – в нём
// объявлено новое событие evSpecial. В классе Balls создан специальный объект,
// обработчик HandlerEvSpecial которого подписан на события всех обычных
// объектов. Изменения файла BallsCs6.cs выделены жирным шрифтом
// Изменения файла BallsCs6.cs выделены жирным шрифтом
. . .
class Ball // Класс обычного объекта
{
public event delEv ev; // Объявление события
public event delEv evSpecial; // Объявление специального события
. . .
void BallFunc ( ) // Выполнить поток
{
while (life) // Пока существует, выполнить
{
x += dx; y += dy;
if (x>w || x<0)
{
dx= -dx;
if (evSpecial != null)
{
evSpecial ( ); // Генерировать событие
}
}
if (y>h || y<0)
{
dy= -dy;
if (evSpecial != null)
{
evSpecial ( ); // Генерировать событие
}
}
if (ev != null)
{
ev ( ); // Генерировать событие
}
Thread.Sleep (100);
}
}
}
//-------------------------------------
class SpecialBall // Класс специального объекта
{
public int x, y; // Координаты шара
public int d=1; // Ширина пера
Thread thread; // Поток
bool run; // Признак выполнения потока
public SpecialBall (int X, int Y) // Конструктор
{
run= false;
x= X; y= Y;
}
void Start ( ) // Стартовать
{
if (!run) // Если поток не выполнялся, то
{
run= true; // пусть выполняется и
d= 5; // утолщить кольцо
thread= new Thread (new ThreadStart (BallFunc));
thread.Start ( ); // Стартовать поток
}
}
public void HandlerEvSpecial ( ) // Обработать событие
{
Start ( );
}
void BallFunc ( ) // Выполнить поток
{
Thread.Sleep (2000);
d= 1;
run= false;
}
}
//-------------------------------------
class Balls : Form // Класс потоковых объектов
{
public Ball [] pBall; // Массив потоковых объектов
public SpecialBall pSpecialBall;
bool run; // Признак выполнения потоковых объектов
Color col; // Цвет шаров
public Balls ( ) // Конструктор
{
run= true;
col= System.Drawing.Color.FromArgb (0, 0, 255);
pSpecialBall= new SpecialBall (30, 30);
pBall= new Ball [2];
for (int i= 0; i < 2; i++)
{
pBall[i]=new Ball (i*3+10, 1*3+15, i*3+5, i*3+5);
pBall[i].ev += new delEv (HandlerEv );
pBall[i].evSpecial += new delEv (
pSpecialBall.HandlerEvSpecial);
}
Text= "Balls"; // Заголовок прикладного окна
Start ( ); // Стартовать обычные объекты
}
. . .
//---------------
protected override void OnPaint (PaintEventArgs arg) // Перерисовать
{
for (int i= 0; i < 2; i++)
{
arg .Graphics.DrawEllipse (new Pen (col),
pBall[i].x, pBall[i].y, 20, 20);
pBall[i].w= Width;
pBall[i].h= Height;
}
arg .Graphics.DrawEllipse (new Pen (Color.Yellow, pSpecialBall.d),
pSpecialBall.x, pSpecialBall.y, 20, 20);
}
. . .
}
. . .
/*
Результат:
Появились прикладное окно с перемещающимися шарами и дочернее окно
с кнопкой и со списком. При нажатии на кнопку можно приостанавливать
или возобновлять движение шаров. Используя список, можно изменить цвет
шаров. В левом верхнем углу прикладного окна находится круг желтого цвета,
толщина которого утолщается при отскакивании кругов обычных объектов от
краёв прикладного окна.
*/
Рис. 5.3.7.1. Прикладное и дочернее окна Balls–приложения 7 этапа
Пример 5.3.7.2. Реализация седьмого этапа разработки Balls–приложения на языке Java.
package BallsCj7;
////////////////////
//C# File BallsCj7
import java.util.*;
import java.awt.*;
import java.awt.event.*;
class Obs
{
private int num, n;
private boolean special; //
public Obs (int num, int n, boolean special) //
{this.num= num; this.n= n;this.special= special;}
int getNumber(){return num;}
int getN(){return n;}
boolean getSpecial(){return special;} //
}
class Ball extends Observable implements Runnable // Класс обычного объекта
{
int num;
Thread thread;
boolean run;
boolean waiting= false;
boolean life;
public int x, y;
public int w, h;
public int dx, dy;
public Ball (int Num , int X, int Y, int Dx, int Dy)// Конструктор
{
num= Num; life= false; run= false;
w= 100; h= 100;
x= X; y= Y; dx= Dx; dy= Dy;
Start ( );
}
public void Start ( ) // Стартовать
{
if (!run)
{
run= true;
life= true;
thread= new Thread (this);
thread.start ( );
}
}
//---------------
synchronized public void Suspend ( ) // Приостановить
{
if (run)
{
run= false;
waiting=true;
}
}
//---------------
synchronized public void Resume ( ) // Возобновить
{
if (!run)
{
run= true;
waiting=false;
notify();
}
}
//---------------
public void run ( ) // Выполнить поток
{
int n= 0;
while (life)
{
System.out.print("object "+num);
System.out.println(" n= "+n);
n++;
x += dx; y += dy;
if (x>w || x<0)
{
setChanged(); //
notifyObservers(new Obs(num, n, true)); //
dx= -dx;
}
if (y>h || y<0)
{
setChanged(); //
notifyObservers(new Obs(num, n, true)); //
dy= -dy;
}
// Уведомить
setChanged();
notifyObservers(new Obs(num, n, false)); //
try
{
Thread.sleep (100);
synchronized(this)
{
if(waiting)
wait();
}
}
catch(InterruptedException iE){}
}
System.out.print("object "+num);
System.out.println(" finished ");
}
}
class SpecialBall implements Runnable, // Класс специального объекта//
Observer
{
public int x, y; // Координаты шара
Thread thread; // Поток
boolean yes; // Признак выполнения потока //
public SpecialBall (int X, int Y) // Конструктор
{
yes= false;
x= X; y= Y;
}
void Start ( ) // Стартовать
{
if (!yes) // Если поток не выполнялся, то
{
yes= true; // пусть выполняется
thread= new Thread (this);
thread.start ( ); // Стартовать поток
}
}
public void update(Observable ob, Object obj) //
{
Obs obs=(Obs) obj;
if(obs.getSpecial())
Start ( );
}
public void run ( ) // Выполнить поток//
{
try
{
Thread.sleep (2000);
}
catch(InterruptedException iE){}
yes= false;
}
}
//-------------------------------------
class Balls extends Frame implements Observer // Класс объектов
{
Ball [] pBall;
Color col;
public SpecialBall pSpecialBall; //
public Balls ( )
{
this.setTitle("Balls");
this.setSize(400, 300);
col= Color.red;
pSpecialBall= new SpecialBall (30, 30); //
pBall= new Ball [2];
for (int i= 0; i < 2; i++)
{
pBall[i]=new Ball (i, i*3+10, 1*3+15, i*3+5, i*3+5);
pBall[i].addObserver(this);
pBall[i].addObserver(pSpecialBall);
}
this.show();
Start ( );
}
//---------------
public void SetColor (Color Col) // Установить цвет
{
col= Col;
repaint();
}
//---------------
public void Start ( ) // Стартовать
{
for(int i=0; i < 2; i++)
{
pBall[i]. Start ( );
}
}
//---------------
public void Suspend ( ) // Возобновить
{
for (int i=0; i < 2; i++)
pBall[i].Suspend ( );
}
//---------------
public void Resume ( ) // Приостановить
{
for (int i= 0; i < 2; i++)
pBall[i].Resume ( );
}
public void update (Observable r, Object ob) // Обработчик события ev
{
Obs obs= (Obs) ob;
if(!obs.getSpecial())
{
System.out.print("object num= "+ obs.getNumber());
System.out.println(" n= "+ obs.getN());
repaint();
}
}
public void paint (Graphics g)
{
super.paint (g);
g.setColor(col);
for (int i= 0; i < 2; i++)
{
g.drawOval(pBall[i].x, pBall[i].y, 20, 20);
pBall[i].w= this.getSize().width;
pBall[i].h= this.getSize().height;
}
if(pSpecialBall.yes)
{
g.setColor(Color.yellow);
g.drawOval(pSpecialBall.x, pSpecialBall.y, 20, 20);
}
}
}
class User extends Balls implements ActionListener, // Класс пользователя шаров
ItemListener
{
private boolean run;
Frame pChildForm;
Button pBut;
private Choice c;// Ссылка на объект-список
public User ( )
{
run= true;
pBut= new Button("OK");
pBut.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent aE)
{
System.out.println ("OkButton");
if (run)
{
run= false;
Suspend ( );
}
else
if (!run)
{
run= true;
Resume ( );
}
}
});
this.setSize(400, 300);
//---------------
pChildForm= new Frame ( );
pChildForm.setLocation(250, 10);
pChildForm.setSize(250, 250);
pChildForm.setTitle("User");
pChildForm.show ( );
pChildForm.setLayout (new FlowLayout ( ));// Установить расстановку
pChildForm.add(pBut);
c= new Choice ( ); // Создать объект списка
c.addItem ("blue");// Добавить элемент "blue"
c.addItem ("green");//Добавить элемент "green"
c.addItem ("red");//Добавить элемент "red"
pBut.addActionListener(this);
pChildForm.add(c, new Point (100,20));//Подсоединить список к окну
pChildForm.setVisible (true);// Показать кнопку и список в окне
}
public void itemStateChanged (ItemEvent iE) { }
public void actionPerformed(ActionEvent aE)
{
switch (c.getSelectedIndex ( ))// Получить индекс списка
{
case 0: col= Color.blue;//
break;
case 1: col= Color.green;//
break;
case 2: col= Color.red;//
break;
}
repaint ( );// Перерисовать
}
//-------------------------
public static void main ( )
{
User u= new User();
}
}
/*
Результат:
Появились прикладное окно с перемещающимися шарами и дочернее окно
с кнопкой и элементом списка. При нажатии на кнопку можно приостанавливать или возобновлять
движение шаров. Выделив в списке цвет, можно изменить цвет шаров.
При отталкивании каждого шара от границ окна появляется в верхнем левом углу окна желтый шар и исчезает через 2000 мс.
*/
6. Описание проблем, возникших при разработке программной системы.
Поэтапная разработка программы позволила быстро разработать её и отладить. Проблем не было.
7. Список используемой литературы
1. Байдачный С.С. .NET Framework. Секреты создания Windows-приложений. – М.: СОЛОН-Пресс, 2004. – 496 с.: ил.
2. Гербердт Шилдт. C#: учебный курс. – СПб.: Питер; К.: Издательская группа BHV, 2003. – 512 c.: ил.
3. Джесс Либерти. Программирование на C#: 2-е издание. – СПб.: Символ-Плюс, 2003. – 688 c.: ил.
4. Медведев В.И. Программирование на С++, C++.NET и С#: – Казань: Мастер Лайн, 2005. – 270 c.: ил. – (Серия «Современная прикладная математика и информатика»).