import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import java.lang.reflect.*; /** * Fenêtre de dessin * *
Cette classe permet d'écrire des applications graphiques simples * en dessinant dans une fenêtre. * *
NB. Pour toutes les méthodes de dessin, le coin en haut à * gauche de la fenêtre a les coordonnées (0, 0). Le coin en bas à * droite de la fenêtre a les coordonnées (largeur - 1, hauteur - 1), * si la fenêtre est de dimension largeur × hauteur. * *
Un appui sur la touche <Esc> provoque la fermeture de la * fenêtre. Comme pour la plupart des applications, il est également * possible de fermer la fenêtre via le gestionnaire de fenêtres. * *
Télécharger le code: DrawingWindow.java * *
Télécharger des exemples d'utilisation: * Hello.java * Exemple1.java * Exemple2.java * Exemple3.java * * @author Arnaud Giersch <arnaud.giersch@univ-fcomte.fr> * @version 20141008 */ public class DrawingWindow extends JPanel implements KeyListener { /** Titre de la fenêtre */ public final String title; /** Largeur de la fenêtre */ public final int width; /** Hauteur de la fenêtre */ public final int height; /** * Construit une nouvelle fenêtre de dessin avec le titre et les dimensions * passés en paramètres. * * @param title titre de la fenêtre * @param width largeur de la fenêtre * @param height hauteur de la fenêtre * * @see javax.swing.JPanel */ public DrawingWindow(String title, int width, int height) { this.title = new String(title); this.width = width; this.height = height; Dimension dimension = new Dimension(width, height); super.setMinimumSize(dimension); super.setMaximumSize(dimension); super.setPreferredSize(dimension); image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); graphics = image.createGraphics(); setColor(Color.BLACK); setBgColor(Color.WHITE); clearGraph(); try { javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { frame = new JFrame(DrawingWindow.this.title); frame.add(DrawingWindow.this); frame.pack(); frame.setResizable(false); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.addKeyListener(DrawingWindow.this); frame.setLocationByPlatform(true); frame.setVisible(true); } }); } catch (Exception e) { System.err.println("Warning: caught spurious exception: " + e); } sync(); } /** * Change la couleur de dessin. * * @param color couleur * * @see java.awt.Color * @see #setColor(String) * @see #setColor(float, float, float) * @see #setBgColor(Color) */ public void setColor(Color color) { graphics.setColor(color); } /** * Change la couleur de dessin. * * Le nom de couleur est de la forme "black", "white", "red", "blue", ... * * @param name nom de couleur * * @see #setColor(Color) * @see #setColor(float, float, float) * @see #setBgColor(String) */ public void setColor(String name) { try { Field field = Class.forName("java.awt.Color").getField(name); graphics.setColor((Color)field.get(null)); } catch (Exception e) { System.err.println("Warning: color not found: " + name); } } /** * Change la couleur de dessin. * * Les composantes de rouge, vert et bleu de la couleur doivent être * compris entre 0 et 1. Si le trois composantes sont à 0, on obtient * du noir; si les trois composantes sont à 1, on obtient du blanc. * * @param red composante de rouge * @param green composante de vert * @param blue composante de bleu * * @see #setColor(Color) * @see #setColor(String) * @see #setBgColor(float, float, float) */ public void setColor(float red, float green, float blue) { setColor(new Color(red, green, blue)); } /** * Change la couleur de fond. * * @param color couleur * * @see #setBgColor(String) * @see #setBgColor(float, float, float) * @see #setColor(Color) * @see #clearGraph() */ public void setBgColor(Color color) { bgColor = color; } /** * Change la couleur de fond. * * @param name nom de couleur * * @see #setBgColor(Color) * @see #setBgColor(float, float, float) * @see #setColor(String) * @see #clearGraph() */ public void setBgColor(String name) { try { Field field = Class.forName("java.awt.Color").getField(name); bgColor = (Color)field.get(null); } catch (Exception e) { System.err.println("Warning: color not found: " + name); } } /** Change la couleur de fond. * * @param red composante de rouge * @param green composante de vert * @param blue composante de bleu * * @see #setBgColor(Color) * @see #setBgColor(String) * @see #setColor(float, float, float) * @see #clearGraph() */ public void setBgColor(float red, float green, float blue) { bgColor = new Color(red, green, blue); } /** * Efface la fenêtre. * * La fenêtre est effacée avec la couleur de fond courante. * * @see #setBgColor */ public void clearGraph() { synchronized (image) { Color c = graphics.getColor(); graphics.setColor(bgColor); graphics.fillRect(0, 0, width, height); graphics.setColor(c); } repaint(); } /** Dessine un point. * * Dessine un point (pixel) aux coordonnées (x, y), avec la couleur de * dessin courante. * * @see #setColor */ public void drawPoint(int x, int y) { synchronized (image) { image.setRGB(x, y, graphics.getColor().getRGB()); } repaint(x, y, 1, 1); } /** * Dessine un segment. * * Dessine un segement de droite entre les coordonnées (x1, y1) et * (x2, y2), avec la couleur de dessin courante. * * @see #setColor */ public void drawLine(int x1, int y1, int x2, int y2) { synchronized (image) { graphics.drawLine(x1, y1, x2, y2); } repaint(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2) + 1, Math.abs(y1 - y2) + 1); } /** Dessine un rectangle. * * Dessine le rectangle parallèle aux axes et défini par les * coordonnées de deux sommets opposés (x1, y1) et (x2, y2). Utilise * la couleur de dessin courante. * * @see #fillRect * @see #setColor */ public void drawRect(int x1, int y1, int x2, int y2) { int x = Math.min(x1, x2); int y = Math.min(y1, y2); int w = Math.abs(x1 - x2); int h = Math.abs(y1 - y2); synchronized (image) { graphics.drawRect(x, y, w, h); } repaint(x, y, w, h); } /** Dessine un rectangle plein. * * Dessine le rectangle plein parallèle aux axes et défini par les * coordonnées de deux sommets opposés (x1, y1) et (x2, y2). Utilise * la couleur de dessin courante. * * @see #drawRect * @see #setColor */ public void fillRect(int x1, int y1, int x2, int y2) { int x = Math.min(x1, x2); int y = Math.min(y1, y2); int w = Math.abs(x1 - x2); int h = Math.abs(y1 - y2); synchronized (image) { graphics.fillRect(x, y, w, h); } repaint(x, y, w, h); } /** * Dessine un cercle. * * Dessine un cercle de centre (x, y) et de rayon r. Utilise la * couleur de dessin courante. * * @see #fillCircle * @see #setColor */ public void drawCircle(int x, int y, int r) { synchronized (image) { graphics.drawOval(x - r, y - r, 2 * r, 2 * r); } repaint(x - r, y - r, 2 * r, 2 * r); } /** * Dessine un disque. * * Dessine un disque (cercle plein) de centre (x, y) et de rayon r. * Utilise la couleur de dessin courante. * * @see #drawCircle * @see #setColor */ public void fillCircle(int x, int y, int r) { synchronized (image) { graphics.fillOval(x - r, y - r, 2 * r, 2 * r); } repaint(x - r, y - r, 2 * r, 2 * r); } /** * Écrit du texte. * * Écrit le texte text, aux coordonnées (x, y). */ public void drawText(int x, int y, String text) { synchronized (image) { graphics.drawString(text, x, y); } repaint(); // don't know how to calculate tighter bounding box } /** * Retourne la couleur d'un pixel. * * Retourne la couleur du pixel de coordonnées (x, y). * * @return couleur du pixel */ public int getPointColor(int x, int y) { return image.getRGB(x, y); } /** * Synchronise le contenu de la fenêtre. * * Pour des raisons d'efficacités, le résultat des fonctions de dessin * n'est pas affiché immédiatement. L'appel à sync permet de * synchroniser le contenu de la fenêtre. Autrement dit, cela bloque * l'exécution du programme jusqu'à ce que le contenu de la fenêtre * soit à jour. */ public void sync() { // put an empty action on the event queue, and wait for its completion try { javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { } }); } catch (Exception e) { } } /** * Ferme la fenêtre graphique. */ public void closeGraph() { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { WindowEvent ev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING); Toolkit.getDefaultToolkit() .getSystemEventQueue().postEvent(ev); } }); } /** * Suspend l'exécution pendant un certain temps. * * @param secs temps d'attente en seconde */ static void sleep(long secs) { try { Thread.sleep(secs * 1000); } catch (Exception e) { } } /** * Suspend l'exécution pendant un certain temps. * * @param msecs temps d'attente en millisecondes */ static void msleep(long msecs) { try { Thread.sleep(msecs); } catch (Exception e) { } } /** * Suspend l'exécution pendant un certain temps. * * @param usecs temps d'attente en microsecondes */ static void usleep(long usecs) { try { Thread.sleep(usecs / 1000, (int)(usecs % 1000) * 1000); } catch (Exception e) { } } public void paint(Graphics g) { synchronized (image) { g.drawImage(image, 0, 0, null); } } public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { closeGraph(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } /* PRIVATE STUFF FOLLOW */ private static final long serialVersionUID = 0; private JFrame frame; private BufferedImage image; private Graphics2D graphics; private Color bgColor; }