- •4.1. Объектное представление программы 6
- •4.3. Потоки 7
- •5.Поэтапная разработка программной системы 7
- •1. Задание
- •2.Уточнение задания
- •3. Описание разрабатываемой программы с точки зрения пользователя
- •4.2. События
- •4.3. Потоки
- •5.Поэтапная разработка программной системы
- •5.3.1. Этап 1. Разработка класса Avto
- •5.3.2. Этап 2. Разработка события ev и уведомления
- •5.3.3. Этап 3. Разработка прикладного и дочернего окон, кнопки добавления шаров.
- •5.3.4. Этап 4. Добавление элемента списка, добавление кнопок остановки и удаления.
- •5.3.5. Этап 5. Добавления события ev.
- •11. Приложение 4. Текст программы на языке Java
5.3.5. Этап 5. Добавления события ev.
На данном этапе добавим событие ev в классе Avto и обработчик Handlerev в классе Avtos. Реализация этого этапа представлены в примерах 5.3.5.1, 5.3.5.2 и 5.3.5.3.
Пример 5.3.5.1. Реализация пятого этапа разработки Avtos–приложения на языке С#.
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Collections;
public delegate void Del();
public class Avto
{
…
public event Del ev;
…
void AvtoFunc()
{
…
if (ev != null) ev();
…
}
class Avtos : Form
{
…
listBoxNum.Items.Add(num);
al.Add(b);
IEnumerator inum = al.GetEnumerator();
while (inum.MoveNext())
{
Avto q = (Avto)inum.Current;
q.evSpecial += new delEv(this.HandlerEvSpecial);
q.ev += new Del(this.Handlerev);
}
}
…
//обработчик столкновения и разъезда машин
public void Handlerev()
{
bool crash = false;
for (int i = 0; i < al.Count; i++)
{
Avto a = (Avto)al[i];
if (a.life)
for (int j = i; j < al.Count; j++)
{
Avto a1 = (Avto)al[j];
if ((a.num != a1.num) && (Math.Abs(a1.x - a.x) < 10) && (Math.Abs(a1.y - a.y) < 10))
{
Console.WriteLine("Автомобили " + a.num +" и "+ a1.num + " врезались");
crash = true;
a.run = false;
a1.run = false;
Thread.Sleep(500);
a.run = true;
a1.run = true;
run = true;
if (crash)
{
if ((a.x > a1.x)||(a.y > a1.y))
{
a.x += 2;
a1.x -= 1;
a.y += 2;
a1.y -= 1;
crash = false;
}
else
{
a1.x += 2;
a.x -= 1;
a1.y += 2;
a.y -= 1;
crash = false;
}
Console.WriteLine("Автомобили " + a.num + " и " + a1.num + " разъехались");
}
}
}
}
}
…
}
}
static void Main()
{
Application.Run(new Avtos());
}
}
Результат:
Пример 5.3.5.2. Реализация пятого этапа разработки Avtos–приложения на языке C++/CLI.
// kurs.cc.cpp : main project file.
#include "stdafx.h"
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::Threading;
delegate void Del();
ref class Avto
{
public:
…
event Del ^ev;
…
void AvtoFunc()
{
…
ev();
…
};
ref class Avtos : public Form
{
…
public:
void ADD(Object ^obj, EventArgs ^arg)
{
…
q->ev += gcnew Del(this, &Avtos::Handlerev);
}
}
…
public:
void Handlerev()
{
bool crash = false;
for (int i = 0; i < al->Count; i++)
{
Avto ^a = (Avto^)al[i];
if (a->life)
for (int j = i; j < al->Count; j++)
{
Avto ^a1 = (Avto^)al[j];
if ((a->num != a1->num) && (System::Math::Abs(a1->x - a->x) < 10) && (System::Math::Abs(a1->y - a->y) < 10))
{
System::Console::WriteLine("Автомобили " + a->num + " и " + a1->num + " врезались");
crash = true;
a->run = false;
a1->run = false;
Thread::Sleep(500);
a->run = true;
a1->run = true;
run = true;
if (crash)
{
if ((a->x > a1->x)||(a->y > a1->y))
{
a->x += 2;
a1->x -= 1;
a->y += 2;
a1->y -= 1;
}
else
{
a1->x += 2;
a->x -= 1;
a1->y += 2;
a->y -= 1;
}
System::Console::WriteLine("Автомобили " + a->num + " и " + a1->num + " разъехались");
}
}
}
}
}
…
};
static void main()
{
Application::Run(gcnew Avtos());
}
Результат:
Пример 5.3.5.3. Реализация пятого этапа разработки Avtos–приложения на языке Java.
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class Avto extends Observable implements Runnable
{
…
}
public class Autos extends Frame implements Observer, ActionListener, ItemListener
{
…
//перерисовать окно
public void paint(Graphics g)
{
g.setColor(Color.gray);
g.fillOval(100, 100, 604, 604);
g.fillOval(175, 175, 450, 450);
g.setColor(Color.white);
g.fillOval(173, 173, 454, 454);
g.setColor(Color.gray);
g.fillOval(175, 175, 450, 450);
g.fillOval(175, 175, 450, 450);
g.setColor(Color.green);
g.fillOval(245, 245, 300, 300);
for (int i = 0; i < al.size(); i++)
{
g.setColor(Color.red);
Avto a = (Avto)al.get(i);
g.fillOval(a.X(), a.Y(), 25, 25);
g.setColor(Color.white);
g.drawString(Integer.toString(a.num), a.X() + 5, a.Y() + 15);
}
boolean crash = false;
for (int i = 0; i < al.size(); i++)
{
Avto a = (Avto)al.get(i);
if (a.life)
for (int j = 0; j < al.size(); j++)
{
Avto a1 = (Avto)al.get(j);
if ((a.num != a1.num) && (Math.abs(a1.x - a.x) < 10) && (Math.abs(a1.y - a.y) < 10))
{
System.out.println("Avto " + a.num + " and " + a1.num + " vrezalis");
crash = true;
a.run = false;
a1.run = false;
try
{
Thread.sleep(400);
}
catch (InterruptedException e) { }
run = true;
a.run = true;
a1.run = true;
if (crash)
{
if ((a.x > a1.x) || (a.y > a1.y))
{
a.x += 2;
a1.x -= 2;
a.y += 2;
a1.y -= 2;
}
else
{
a1.x += 2;
a.x -= 2;
a1.y += 2;
a.y -= 2;
}
System.out.println("Avto " + a.num + " and " + a1.num + " raz'ehalis");
}
}
}
}
}
//выполнить команды для нажатия кнопок
public void actionPerformed(ActionEvent aE)
{
…
}
public void itemStateChanged(ItemEvent e)
{
repaint();
}
public static void main(String[] args)
{
Autos auto = new Autos();
auto.setSize(750, 750);
auto.setVisible(true);
}
}
Результат:
6. Описание проблем, возникших при разработке
программной системы.
Поэтапная разработка программы позволила быстро разработать её и отладить. Проблем не было.
7. Список используемой литературы
Медведев В.И. Особенности объектно-ориентированного программирования на C++/CLI, C# и Java. 3-е изд., испр. и доп. – Казань: РИЦ «Школа», 2011. – 430 c.: ил
8. Приложение 1. Диаграмма классов разработанной
программы
9. Приложение 2. Текст программы на языке C#
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Collections;
public delegate void delEv();
public delegate void Del();
public class Avto
{
public int num; //номер объекта
public event delEv evSpecial;
public int x, y;//координаты машины
public double fi = 0.1;
public int dx1, dy1, dx2, dy2;//приращения машин
public int speed;//скорость машины
Thread thread;
public bool dvig = true;
public bool life;//признак жизни потока
public bool run = true;
public event Del ev;
public int N { get { return num; } }//номер машины
public int X { get { return x; } set { x = value; } }//координата X
public int Y { get { return y; } set { y = value; } }//координата Y
public Avto(int N, int X, int Y, int Speed)
{
num = N;
x = X; y = Y;
speed = Speed;
life = true;
//создать и запустить поток
thread = new Thread(new ThreadStart(AvtoFunc));
thread.Start();
}
public void Finish()//завершить поток
{
//Resume();
life = false;
}
void AvtoFunc()
{
while (life)
{
if (run)
{
Thread.Sleep(speed);
if (ev != null) ev();
if (dvig)
{
//уравнение движения по окр-ти
dx1 = (int)(19 * Math.Sin(fi));
dy1 = (int)(19 * Math.Cos(fi));
x += dx1;
y += dy1;
}
else
{
dx2 = (int)(28 * Math.Sin(fi));
dy2 = (int)(28 * Math.Cos(fi));
y -= dx2;
x -= dy2;
}
fi += 0.1;
}
evSpecial();
}
}
public void Suspend()//приостановить поток
{
if (run)
{
run = false;
}
}
public void Resume()//возобновить поток
{
if (!run)
{
run = true;
}
}
}
class Avtos : Form
{
ArrayList al; //ссылка на список машин
ListBox listBoxNum;//список номеров машин
private int num = 0;//номер объекта машины
private Form f;// ссылка на дочернее окно управления
private Button add, del, ok;// ссылки на кнопки
public bool run = true;//признак движения машин
public Avtos()//конструктор
{
al = new ArrayList();
run = true;//машины двигаются
Size = new Size(770, 770);//установить размер прикладного окна
Text = "Шоссе";//установить заголовок прикладного окна
f = new Form();//создать объект дочернего окна
f.Text = "Control";//установить заголовок дочернего окна
f.Size = new Size(300, 150);//установить размеры дочернего окна
f.Show();//показать дочернее окно
ok = new Button();//создать кнопку приостановки
ok.Text = "Stop";//именовать кнопку
ok.Size = new Size(45, 30);//размеры кнопки
ok.Location = new Point(5, 10);//поместить кнопку в окне
ok.Click += new EventHandler(OK);//подписать обработчик
f.Controls.Add(ok);//поместить объект ок в контейнер окна
add = new Button();//создать кнопку добавления машин
add.Text = "Add";//именовать кнопку
add.Size = new Size(45, 30);//размеры кнопки
add.Location = new Point(5, 50);//поместить кнопку в окне
add.Click += new EventHandler(ADD);//подписать обработчик
f.Controls.Add(add);//поместить объект add в контейнер окна
listBoxNum = new ListBox();//создать элемент списка номеров
listBoxNum.Location = new Point(140, 10);//разместить в окне
listBoxNum.Size = new Size(60, 70);//установить размер
f.Controls.Add(listBoxNum);//поместить в контейнер окна
del = new Button();//создать кнопку удаления машин
del.Text = "Del";//именовать кнопку
del.Size = new Size(40, 30);//установить размер
del.Location = new Point(90, 10);//поместить кнопку в окне
del.Click += new EventHandler(DEL);//подписать обработчик
f.Controls.Add(del);//поместить объект del в контейнер окна
}
//приостановить или возобновить поток перерисовки
private void OK(Object obj, EventArgs arg)
{
IEnumerator inum = al.GetEnumerator();
while (inum.MoveNext())
{
//перебрать список объектов машин
Avto a = (Avto)inum.Current;
if (run) { a.Suspend(); ok.Text = "Start"; }
else { a.Resume(); ok.Text = "Stop"; }
}
run = !run;
}
//создать автомобиль и включить его в список
public void ADD(Object obj, EventArgs arg)
{
num++;
Avto b;
Random r = new Random();
if (num % 2 == 0)
{
Avto a = new Avto(num, 385, 660, r.Next(50, 100));
Console.WriteLine("Добавлен автомобиль " + num);
a.dvig = false;
//a.ev += new Del(this.Handlerev);
b = a;
}
else
{
Avto a = new Avto(num, 195, 400, r.Next(50, 100));
Console.WriteLine("Добавлен автомобиль " + num);
a.dvig = true;
//a.ev += new Del(this.Handlerev);
b = a;
}
listBoxNum.Items.Add(num);
al.Add(b);
IEnumerator inum = al.GetEnumerator();
while (inum.MoveNext())
{
Avto q = (Avto)inum.Current;
q.evSpecial += new delEv(this.HandlerEvSpecial);
q.ev += new Del(this.Handlerev);
}
}
//обработать нажатие кнопки удаления машины
private void DEL(Object o, EventArgs e)
{
if (listBoxNum.SelectedIndex == -1)
{
MessageBox.Show("Выделите номер"
+ "\n удаляемого объекта");
}
else
{
int numSel = (int)listBoxNum.SelectedItem;
listBoxNum.Items.Remove(numSel);//Удалить из списка
IEnumerator inum = al.GetEnumerator();
while (inum.MoveNext())
{
Avto a = (Avto)inum.Current;
if (a.N == numSel)
{//объект с указанным номером найден
a.Finish();//завершить поток
al.Remove(a);//удалить из списка
return;
}
}
}
}
//обработчик столкновения и разъезда машин
public void Handlerev()
{
bool crash = false;
for (int i = 0; i < al.Count; i++)
{
Avto a = (Avto)al[i];
if (a.life)
for (int j = i; j < al.Count; j++)
{
Avto a1 = (Avto)al[j];
if ((a.num != a1.num) && (Math.Abs(a1.x - a.x) < 10) && (Math.Abs(a1.y - a.y) < 10))
{
Console.WriteLine("Автомобили " + a.num +" и "+ a1.num + " врезались");
crash = true;
a.run = false;
a1.run = false;
Thread.Sleep(500);
a.run = true;
a1.run = true;
run = true;
if (crash)
{
if ((a.x > a1.x)||(a.y > a1.y))
{
a.x += 2;
a1.x -= 1;
a.y += 2;
a1.y -= 1;
crash = false;
}
else
{
a1.x += 2;
a.x -= 1;
a1.y += 2;
a.y -= 1;
crash = false;
}
Console.WriteLine("Автомобили " + a.num + " и " + a1.num + " разъехались");
}
}
}
}
}
public void HandlerEvSpecial()
{
Invalidate();
}
//перерисовать прикладное окно
protected override void OnPaint(PaintEventArgs arg)
{
arg.Graphics.FillEllipse(new SolidBrush(Color.Gray), 100, 100, 604, 604);//внешнее кольцо
arg.Graphics.FillEllipse(new SolidBrush(Color.White), 173, 173, 454, 454);//разделительная полоса
arg.Graphics.FillEllipse(new SolidBrush(Color.Gray), 175, 175, 450, 450);//внутреннее кольцо
arg.Graphics.FillEllipse(new SolidBrush(Color.YellowGreen), 245, 245, 300, 300);
this.BackColor = Color.YellowGreen; // Закрасить фон зеленым
this.FormBorderStyle = FormBorderStyle.FixedSingle; // Запрет изменения размера окна
this.MaximizeBox = false; // Убрать кнопку "Развернуть окно"
this.DoubleBuffered = true; // Включить буферизацию изображения
IEnumerator inum = al.GetEnumerator();
while (inum.MoveNext())
{
Avto a = (Avto)inum.Current;
arg.Graphics.FillEllipse(new SolidBrush(Color.Red), a.x, a.y, 25, 25);//машина
arg.Graphics.DrawString(a.N.ToString(), new Font("Comic Sans MS", 9), new SolidBrush(Color.White), a.x + 5, a.y + 5);//номера машин
}
}
static void Main()
{
Application.Run(new Avtos());
}
}
10. Приложение 3. Текст программы на языке C++/CLI
// kurs.cc.cpp : main project file.
#include "stdafx.h"
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::Threading;
using namespace System::Collections;
using namespace System::Drawing;
using namespace System::Windows::Forms;
delegate void delEv();
delegate void Del();
ref class Avto
{
public:
int num;
event delEv ^evSpecial;
int x, y;
double fi;
int dx1, dy1, dx2, dy2;
int speed;
Thread ^thread;
bool dvig;
bool life;
bool run;
event Del ^ev;
property int N { int get() { return num; } }
property int X { int get() { return x; } }
property int Y { int get() { return y; } }
Avto(int N, int X, int Y, int Speed)
{
fi = 0.1;
num = N;
dvig = true;
run = true;
x = X; y = Y;
speed = Speed;
life = true;
thread = gcnew Thread(gcnew ThreadStart(this,&Avto::AvtoFunc));
thread->Start();
}
void Finish()
{
//Resume();
life = false;
}
void AvtoFunc()
{
while (life)
{
if (run)
{
Thread::Sleep(speed);
ev();
if (dvig)
{
dx1 = (int)(19 * System::Math::Sin(fi));
dy1 = (int)(19 * System::Math::Cos(fi));
x += dx1;
y += dy1;
}
else
{
dx2 = (int)(28 * System::Math::Sin(fi));
dy2 = (int)(28 * System::Math::Cos(fi));
y -= dx2;
x -= dy2;
}
fi += 0.1;
}
evSpecial();
}
}
void Suspend()
{
if (run)
{
run = false;
}
}
void Resume()
{
if (!run)
{
run = true;
}
}
};
ref class Avtos : public Form
{
private:
ArrayList ^al; //ссылка на список машин
ListBox ^listBoxNum;//список номеров машин
int num;// = 0;//номер объекта машины
Form ^f;// ссылка на дочернее окно управления
Button ^add, ^del, ^ok;// ссылки на кнопки
bool run;// = true;//признак движения машин
public:
Avtos()
{
num=0;
al = gcnew ArrayList();
run = true;
Size = Drawing::Size(770, 770);
Text = "Шоссе";
f = gcnew Form();
f->Text = "Control";
f->Size = Drawing::Size(300, 150);
f->Show();
ok = gcnew Button();
ok->Text = "Stop";
ok->Size = Drawing::Size(45, 30);
ok->Location = Point(5, 10);
ok->Click += gcnew EventHandler(this, &Avtos::OK);
f->Controls->Add(ok);
add = gcnew Button();
add->Text = "Add";
add->Size = Drawing::Size(45, 30);
add->Location = Point(5, 50);
add->Click += gcnew EventHandler(this, &Avtos::ADD);
f->Controls->Add(add);
listBoxNum = gcnew ListBox();
listBoxNum->Location = Point(140, 10);
listBoxNum->Size = Drawing::Size(60, 70);
f->Controls->Add(listBoxNum);
del = gcnew Button();
del->Text = "Del";
del->Size = Drawing::Size(40, 30);
del->Location = Point(90, 10);
del->Click += gcnew EventHandler(this, &Avtos::DEL);
f->Controls->Add(del);
}
private:
void OK(Object ^obj, EventArgs ^arg)
{
IEnumerator ^inum = al->GetEnumerator();
while (inum->MoveNext())
{
Avto ^a = (Avto^)inum->Current;
if (run) { a->Suspend(); ok->Text = "Start"; }
else { a->Resume(); ok->Text = "Stop"; }
}
run = !run;
}
public:
void ADD(Object ^obj, EventArgs ^arg)
{
num++;
Avto ^b;
Random ^r = gcnew Random();
//Random rand = new Random();
if (num % 2 == 0)
{
Avto ^a = gcnew Avto(num, 385, 660, r->Next(50, 100));
System::Console::WriteLine("Добавлен автомобиль"+num);
a->dvig = false;
// a.ev += new Del(this.Handlerev);
b = a;
}
else
{
Avto ^a = gcnew Avto(num, 195, 400, r->Next(50, 100));
System::Console::WriteLine("Добавлен автомобиль"+num);
a->dvig = true;
// a.ev += new Del(this.Handlerev);
b = a;
}
listBoxNum->Items->Add(num);
al->Add(b);
IEnumerator ^inum = al->GetEnumerator();
while (inum->MoveNext())
{
Avto ^q = (Avto^)inum->Current;
q->evSpecial += gcnew delEv(this, &Avtos::HandlerEvSpecial);
q->ev += gcnew Del(this, &Avtos::Handlerev);
}
}
private:
void DEL(Object ^o, EventArgs ^e)
{
if (listBoxNum->SelectedIndex == -1)
{
MessageBox::Show("Выделите номер удаляемого объекта");
}
else
{
int numSel = (int)listBoxNum->SelectedItem;
listBoxNum->Items->Remove(numSel);//Удалить из списка
IEnumerator ^inum = al->GetEnumerator();
while (inum->MoveNext())
{
Avto ^a = (Avto^)inum->Current;
if (a->N == numSel)
{//объект с указанным номером найден
a->Finish();//завершить поток
al->Remove(a);//удалить из списка
return;
}
}
}
}
public:
void Handlerev()
{
bool crash = false;
for (int i = 0; i < al->Count; i++)
{
Avto ^a = (Avto^)al[i];
if (a->life)
for (int j = i; j < al->Count; j++)
{
Avto ^a1 = (Avto^)al[j];
if ((a->num != a1->num) && (System::Math::Abs(a1->x - a->x) < 10) && (System::Math::Abs(a1->y - a->y) < 10))
{
System::Console::WriteLine("Автомобили " + a->num + " и " + a1->num + " врезались");
crash = true;
a->run = false;
a1->run = false;
Thread::Sleep(500);
a->run = true;
a1->run = true;
run = true;
if (crash)
{
if ((a->x > a1->x)||(a->y > a1->y))
{
a->x += 2;
a1->x -= 1;
a->y += 2;
a1->y -= 1;
}
else
{
a1->x += 2;
a->x -= 1;
a1->y += 2;
a->y -= 1;
}
System::Console::WriteLine("Автомобили " + a->num + " и " + a1->num + " разъехались");
}
}
}
}
}
public:
void HandlerEvSpecial()
{
Invalidate();
}
protected:
virtual void OnPaint(PaintEventArgs ^arg) override
{
arg->Graphics->FillEllipse(gcnew SolidBrush(Color::Gray), 100, 100, 604, 604);//внешнее кольцо
arg->Graphics->FillEllipse(gcnew SolidBrush(Color::White), 173, 173, 454, 454);//разделительная полоса
arg->Graphics->FillEllipse(gcnew SolidBrush(Color::Gray), 175, 175, 450, 450);//внутреннее кольцо
arg->Graphics->FillEllipse(gcnew SolidBrush(Color::YellowGreen), 245, 245, 300, 300);
this->BackColor = Color::YellowGreen; // Закрасить фон зеленым
this->MaximizeBox = false; // Убрать кнопку "Развернуть окно"
this->DoubleBuffered = true; // Включить буферизацию изображения
IEnumerator ^inum = al->GetEnumerator();
while (inum->MoveNext())
{
Avto ^a = (Avto^)inum->Current;
arg->Graphics->FillEllipse(gcnew SolidBrush(Color::Red), a->X, a->Y, 25, 25);//машина
arg->Graphics->DrawString(a->N.ToString(), gcnew Drawing::Font("Comic Sans MS", 10), gcnew SolidBrush(Color::White), a->X + 5, a->Y + 5);//номера машин
}
}
};
static void main()
{
Application::Run(gcnew Avtos());
}
