-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import javax.swing.*;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Toolkit;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.image.BufferedImage;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
/**
* Fenêtre de dessin
* possible de fermer la fenêtre via le gestionnaire de fenêtres.
*
* @author Arnaud Giersch <arnaud.giersch@univ-fcomte.fr>
- * @version 20141014
+ * @version 20141021b
*/
public class DrawingWindow {
this.width = width;
this.height = height;
+ mouseLock = new Object();
+ mouseEvent = null;
+ mousePos = new Point(0, 0);
+ mouseButton = 0;
+
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
graphics = image.createGraphics();
* @see #setBgColor(String)
* @see #setBgColor(float, float, float)
* @see #setColor(Color)
- * @see #clearGraph()
+ * @see #clearGraph
*/
public void setBgColor(Color color) {
bgColor = color;
* @see #setBgColor(float, float, float)
* @see #setColor(int)
* @see #getPointColor
- * @see #clearGraph()
+ * @see #clearGraph
*/
public void setBgColor(int rgb) {
setBgColor(new Color(rgb));
* @see #setBgColor(int)
* @see #setBgColor(float, float, float)
* @see #setColor(String)
- * @see #clearGraph()
+ * @see #clearGraph
* @see <a href="http://www.w3.org/TR/SVG/types.html#ColorKeywords">liste des noms de couleurs</a>
*/
public void setBgColor(String name) {
* @see #setBgColor(int)
* @see #setBgColor(String)
* @see #setColor(float, float, float)
- * @see #clearGraph()
+ * @see #clearGraph
*/
public void setBgColor(float red, float green, float blue) {
setBgColor(new Color(red, green, blue));
* @see #setColor
*/
public void drawPoint(int x, int y) {
+ if (x < 0 || y < 0 || x >= width || y >= height)
+ return;
synchronized (image) {
image.setRGB(x, y, graphics.getColor().getRGB());
}
* @see #setBgColor(int)
*/
public int getPointColor(int x, int y) {
- return image.getRGB(x, y);
+ return (x < 0 || y < 0 || x >= width || y >= height) ?
+ 0 : image.getRGB(x, y) & 0x00ffffff;
+ }
+
+ /**
+ * Attend l'appui sur un des boutons de la souris.
+ *
+ * @return vrai (true) si un bouton a été pressé
+ *
+ * @see #waitMousePress(long)
+ * @see #getMouseX
+ * @see #getMouseY
+ * @see #getMouseButton
+ */
+ public boolean waitMousePress() {
+ return waitMousePress(-1);
+ }
+
+ /**
+ * Attend l'appui sur un des boutons de la souris.
+ *
+ * @param timeout temps maximal d'attente (millisecondes)
+ *
+ * @return vrai (true) si un bouton a été pressé
+ *
+ * @see #waitMousePress()
+ * @see #getMouseX
+ * @see #getMouseY
+ * @see #getMouseButton
+ */
+ public boolean waitMousePress(long timeout) {
+ boolean result = false;
+ synchronized (mouseLock) {
+ if (timeout != 0) {
+ mouseEvent = null;
+ try {
+ if (timeout > 0)
+ mouseLock.wait(timeout);
+ else // (timeout < 0)
+ mouseLock.wait();
+ }
+ catch (InterruptedException e) {
+ }
+ }
+ if (mouseEvent != null) {
+ mousePos.setLocation(mouseEvent.getPoint());
+ mouseButton = mouseEvent.getButton();
+ mouseEvent = null;
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Retourne la position (x) de la souris la dernière fois qu'un
+ * bouton a été pressé pendant l'appel à {@link #waitMousePress()}.
+ *
+ * @return position (x)
+ */
+ public int getMouseX() {
+ return mousePos.x;
+ }
+
+ /**
+ * Retourne la position (y) de la souris la dernière fois qu'un
+ * bouton a été pressé pendant l'appel à {@link #waitMousePress()}.
+ *
+ * @return position (y)
+ */
+ public int getMouseY() {
+ return mousePos.y;
+ }
+
+ /**
+ * Retourne le numéro du bouton de la souris pressé pendant
+ * le dernier appel à {@link #waitMousePress()}.
+ *
+ * @return numéro de bouton (1: gauche, 2: milieu, 3: droit)
+ */
+ public int getMouseButton() {
+ return mouseButton;
}
/**
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
WindowEvent ev =
- new WindowEvent(frame,
- WindowEvent.WINDOW_CLOSING);
+ 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
+ *
+ * @see #msleep
+ * @see #usleep
*/
- static void sleep(long secs) {
+ public static void sleep(long secs) {
try {
Thread.sleep(secs * 1000);
}
* Suspend l'exécution pendant un certain temps.
*
* @param msecs temps d'attente en millisecondes
+ *
+ * @see #sleep
+ * @see #usleep
*/
- static void msleep(long msecs) {
+ public static void msleep(long msecs) {
try {
Thread.sleep(msecs);
}
* Suspend l'exécution pendant un certain temps.
*
* @param usecs temps d'attente en microsecondes
+ *
+ * @see #sleep
+ * @see #msleep
*/
- static void usleep(long usecs) {
+ public static void usleep(long usecs) {
try {
Thread.sleep(usecs / 1000, (int)(usecs % 1000) * 1000);
}
colorMap = Collections.unmodifiableMap(m);
}
+ private static int instances = 0;
+
private final String title; // window's title
private JFrame frame; // the frame (window)
private DWPanel panel; // the panel showing the image
private BufferedImage image; // the image we draw into
private Graphics2D graphics; // graphics associated with image
private Color bgColor; // background color, for clearGraph()
+ private boolean isClosed; // is the window closed ?
+ private Object mouseLock; // lock for mouse events
+ private MouseEvent mouseEvent; // last mouse event
+ private Point mousePos; // last mouse position
+ private int mouseButton; // last mouse click
// To be run on the Event Dispatching Thread
void createGUI() {
- panel = new DWPanel(this);
-
+ panel = new DWPanel();
frame = new JFrame(title);
frame.add(panel);
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- frame.addKeyListener(panel);
+ frame.addWindowListener(new DWWindowHandler());
+ frame.addKeyListener(new DWKeyHandler());
+ panel.addMouseListener(new DWMouseHandler());
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
- private class DWPanel extends JPanel implements KeyListener {
+ private class DWWindowHandler extends WindowAdapter {
+ public void windowOpened(WindowEvent ev) {
+ DrawingWindow w = DrawingWindow.this;
+ DrawingWindow.instances++;
+ w.isClosed = false;
+ }
- private static final long serialVersionUID = 0;
+ public void windowClosed(WindowEvent ev) {
+ DrawingWindow w = DrawingWindow.this;
+ if (!w.isClosed) {
+ w.isClosed = true;
+ if (DrawingWindow.instances <= 0)
+ throw new AssertionError("Bad instance counter: " +
+ DrawingWindow.instances);
+ DrawingWindow.instances--;
+ if (DrawingWindow.instances == 0)
+ System.exit(0);
+ }
+ }
+ }
- final DrawingWindow w;
+ private class DWKeyHandler extends KeyAdapter {
+ public void keyPressed(KeyEvent ev) {
+ DrawingWindow w = DrawingWindow.this;
+ if (ev.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ w.closeGraph();
+ }
+ }
+ }
+
+ private class DWMouseHandler extends MouseAdapter {
+ public void mousePressed(MouseEvent ev) {
+ DrawingWindow w = DrawingWindow.this;
+ synchronized (w.mouseLock) {
+ w.mouseEvent = ev;
+ mouseLock.notifyAll();
+ }
+ }
+ }
- DWPanel(DrawingWindow w) {
- this.w = w;
+ private class DWPanel extends JPanel {
+ DWPanel() {
+ DrawingWindow w = DrawingWindow.this;
Dimension dimension = new Dimension(w.width, w.height);
super.setMinimumSize(dimension);
super.setMaximumSize(dimension);
}
public void paint(Graphics g) {
+ DrawingWindow w = DrawingWindow.this;
synchronized (w.image) {
g.drawImage(w.image, 0, 0, null);
}
}
- public void keyPressed(KeyEvent e) {
- if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
- w.closeGraph();
- }
- }
-
- public void keyReleased(KeyEvent e) { }
- public void keyTyped(KeyEvent e) { }
-
+ private static final long serialVersionUID = 0;
}
}