Comme promis, voici le source du programme décrit au TD du vendredi 18 décembre 1998. Vous pouvez récupérer le source dans le fichier archivé=compressé cl.java.tar.gz
Que cela ne vous empêche pas de passer un bon Noël et une bonne année :-)
import java.awt.*;
import java.awt.event.*;
/** ==
Ensemble d'objets
*/
class Ensemble
{
// -- Nombre maximal d'objets
private int max;
// -- Nombre courant d'objets
private int cpt;
// -- Tableau de stockage
private Object t[];
// -- Constructeur
public Ensemble(int n)
{
max = n;
cpt = 0;
t = new Object[n];
}
// -- Lecture du i-eme objet
public Object get(int i)
{
return(t[i]);
}
// -- Ajout d'un objet a l'ensemble
public boolean add(Object o)
{
if (cpt < max) { t[cpt++] = o; return true; }
else return false;
}
// -- Lecture du nombre courant d'objets
public int getcursize() { return cpt; }
// -- Appartenance
public boolean mem(Object o)
{
for(int i=0; i < cpt; i++)
{
if (o==t[i]) return true;
}
return false;
}
}
/** ==
Les points de connexion
*/
class ConnexionPoint
{
// -- Un compteur global :
// chaque point recoit un numero d'ordre de creation
static int N = 0;
// -- Position
int x;
int y;
// -- Numero
int n;
// -- Pour affichage (cf 'paint')
int xs[] = {0,0,0};
int ys[] = {0,0,0};
// -- Constructeurs
ConnexionPoint() { n = ++N; }
ConnexionPoint(int x0, int y0)
{
n = ++N; x = x0; y = y0;
xs[0] = x; xs[1] = x+5; xs[2] = x;
ys[0] = y; ys[1] = y+2; ys[2] = y+5;
}
// -- Mise a jour des positions
void place(int x0, int y0)
{
x = x0; y = y0;
xs[0] = x; xs[1] = x+5; xs[2] = x;
ys[0] = y; ys[1] = y+2; ys[2] = y+5;
}
// -- Effacement
void clear(Graphics g) { g.clearRect(x,y,5,5); }
// -- Affichage
void paint(Graphics g) { g.fillPolygon(xs,ys,3); }
// -- Affichage texte
void print() { System.out.println("ConnexionPoint ["+n+"]("+x+","+y+")"); }
}
/** ==
Les boites de connection
*/
abstract class ConnexionBox
implements MouseListener, MouseMotionListener
{
// -- Position
int x;
int y;
// -- Deplacement demande
int nextX;
int nextY;
// -- Boite active ou non (cf 'paint' et 'place')
boolean selected;
// -- Points d'entree et points de sortie
ConnexionPoint in[];
ConnexionPoint out[];
// -- Deplacement effectif
void place(int x0, int y0) { x = x0; y = y0; }
// -- Effacement
abstract void clear(Graphics g);
// -- Affichage
abstract void paint(Graphics g);
// -- Affichage texte
abstract void print();
// -- Reaction aux evenements souris :
// 'Nop' pour l'instant
public void mousePressed(MouseEvent e) { ; }
public void mouseReleased(MouseEvent e) { ; }
public void mouseClicked(MouseEvent e) { ; }
public void mouseEntered(MouseEvent e) { ; }
public void mouseExited(MouseEvent e) { ; }
public void mouseDragged(MouseEvent e) { ; }
public void mouseMoved(MouseEvent e) { ; }
}
/** ==
Fils de connection
*/
class WireBox extends ConnexionBox
{
// -- Etats du fil
boolean inConnected;
boolean inConnecting;
boolean outConnected;
boolean outConnecting;
// -- Position entree
int inX;
int inY;
// -- Deplacement entree
int nextInX;
int nextInY;
// -- Position sortie
int outX;
int outY;
// -- Deplacement sortie
int nextOutX;
int nextOutY;
// -- Zone de dessin (cf 'mouseReleased')
DesignPanel p;
// -- Constructeur
WireBox(DesignPanel p0)
{
super();
p = p0;
inX = 5;
inY = 5;
outX = 20;
outY = 5;
inConnected = false;
inConnecting = false;
outConnected = false;
outConnecting = false;
selected = false;
in = new ConnexionPoint[] {new ConnexionPoint(inX-2, inY-2)};
out = new ConnexionPoint[] {new ConnexionPoint(outX-2, outY-2)};
}
// -- Deplacement effectif :
// entree ou sortie, suivant l'etat
void place(int x0, int y0)
{
if (inConnecting)
{
inX = x0; inY = y0;
in[0].place(x0-2, y0-2);
}
else if (outConnecting)
{
outX = x0; outY = y0;
out[0].place(x0-2, y0-2);
}
}
// -- Effacement
void clear(Graphics g)
{
g.drawLine(inX,inY,outX,outY);
in[0].paint(g);
out[0].paint(g);
}
// -- Affichage
void paint(Graphics g)
{
if (inConnecting) { place(nextInX, nextInY); }
else if (outConnecting) { place(nextOutX, nextOutY); }
g.drawLine(inX,inY,outX,outY);
in[0].paint(g);
out[0].paint(g);
}
// -- Affichage texte
void print()
{
System.out.println("WireBox :");
in[0].print();
out[0].print();
}
// -- Reaction au bouton presse :
// devient actif ('selected') si l'on designe
// le point d'entree ou le point de sortie
public void mousePressed(MouseEvent e)
{
int xm = e.getX();
int ym = e.getY();
inConnecting =
(!inConnected
&& (inX-5 <= xm && xm <= inX+5) && (inY-5 <= ym && ym <= inY+5));
outConnecting =
(!outConnected
&& (outX-5 <= xm && xm <= outX+5) && (outY-5 <= ym && ym <= outY+5));
selected = inConnecting || outConnecting;
}
// -- Reaction au bouton relache :
// mise a jour du point de sortie ou d'entree
// suivant l'etat
public void mouseReleased(MouseEvent e)
{
if (selected)
{
int xm = e.getX();
int ym = e.getY();
if(inConnecting)
{
ConnexionPoint cp = p.isOutPoint(xm, ym);
if (cp != null)
{
clear(p.getGraphics());
in[0] = cp;
nextInX = cp.x+2;
nextInY = cp.y+2;
paint(p.getGraphics());
inConnecting = false;
}
}
else if (outConnecting)
{
ConnexionPoint cp = p.isInPoint(xm, ym);
if (cp != null)
{
clear(p.getGraphics());
out[0] = cp;
nextOutX = cp.x+2;
nextOutY = cp.y+2;
paint(p.getGraphics());
outConnected = true;
}
}
selected = false;
}
}
// -- Reaction au mouvement de la souris
public void mouseDragged(MouseEvent e)
{
if (selected)
{
if (inConnecting)
{
nextInX = e.getX(); nextInY = e.getY();
}
else if (outConnecting)
{ nextOutX = e.getX(); nextOutY = e.getY(); }
}
}
}
/** ==
Une boite a une entree et une sortie
*/
class NotBox extends ConnexionBox
implements MouseListener, MouseMotionListener
{
// -- Dimension
int w;
int h;
// -- Constructeur
NotBox()
{
super();
w = 20;
h = 15;
x = 5;
y = 5;
nextX = 5;
nextY = 5;
selected = false;
in = new ConnexionPoint[] {new ConnexionPoint()};
out = new ConnexionPoint[] {new ConnexionPoint()};
}
// -- Deplacement effectif
void place(int x0, int y0)
{
super.place(x0, y0);
in[0].place(x, y+5);
out[0].place(x+w, y+5);
}
// -- Effacement
void clear(Graphics g)
{
g.clearRect(x,y,w+1,h+1);
in[0].clear(g);
out[0].clear(g);
}
// -- Affichage
void paint(Graphics g)
{
if (selected) { place(nextX, nextY); }
g.drawRect(x,y,w,h);
in[0].paint(g);
out[0].paint(g);
}
// -- Affichage texte
void print()
{
System.out.print("NotBox ("+x+","+y+") ");
System.out.print("InPoints ");
for(int i=0; i < in.length; i++) in[i].print();
System.out.print(" OutPoints ");
for(int i=0; i < out.length; i++) out[i].print();
}
// -- Reaction au bouton presse :
// devient actif si concerne
public void mousePressed(MouseEvent e)
{
if (!selected)
{
int xm = e.getX();
int ym = e.getY();
selected = ((x <= xm && xm <= x+w) && (y <= ym && ym <= y+h));
}
}
// -- Reaction au bouton relache :
// devient inactif
public void mouseReleased(MouseEvent e)
{
if (selected)
{
selected = false;
}
}
// -- Reaction au mouvement de la souris :
// demande de mouvement si actif
public void mouseDragged(MouseEvent e)
{
if (selected)
{
nextX = e.getX();
nextY = e.getY();
}
}
}
/** ==
La zone de dessin
*/
class DesignPanel extends Panel
{
// -- Ensemble des boites de connection
Ensemble bs;
// -- Ensemble de fils de connection
Ensemble ws;
// -- Constructeur
DesignPanel(int h, int w)
{
super();
setSize(h,w);
setVisible(true);
bs = new Ensemble(25);
ws = new Ensemble(25);
}
// -- Retourne le point de connection designe
// (a peu pres) par 'x' et 'y' si c'est un point
// d'entree, 'null' sinon
ConnexionPoint isInPoint(int x, int y)
{
int i=0;
while(i < bs.getcursize())
{
ConnexionBox b = (ConnexionBox)bs.get(i);
int j=0;
while(j < b.in.length)
{
ConnexionPoint cp = b.in[j];
if ((x-5 <= cp.x && cp.x <= x+5) && (y-5 <= cp.y && cp.y <= y+5))
{ return cp; }
j++;
}
i++;
}
return (ConnexionPoint)null;
}
// -- Retourne le point de connection designe
// (a peu pres) par 'x' et 'y' si c'est un point
// d'entree, 'null' sinon
ConnexionPoint isOutPoint(int x, int y)
{
int i=0;
while(i < bs.getcursize())
{
ConnexionBox b = (ConnexionBox)bs.get(i);
int j=0;
while(j < b.out.length)
{
ConnexionPoint cp = b.out[j];
if ((x-5 <= cp.x && cp.x <= x+5) && (y-5 <= cp.y && cp.y <= y+5))
{ return cp; }
j++;
}
i++;
}
return (ConnexionPoint)null;
}
// -- Ajout d'une nouvelle boite de connection
void addBox(ConnexionBox b)
{
bs.add(b);
addMouseMotionListener(b);
addMouseListener(b);
}
// -- Ajout d'un nouveau fil de connection
void addWire(ConnexionBox b)
{
ws.add(b);
addMouseMotionListener(b);
addMouseListener(b);
}
// -- Effacement d'une boite (ou d'un fil) de connexion
void clearBox(ConnexionBox b)
{
setForeground(getBackground());
b.clear(this.getGraphics());
}
// -- Affichage d'une boite (ou d'un fil) de connexion
void paintBox(ConnexionBox b)
{
setForeground(Color.black);
b.paint(this.getGraphics());
}
// -- Afficahge de l'ensemble des boites et fils de connection
void paintBoxes()
{
for(int i=0; i < bs.getcursize(); i++)
{
ConnexionBox b = (ConnexionBox)bs.get(i);
if (b.selected) clearBox(b);
paintBox(b);
}
for(int i=0; i < ws.getcursize(); i++)
{
ConnexionBox b = (ConnexionBox)ws.get(i);
if (b.selected) clearBox(b);
paintBox(b);
}
}
// -- Affichage general
public void paint(Graphics g)
{
setVisible(true);
paintBoxes();
}
// -- Affichage texte
void print()
{
System.out.println("DesignPanel ");
for(int i=0; i < bs.getcursize(); i++)
{
((ConnexionBox)bs.get(i)).print();
System.out.println();
}
for(int i=0; i < ws.getcursize(); i++)
{
((ConnexionBox)ws.get(i)).print();
System.out.println();
}
}
}
/** ==
Gestionnaire d'evenements pour la zone de dessin :
appelle la methode 'paint' sur les evenements auxquels
reagissent les boites de connexion
*/
class panelMouseAdapter implements MouseListener, MouseMotionListener
{
// -- La zone de dessin
DesignPanel p;
// -- Constructeur
panelMouseAdapter(DesignPanel p0) { p = p0; }
// -- Reactions au evenements souris
public void mousePressed(MouseEvent e) { p.paint(p.getGraphics()); }
public void mouseReleased(MouseEvent e) { p.paint(p.getGraphics()); }
public void mouseClicked(MouseEvent e) { ; }
public void mouseEntered(MouseEvent e) { ; }
public void mouseExited(MouseEvent e) { ; }
public void mouseDragged(MouseEvent e) { p.paint(p.getGraphics()); }
public void mouseMoved(MouseEvent e) { ; }
}
/** ==
Classe pincipale
*/
class cl2
{
// -- La zone de dessin
static DesignPanel p = new DesignPanel(200,200);
// -- Le delegue pour la zone de dessin
static panelMouseAdapter a = new panelMouseAdapter(p);
// La fentre principale
static Frame f = new Frame("Titre");
// -- Stop ou encore ?
static boolean stop = false;
// -- *LA* methode
public static void main(String args[])
{
// -- Fenetre principale
f.setSize(300,300);
f.setLayout(new BorderLayout(2,2));
f.show();
// -- Zone de dessin
p.addMouseListener(a);
p.addMouseMotionListener(a);
f.add("Center",p);
// -- Zone des boutons
// Bouton "box" : creation d'une boite
Button boxb = new Button("box");
boxb.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
NotBox b = new NotBox();
p.addBox((ConnexionBox)b);
b.selected = true;
p.paintBox((ConnexionBox)b);
b.selected = false;
}
});
// Bouton "connect" : creation d'un fil
Button conb = new Button("connect");
conb.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
WireBox b = new WireBox(p);
p.addWire((ConnexionBox)b);
//b.selected = true;
p.paintBox((ConnexionBox)b);
b.selected = false;
}
});
// Bouton "print" : affichage texte
Button printb = new Button("print");
printb.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
p.print();
}
});
// Zone des boutons : initialisations
Panel bp = new Panel();
bp.setLayout(new GridLayout());
bp.add(boxb);
bp.add(conb);
bp.add(printb);
f.add("South",bp);
// Affichage du tout
f.paintAll(f.getGraphics());
}
}