Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Complete list of color names.
[graphlib_java.git] / DrawingWindow.java
1 import java.awt.*;
2 import java.awt.event.*;
3 import java.awt.image.*;
4 import javax.swing.*;
5 import java.util.*;
6
7 /**
8  * Fenêtre de dessin
9  *
10  * <p>Cette classe permet d'écrire des applications graphiques simples
11  * en dessinant dans une fenêtre.
12  *
13  * <p><b>NB.</b> Pour toutes les méthodes de dessin, le coin en haut à
14  * gauche de la fenêtre a les coordonnées (0, 0).  Le coin en bas à
15  * droite de la fenêtre a les coordonnées (largeur - 1, hauteur - 1),
16  * si la fenêtre est de dimension largeur × hauteur.
17  *
18  * <p>Un appui sur la touche &lt;Esc&gt; provoque la fermeture de la
19  * fenêtre.  Comme pour la plupart des applications, il est également
20  * possible de fermer la fenêtre via le gestionnaire de fenêtres.
21  *
22  * @author Arnaud Giersch &lt;arnaud.giersch@univ-fcomte.fr&gt;
23  * @version 20141014
24  */
25 public class DrawingWindow {
26
27     /** Largeur de la fenêtre */
28     public final int width;
29
30     /** Hauteur de la fenêtre */
31     public final int height;
32
33     /**
34      * Construit une nouvelle fenêtre de dessin avec le titre et les dimensions
35      * passés en paramètres.
36      *
37      * @param title             titre de la fenêtre
38      * @param width             largeur de la fenêtre
39      * @param height            hauteur de la fenêtre
40      *
41      * @see javax.swing.JPanel
42      */
43     public DrawingWindow(String title, int width, int height) {
44
45         this.title = new String(title);
46         this.width = width;
47         this.height = height;
48
49         image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
50         graphics = image.createGraphics();
51
52         try {
53             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
54                     public void run() { createGUI(); }
55                 });
56         }
57         catch (Exception e) {
58             System.err.println("Error: interrupted while creating GUI");
59             System.err.println("Got exception: " + e);
60             System.exit(1);
61         }
62
63         setColor(Color.BLACK);
64         setBgColor(Color.WHITE);
65         clearGraph();
66         sync();
67     }
68
69     /**
70      * Change la couleur de dessin.
71      *
72      * @param color         couleur
73      *
74      * @see java.awt.Color
75      * @see #setColor(int)
76      * @see #setColor(String)
77      * @see #setColor(float, float, float)
78      * @see #setBgColor(Color)
79      */
80     public void setColor(Color color) {
81         graphics.setColor(color);
82     }
83
84     /**
85      * Change la couleur de dessin.
86      *
87      * La couleur est un entier, tel que retourné par {@link #getPointColor}.
88      * Normalement de la forme #00RRGGBB.
89      *
90      * @param rgb       couleur
91      *
92      * @see #setColor(String)
93      * @see #setColor(float, float, float)
94      * @see #setBgColor(int)
95      * @see #getPointColor
96      */
97     public void setColor(int rgb) {
98         setColor(new Color(rgb));
99     }
100
101     /**
102      * Change la couleur de dessin.
103      *
104      * @param name          nom de couleur
105      *
106      * @see #setColor(int)
107      * @see #setColor(float, float, float)
108      * @see #setBgColor(String)
109      * @see <a href="http://www.w3.org/TR/SVG/types.html#ColorKeywords">liste des noms de couleurs</a>
110      */
111     public void setColor(String name) {
112         Color color = colorMap.get(name);
113         if (color != null)
114             setColor(color);
115         else
116             System.err.println("Warning: color not found: " + name);
117     }
118
119     /**
120      * Change la couleur de dessin.
121      *
122      * Les composantes de rouge, vert et bleu de la couleur doivent être
123      * compris entre 0 et 1.  Si le trois composantes sont à 0, on obtient
124      * du noir; si les trois composantes sont à 1, on obtient du blanc.
125      *
126      * @param red           composante de rouge
127      * @param green         composante de vert
128      * @param blue          composante de bleu
129      *
130      * @see #setColor(int)
131      * @see #setColor(String)
132      * @see #setBgColor(float, float, float)
133      */
134     public void setColor(float red, float green, float blue) {
135         setColor(new Color(red, green, blue));
136     }
137
138     /**
139      * Change la couleur de fond.
140      *
141      * @param color         couleur
142      *
143      * @see #setBgColor(int)
144      * @see #setBgColor(String)
145      * @see #setBgColor(float, float, float)
146      * @see #setColor(Color)
147      * @see #clearGraph()
148      */
149     public void setBgColor(Color color) {
150         bgColor = color;
151     }
152
153     /** Change la couleur de fond.
154      *
155      * @param rgb       couleur
156      *
157      * @see #setBgColor(String)
158      * @see #setBgColor(float, float, float)
159      * @see #setColor(int)
160      * @see #getPointColor
161      * @see #clearGraph()
162      */
163     public void setBgColor(int rgb) {
164         setBgColor(new Color(rgb));
165     }
166
167     /**
168      * Change la couleur de fond.
169      *
170      * @param name          nom de couleur
171      *
172      * @see #setBgColor(int)
173      * @see #setBgColor(float, float, float)
174      * @see #setColor(String)
175      * @see #clearGraph()
176      * @see <a href="http://www.w3.org/TR/SVG/types.html#ColorKeywords">liste des noms de couleurs</a>
177      */
178     public void setBgColor(String name) {
179         Color color = colorMap.get(name);
180         if (color != null)
181             setBgColor(color);
182         else
183             System.err.println("Warning: color not found: " + name);
184     }
185
186     /** Change la couleur de fond.
187      *
188      * @param red           composante de rouge
189      * @param green         composante de vert
190      * @param blue          composante de bleu
191      *
192      * @see #setBgColor(int)
193      * @see #setBgColor(String)
194      * @see #setColor(float, float, float)
195      * @see #clearGraph()
196      */
197     public void setBgColor(float red, float green, float blue) {
198         setBgColor(new Color(red, green, blue));
199     }
200
201     /**
202      * Efface la fenêtre.
203      *
204      * La fenêtre est effacée avec la couleur de fond courante.
205      *
206      * @see #setBgColor
207      */
208     public void clearGraph() {
209         synchronized (image) {
210             Color c = graphics.getColor();
211             graphics.setColor(bgColor);
212             graphics.fillRect(0, 0, width, height);
213             graphics.setColor(c);
214         }
215         panel.repaint();
216     }
217
218     /** Dessine un point.
219      *
220      * Dessine un point (pixel) aux coordonnées (x, y), avec la couleur de
221      * dessin courante.
222      *
223      * @see #setColor
224      */
225     public void drawPoint(int x, int y) {
226         synchronized (image) {
227             image.setRGB(x, y, graphics.getColor().getRGB());
228         }
229         panel.repaint(x, y, 1, 1);
230     }
231
232     /**
233      * Dessine un segment.
234      *
235      * Dessine un segement de droite entre les coordonnées (x1, y1) et
236      * (x2, y2), avec la couleur de dessin courante.
237      *
238      * @see #setColor
239      */
240     public void drawLine(int x1, int y1, int x2, int y2) {
241         synchronized (image) {
242             graphics.drawLine(x1, y1, x2, y2);
243         }
244         panel.repaint(Math.min(x1, x2), Math.min(y1, y2),
245                       Math.abs(x1 - x2) + 1, Math.abs(y1 - y2) + 1);
246     }
247
248     /** Dessine un rectangle.
249      *
250      * Dessine le rectangle parallèle aux axes et défini par les
251      * coordonnées de deux sommets opposés (x1, y1) et (x2, y2).  Utilise
252      * la couleur de dessin courante.
253      *
254      * @see #fillRect
255      * @see #setColor
256      */
257     public void drawRect(int x1, int y1, int x2, int y2) {
258         int x = Math.min(x1, x2);
259         int y = Math.min(y1, y2);
260         int w = Math.abs(x1 - x2);
261         int h = Math.abs(y1 - y2);
262         synchronized (image) {
263             graphics.drawRect(x, y, w, h);
264         }
265         panel.repaint(x, y, w + 1, h + 1);
266     }
267
268     /** Dessine un rectangle plein.
269      *
270      * Dessine le rectangle plein parallèle aux axes et défini par les
271      * coordonnées de deux sommets opposés (x1, y1) et (x2, y2).  Utilise
272      * la couleur de dessin courante.
273      *
274      * @see #drawRect
275      * @see #setColor
276      */
277     public void fillRect(int x1, int y1, int x2, int y2) {
278         int x = Math.min(x1, x2);
279         int y = Math.min(y1, y2);
280         int w = Math.abs(x1 - x2) + 1;
281         int h = Math.abs(y1 - y2) + 1;
282         synchronized (image) {
283             graphics.fillRect(x, y, w, h);
284         }
285         panel.repaint(x, y, w, h);
286     }
287
288     /**
289      * Dessine un cercle.
290      *
291      * Dessine un cercle de centre (x, y) et de rayon r.  Utilise la
292      * couleur de dessin courante.
293      *
294      * @see #fillCircle
295      * @see #setColor
296      */
297     public void drawCircle(int x, int y, int r) {
298         synchronized (image) {
299             graphics.drawOval(x - r, y - r, 2 * r, 2 * r);
300         }
301         panel.repaint(x - r, y - r, 2 * r + 1, 2 * r + 1);
302     }
303
304     /**
305      * Dessine un disque.
306      *
307      * Dessine un disque (cercle plein) de centre (x, y) et de rayon r.
308      * Utilise la couleur de dessin courante.
309      *
310      * @see #drawCircle
311      * @see #setColor
312      */
313     public void fillCircle(int x, int y, int r) {
314         synchronized (image) {
315             graphics.drawOval(x - r, y - r, 2 * r, 2 * r);
316             graphics.fillOval(x - r, y - r, 2 * r, 2 * r);
317         }
318         panel.repaint(x - r, y - r, 2 * r + 1, 2 * r + 1);
319     }
320
321     /**
322      * Dessine un triangle.
323      *
324      * Dessine un triangle défini par les coordonnées de ses sommets:
325      * (x1, y1), (x2, y2) et (x3, y3).  Utilise la couleur de dessin
326      * courante.
327      *
328      * @see #fillTriangle
329      * @see #setColor
330      */
331
332     public void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
333         Polygon poly = new Polygon();
334         poly.addPoint(x1, y1);
335         poly.addPoint(x2, y2);
336         poly.addPoint(x3, y3);
337         synchronized (image) {
338             graphics.drawPolygon(poly);
339         }
340         panel.repaint(poly.getBounds());
341     }
342
343     /**
344      * Dessine un triangle plein.
345      *
346      * Dessine un triangle plein défini par les coordonnées de ses
347      * sommets: (x1, y1), (x2, y2) et (x3, y3).  Utilise la couleur de
348      * dessin courante.
349      *
350      * @see #drawTriangle
351      * @see #setColor
352      */
353     public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
354         Polygon poly = new Polygon();
355         poly.addPoint(x1, y1);
356         poly.addPoint(x2, y2);
357         poly.addPoint(x3, y3);
358         synchronized (image) {
359             graphics.drawPolygon(poly);
360             graphics.fillPolygon(poly);
361         }
362         panel.repaint(poly.getBounds());
363     }
364
365     /**
366      * Écrit du texte.
367      *
368      * Écrit le texte text, aux coordonnées (x, y).
369      */
370     public void drawText(int x, int y, String text) {
371         synchronized (image) {
372             graphics.drawString(text, x, y);
373         }
374         panel.repaint(); // don't know how to calculate tighter bounding box
375     }
376
377     /**
378      * Retourne la couleur d'un pixel.
379      *
380      * Retourne la couleur du pixel de coordonnées (x, y).
381      *
382      * @return              couleur du pixel
383      *
384      * @see #setColor(int)
385      * @see #setBgColor(int)
386      */
387     public int getPointColor(int x, int y) {
388         return image.getRGB(x, y);
389     }
390
391     /**
392      * Synchronise le contenu de la fenêtre.
393      *
394      * Pour des raisons d'efficacités, le résultat des fonctions de dessin
395      * n'est pas affiché immédiatement.  L'appel à sync permet de
396      * synchroniser le contenu de la fenêtre.  Autrement dit, cela bloque
397      * l'exécution du programme jusqu'à ce que le contenu de la fenêtre
398      * soit à jour.
399      */
400     public void sync() {
401         // put an empty action on the event queue, and  wait for its completion
402         try {
403             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
404                     public void run() { }
405                 });
406         }
407         catch (Exception e) {
408         }
409     }
410
411     /**
412      *  Ferme la fenêtre graphique.
413      */
414     public void closeGraph() {
415         javax.swing.SwingUtilities.invokeLater(new Runnable() {
416                 public void run() {
417                     WindowEvent ev =
418                         new WindowEvent(frame,
419                                         WindowEvent.WINDOW_CLOSING);
420                     Toolkit.getDefaultToolkit()
421                         .getSystemEventQueue().postEvent(ev);
422                 }
423             });
424     }
425
426
427     /**
428      * Suspend l'exécution pendant un certain temps.
429      *
430      * @param secs          temps d'attente en seconde
431      */
432     static void sleep(long secs) {
433         try {
434             Thread.sleep(secs * 1000);
435         }
436         catch (Exception e) {
437         }
438     }
439
440     /**
441      * Suspend l'exécution pendant un certain temps.
442      *
443      * @param msecs          temps d'attente en millisecondes
444      */
445     static void msleep(long msecs) {
446         try {
447             Thread.sleep(msecs);
448         }
449         catch (Exception e) {
450         }
451     }
452
453     /**
454      * Suspend l'exécution pendant un certain temps.
455      *
456      * @param usecs          temps d'attente en microsecondes
457      */
458     static void usleep(long usecs) {
459         try {
460             Thread.sleep(usecs / 1000, (int)(usecs % 1000) * 1000);
461         }
462         catch (Exception e) {
463         }
464     }
465
466     /* PRIVATE STUFF FOLLOWS */
467
468     private static final Map<String, Color> colorMap;
469
470     static {
471         Map<String, Color> m = new HashMap<String, Color>();
472         // From http://www.w3.org/TR/SVG/types.html#ColorKeywords
473         m.put("aliceblue",              new Color(0x00f0f8ff));
474         m.put("antiquewhite",           new Color(0x00faebd7));
475         m.put("aqua",                   new Color(0x0000ffff));
476         m.put("aquamarine",             new Color(0x007fffd4));
477         m.put("azure",                  new Color(0x00f0ffff));
478         m.put("beige",                  new Color(0x00f5f5dc));
479         m.put("bisque",                 new Color(0x00ffe4c4));
480         m.put("black",                  new Color(0000000000));
481         m.put("blanchedalmond",         new Color(0x00ffebcd));
482         m.put("blue",                   new Color(0x000000ff));
483         m.put("blueviolet",             new Color(0x008a2be2));
484         m.put("brown",                  new Color(0x00a52a2a));
485         m.put("burlywood",              new Color(0x00deb887));
486         m.put("cadetblue",              new Color(0x005f9ea0));
487         m.put("chartreuse",             new Color(0x007fff00));
488         m.put("chocolate",              new Color(0x00d2691e));
489         m.put("coral",                  new Color(0x00ff7f50));
490         m.put("cornflowerblue",         new Color(0x006495ed));
491         m.put("cornsilk",               new Color(0x00fff8dc));
492         m.put("crimson",                new Color(0x00dc143c));
493         m.put("cyan",                   new Color(0x0000ffff));
494         m.put("darkblue",               new Color(0x0000008b));
495         m.put("darkcyan",               new Color(0x00008b8b));
496         m.put("darkgoldenrod",          new Color(0x00b8860b));
497         m.put("darkgray",               new Color(0x00a9a9a9));
498         m.put("darkgreen",              new Color(0x00006400));
499         m.put("darkgrey",               new Color(0x00a9a9a9));
500         m.put("darkkhaki",              new Color(0x00bdb76b));
501         m.put("darkmagenta",            new Color(0x008b008b));
502         m.put("darkolivegreen",         new Color(0x00556b2f));
503         m.put("darkorange",             new Color(0x00ff8c00));
504         m.put("darkorchid",             new Color(0x009932cc));
505         m.put("darkred",                new Color(0x008b0000));
506         m.put("darksalmon",             new Color(0x00e9967a));
507         m.put("darkseagreen",           new Color(0x008fbc8f));
508         m.put("darkslateblue",          new Color(0x00483d8b));
509         m.put("darkslategray",          new Color(0x002f4f4f));
510         m.put("darkslategrey",          new Color(0x002f4f4f));
511         m.put("darkturquoise",          new Color(0x0000ced1));
512         m.put("darkviolet",             new Color(0x009400d3));
513         m.put("deeppink",               new Color(0x00ff1493));
514         m.put("deepskyblue",            new Color(0x0000bfff));
515         m.put("dimgray",                new Color(0x00696969));
516         m.put("dimgrey",                new Color(0x00696969));
517         m.put("dodgerblue",             new Color(0x001e90ff));
518         m.put("firebrick",              new Color(0x00b22222));
519         m.put("floralwhite",            new Color(0x00fffaf0));
520         m.put("forestgreen",            new Color(0x00228b22));
521         m.put("fuchsia",                new Color(0x00ff00ff));
522         m.put("gainsboro",              new Color(0x00dcdcdc));
523         m.put("ghostwhite",             new Color(0x00f8f8ff));
524         m.put("gold",                   new Color(0x00ffd700));
525         m.put("goldenrod",              new Color(0x00daa520));
526         m.put("gray",                   new Color(0x00808080));
527         m.put("grey",                   new Color(0x00808080));
528         m.put("green",                  new Color(0x00008000));
529         m.put("greenyellow",            new Color(0x00adff2f));
530         m.put("honeydew",               new Color(0x00f0fff0));
531         m.put("hotpink",                new Color(0x00ff69b4));
532         m.put("indianred",              new Color(0x00cd5c5c));
533         m.put("indigo",                 new Color(0x004b0082));
534         m.put("ivory",                  new Color(0x00fffff0));
535         m.put("khaki",                  new Color(0x00f0e68c));
536         m.put("lavender",               new Color(0x00e6e6fa));
537         m.put("lavenderblush",          new Color(0x00fff0f5));
538         m.put("lawngreen",              new Color(0x007cfc00));
539         m.put("lemonchiffon",           new Color(0x00fffacd));
540         m.put("lightblue",              new Color(0x00add8e6));
541         m.put("lightcoral",             new Color(0x00f08080));
542         m.put("lightcyan",              new Color(0x00e0ffff));
543         m.put("lightgoldenrodyellow",   new Color(0x00fafad2));
544         m.put("lightgray",              new Color(0x00d3d3d3));
545         m.put("lightgreen",             new Color(0x0090ee90));
546         m.put("lightgrey",              new Color(0x00d3d3d3));
547         m.put("",                       new Color(0000000000));
548         m.put("lightpink",              new Color(0x00ffb6c1));
549         m.put("lightsalmon",            new Color(0x00ffa07a));
550         m.put("lightseagreen",          new Color(0x0020b2aa));
551         m.put("lightskyblue",           new Color(0x0087cefa));
552         m.put("lightslategray",         new Color(0x00778899));
553         m.put("lightslategrey",         new Color(0x00778899));
554         m.put("lightsteelblue",         new Color(0x00b0c4de));
555         m.put("lightyellow",            new Color(0x00ffffe0));
556         m.put("lime",                   new Color(0x0000ff00));
557         m.put("limegreen",              new Color(0x0032cd32));
558         m.put("linen",                  new Color(0x00faf0e6));
559         m.put("magenta",                new Color(0x00ff00ff));
560         m.put("maroon",                 new Color(0x00800000));
561         m.put("mediumaquamarine",       new Color(0x0066cdaa));
562         m.put("mediumblue",             new Color(0x000000cd));
563         m.put("mediumorchid",           new Color(0x00ba55d3));
564         m.put("mediumpurple",           new Color(0x009370db));
565         m.put("mediumseagreen",         new Color(0x003cb371));
566         m.put("mediumslateblue",        new Color(0x007b68ee));
567         m.put("mediumspringgreen",      new Color(0x0000fa9a));
568         m.put("mediumturquoise",        new Color(0x0048d1cc));
569         m.put("mediumvioletred",        new Color(0x00c71585));
570         m.put("midnightblue",           new Color(0x00191970));
571         m.put("mintcream",              new Color(0x00f5fffa));
572         m.put("mistyrose",              new Color(0x00ffe4e1));
573         m.put("moccasin",               new Color(0x00ffe4b5));
574         m.put("navajowhite",            new Color(0x00ffdead));
575         m.put("navy",                   new Color(0x00000080));
576         m.put("oldlace",                new Color(0x00fdf5e6));
577         m.put("olive",                  new Color(0x00808000));
578         m.put("olivedrab",              new Color(0x006b8e23));
579         m.put("orange",                 new Color(0x00ffa500));
580         m.put("orangered",              new Color(0x00ff4500));
581         m.put("orchid",                 new Color(0x00da70d6));
582         m.put("palegoldenrod",          new Color(0x00eee8aa));
583         m.put("palegreen",              new Color(0x0098fb98));
584         m.put("paleturquoise",          new Color(0x00afeeee));
585         m.put("palevioletred",          new Color(0x00db7093));
586         m.put("papayawhip",             new Color(0x00ffefd5));
587         m.put("peachpuff",              new Color(0x00ffdab9));
588         m.put("peru",                   new Color(0x00cd853f));
589         m.put("pink",                   new Color(0x00ffc0cb));
590         m.put("plum",                   new Color(0x00dda0dd));
591         m.put("powderblue",             new Color(0x00b0e0e6));
592         m.put("purple",                 new Color(0x00800080));
593         m.put("red",                    new Color(0x00ff0000));
594         m.put("rosybrown",              new Color(0x00bc8f8f));
595         m.put("royalblue",              new Color(0x004169e1));
596         m.put("saddlebrown",            new Color(0x008b4513));
597         m.put("salmon",                 new Color(0x00fa8072));
598         m.put("sandybrown",             new Color(0x00f4a460));
599         m.put("seagreen",               new Color(0x002e8b57));
600         m.put("seashell",               new Color(0x00fff5ee));
601         m.put("sienna",                 new Color(0x00a0522d));
602         m.put("silver",                 new Color(0x00c0c0c0));
603         m.put("skyblue",                new Color(0x0087ceeb));
604         m.put("slateblue",              new Color(0x006a5acd));
605         m.put("slategray",              new Color(0x00708090));
606         m.put("slategrey",              new Color(0x00708090));
607         m.put("snow",                   new Color(0x00fffafa));
608         m.put("springgreen",            new Color(0x0000ff7f));
609         m.put("steelblue",              new Color(0x004682b4));
610         m.put("tan",                    new Color(0x00d2b48c));
611         m.put("teal",                   new Color(0x00008080));
612         m.put("thistle",                new Color(0x00d8bfd8));
613         m.put("tomato",                 new Color(0x00ff6347));
614         m.put("turquoise",              new Color(0x0040e0d0));
615         m.put("violet",                 new Color(0x00ee82ee));
616         m.put("wheat",                  new Color(0x00f5deb3));
617         m.put("white",                  new Color(0x00ffffff));
618         m.put("whitesmoke",             new Color(0x00f5f5f5));
619         m.put("yellow",                 new Color(0x00ffff00));
620         m.put("yellowgreen",            new Color(0x009acd32));
621         colorMap = Collections.unmodifiableMap(m);
622     }
623
624     private final String title; // window's title
625     private JFrame frame;       // the frame (window)
626     private DWPanel panel;      // the panel showing the image
627     private BufferedImage image; // the image we draw into
628     private Graphics2D graphics; // graphics associated with image
629     private Color bgColor;       // background color, for clearGraph()
630
631     // To be run on the Event Dispatching Thread
632     void createGUI() {
633         panel = new DWPanel(this);
634
635         frame = new JFrame(title);
636         frame.add(panel);
637         frame.pack();
638         frame.setResizable(false);
639         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
640         frame.addKeyListener(panel);
641         frame.setLocationByPlatform(true);
642         frame.setVisible(true);
643     }
644
645     private class DWPanel extends JPanel implements KeyListener {
646
647         private static final long serialVersionUID = 0;
648
649         final DrawingWindow w;
650
651         DWPanel(DrawingWindow w) {
652             this.w = w;
653             Dimension dimension = new Dimension(w.width, w.height);
654             super.setMinimumSize(dimension);
655             super.setMaximumSize(dimension);
656             super.setPreferredSize(dimension);
657         }
658
659         public void paint(Graphics g) {
660             synchronized (w.image) {
661                 g.drawImage(w.image, 0, 0, null);
662             }
663         }
664
665         public void keyPressed(KeyEvent e) {
666             if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
667                 w.closeGraph();
668             }
669         }
670
671         public void keyReleased(KeyEvent e) { }
672         public void keyTyped(KeyEvent e) { }
673
674     }
675 }