package BallsCj5;
////////////////////
//C# File BallsCj5
import java.util.*;
import java.awt.*;
import java.awt.event.*;
class Obs
{
public int num, n;
public Obs (int num, int n)
{this.num= num; this.n= n;}
int getNumber(){return num;}
int getN(){return n;}
}
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) dx= -dx;
if (y>h || y<0) dy= -dy;
// Уведомить
setChanged();
notifyObservers(new Obs(num, n));
try
{
Thread.sleep (100);
synchronized(this)
{
if(waiting)
wait();
}
}
catch(InterruptedException iE){}
}
System.out.print("object "+num);
System.out.println(" finished ");
}
}
//-------------------------------------
class Balls extends Frame implements Observer // Класс объектов
{
Ball [] pBall;
Color col;
public Balls ( )
{
this.setTitle("Balls");
this.setSize(400, 300);
col= Color.red;
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);
}
this.show();
Start ( );
}
//---------------
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;
System.out.print("object num= "+ obs.num);
System.out.println(" n= "+ obs.n);
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;
}
}
}
class User extends Balls // Класс пользователя шаров
{
private boolean run;
Frame pChildForm;
Button pBut;
public User ( )
{
run= true;
//---------------
this.setLayout(null);
pBut= new Button("OK");
pBut.setLocation(60, 60);
pBut.setSize (32, 24);
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.add(pBut);
this.show();
}
//-------------------------
public static void main ( )
{
User u= new User();
}
}
/*
Результат:
Появились прикладное окно с перемещающимися шарами и дочернее окно
с кнопкой. При нажатии на кнопку можно приостанавливать или возобновлять
движение шаров.
*/
5.3.6. Этап 6. Добавление элемента списка
Этот этап предпоследний. Добавим в дочернее окно управляющий элемент-список для выбора одного из трёх цветов шаров. Диаграмма классов и реализация последнего этапа представлены на рис. 4.3.6.1 и в примерах 4.3.6.1 и 4.3.6.2.
Рис. 5.3.6.1. Диаграмма классов Balls–приложения шестого этапа
Пример 5.3.6.1. Реализация шестого этапа разработки Balls–приложения.
////////////////////
// C# File BallsCs6.cs
// Файл BallsCs6.cs полностью включает файл BallsCs5.cs, дополнив класс
// User элементом списка и включив его в дочернее окно. Используя список,
// можно изменить цвет шаров.
// Изменения файла BallsCs5.cs выделены жирным шрифтом
. . .
//-------------------------------------
class Balls : Form // Класс объектов
{
Ball [] pBall;
Color col;
. . .
public void SetColor (Color Col) // Установить цвет
{
col= Col;
Invalidate ( );
}
. . .
}
//-------------------------------------
class User : Balls // Класс пользователя шаров
{
. . .
Color col;
ListBox pListBox;
public User ( ) // Конструктор
{
. . .
pListBox= new ListBox ( );
pBut.MouseDown += new MouseEventHandler (OnBut);
pListBox.Items.Add ("red");
pListBox.Items.Add ("green");
pListBox.Items.Add ("blue");
pListBox.Location = new Point (104, 24);
pListBox.Name = "listBox";
pListBox.Size = new System.Drawing.Size (56, 17); pListBox.SelectedIndexChanged += new
System.EventHandler (SelectedItem); pChildForm.Controls.Add (pListBox);
}
. . .
void SelectedItem (object obj, EventArgs arg)
{
Console.WriteLine ("OkList");
if(pListBox.GetSelected (0))
col= Color.Red;
if(pListBox.GetSelected (1))
col= Color.Green;
if(pListBox.GetSelected (2))
col=Color.Blue;
SetColor (col);
}
. . .
}
/*
Результат:
Появились прикладное окно с перемещающимися шарами и дочернее окно
с кнопкой и со списком. При нажатии на кнопку можно приостанавливать
или возобновлять движение шаров. Используя список, можно изменить цвет
шаров.
*/
Рис. 5.3.6.1. Прикладное и дочернее окна Balls–приложения 6 этапа
Пример 5.3.6.2. Реализация шестого этапа разработки Balls–приложения на языке Java.
package BallsCj6;
////////////////////
//C# File BallsCj6
import java.util.*;
import java.awt.*;
import java.awt.event.*;
//import java.awt.event.ActionListener;
class Obs
{
public int num, n;
public Obs (int num, int n)
{this.num= num; this.n= n;}
int getNumber(){return num;}
int getN(){return n;}
}
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) dx= -dx;
if (y>h || y<0) dy= -dy;
// Уведомить
setChanged();
notifyObservers(new Obs(num, n));
try
{
Thread.sleep (100);
synchronized(this)
{
if(waiting)
wait();
}
}
catch(InterruptedException iE){}
}
System.out.print("object "+num);
System.out.println(" finished ");
}
}
//-------------------------------------
class Balls extends Frame implements Observer // Класс объектов
{
Ball [] pBall;
Color col;
public Balls ( )
{
this.setTitle("Balls");
this.setSize(400, 300);
col= Color.red;
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);
}
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;
System.out.print("object num= "+ obs.num);
System.out.println(" n= "+ obs.n);
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;
}
}
}
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();
}
}
/*
Результат:
Появились прикладное окно с перемещающимися шарами и дочернее окно
с кнопкой и элементом списка. При нажатии на кнопку можно приостанавливать или возобновлять
движение шаров. Выделив в списке цвет, можно изменить цвет шаров.
*/
5.3.7. Этап 7. Разработка специального объекта
В последнем этапе разработаем класс SpecialBall специального объекта, добавим его объект в класс, содержащий массив обычных объектов. В соответствии с заданием этот специальный объект должен быть представлен в виде желтой окружности в левом верхнем углу прикладного окна, и эта оеружность вспыхивает (увеличивается ширина круга) при отталкивании шаров от стенок прикладного окна. Создадим специальный объект в теле конструктора класса Balls, подписав событие или уведомление каждого обычного объекта с обработчиком этого специального объекта. Добавим в дочернее окно управляющий элемент-список для выбора одного из трёх цветов шаров. Диаграмма классов и реализация последнего этапа представлены на рис. 5.3.7.1 и в примерах 5.3.7.1 и 5.3.7.2.