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()); } }