import java.awt.*; import java.awt.event.*; import java.util.*; public class SensitivePolygon extends Polygon implements MouseMotionListener, MouseListener { boolean isActive; Vector listeners; protected Color fillColor; protected Color lineColor; protected Color fillColorInside; protected Color lineColorInside; protected Component canvas; private Graphics cacheGraphics; /** * Create this sensitive polygon, with 0 points. * and default colors. */ public SensitivePolygon(Component myCanvas) { super(); isActive = false; listeners = new Vector(); fillColor = Color.cyan; lineColor = Color.gray; fillColorInside = Color.blue; lineColorInside = Color.black; canvas = myCanvas; cacheGraphics = null; canvas.addMouseListener(this); canvas.addMouseMotionListener(this); } protected Graphics getGraphics() { if (cacheGraphics == null) { if (canvas != null) { cacheGraphics = canvas.getGraphics(); } } return cacheGraphics; } /** * Add a mouse listener to this sensitive polygon. */ public synchronized void addMouseListener(MouseListener m) { listeners.addElement(m); } public synchronized void removeMouseListener(MouseListener m) { listeners.removeElement(m); } // ************************************************************ public void mouseClicked(MouseEvent e) { if (isActive) notifyListeners(MouseEvent.MOUSE_CLICKED, e); } public void mousePressed(MouseEvent e) { if (isActive) notifyListeners(MouseEvent.MOUSE_PRESSED, e); } public void mouseReleased(MouseEvent e) { if (isActive) notifyListeners(MouseEvent.MOUSE_RELEASED, e); } public void mouseEntered(MouseEvent e) { boolean prev = isActive; processPoint(e.getPoint()); if (isActive && !prev) notifyListeners(MouseEvent.MOUSE_ENTERED, e); } public void mouseExited(MouseEvent e) { boolean prev = isActive; processPoint(e.getPoint()); if (!isActive && prev) notifyListeners(MouseEvent.MOUSE_EXITED, e); } public void mouseDragged(MouseEvent e) { boolean prev = isActive; processPoint(e.getPoint()); if (!isActive && prev) notifyListeners(MouseEvent.MOUSE_EXITED, e); if (isActive && !prev) notifyListeners(MouseEvent.MOUSE_ENTERED, e); } public void mouseMoved(MouseEvent e) { boolean prev = isActive; processPoint(e.getPoint()); if (!isActive && prev) notifyListeners(MouseEvent.MOUSE_EXITED, e); if (isActive && !prev) notifyListeners(MouseEvent.MOUSE_ENTERED, e); } public void paint(Graphics g) { if (g != null) { synchronized(g) { Color fi = ((isActive)?(fillColorInside):(fillColor)); Color li = ((isActive)?(lineColorInside):(lineColor)); if (fi != null) { g.setColor(fi); g.fillPolygon(this); } if (li != null) { g.setColor(li); g.drawPolygon(this); } } } return; } protected void processPoint(Point pt) { if (npoints < 3) { isActive = false; return; } if (contains(pt)) { if (!isActive) { // state change, possibly do redraw as activated isActive = true; paint(getGraphics()); } } else { if (isActive) { // state change, possibly do redraw as at rest isActive = false; paint(getGraphics()); } } } protected void notifyListeners(int id, MouseEvent evt) { MouseListener m; for(Enumeration e = listeners.elements(); e.hasMoreElements(); ) { m = (MouseListener)(e.nextElement()); switch (id) { case MouseEvent.MOUSE_PRESSED: m.mousePressed(evt); break; case MouseEvent.MOUSE_RELEASED: m.mouseReleased(evt); break; case MouseEvent.MOUSE_ENTERED: m.mouseEntered(evt); break; case MouseEvent.MOUSE_EXITED: m.mouseExited(evt); break; case MouseEvent.MOUSE_CLICKED: m.mouseClicked(evt); break; default: break; } } return; } /** * Set the fill color for the polygon when it is at rest. */ public void setFillColor(Color c) { fillColor = c; } /** * Get the fill color for the polygon when it is at rest. */ public Color getFillColor() { return fillColor; } /** * Set the outline color for the polygon when it is at rest. */ public void setLineColor(Color c) { lineColor = c; } /** * Get the outline color for the polygon when it is at rest. */ public Color getLineColor() { return lineColor; } /** * Set the fill color for the polygon when it is activated. */ public void setFillColorActive(Color c) { fillColorInside = c; } /** * Get the fill color for the polygon when it is activated. */ public Color getFillColorActive() { return fillColorInside; } /** * Set the outline color for the polygon when it is activated. */ public void setLineColorActive(Color c) { lineColorInside = c; } /** * Get the outline color for the polygon when it is activated. */ public Color getLineColorActive() { return lineColorInside; } static SensitivePolygon sp1, sp2, sp3; public static void main(String [] args) { Frame f; Canvas c; f = new Frame("SensitivePolygon Test"); c = new Canvas() { public void paint(Graphics g) { super.paint(g); sp1.paint(g); sp2.paint(g); } }; c.setBackground(Color.pink); c.setSize(300,300); f.add(c); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); sp1 = new SensitivePolygon(c); sp1.addPoint(20,30); sp1.addPoint(60,35); sp1.addPoint(120,130); sp1.addPoint(20,133); sp1.addPoint(20,30); sp2 = new SensitivePolygon(c); sp2.addPoint(200,200); sp2.addPoint(260,200); sp2.addPoint(260,240); sp2.addPoint(200,240); sp2.addPoint(200,200); sp2.setFillColor(Color.red); sp2.setLineColor(Color.black); sp3 = new SensitivePolygon(c); sp3.addPoint(0,220); sp3.addPoint(100,220); sp3.addPoint(0,290); sp3.addPoint(0,220); sp3.setFillColor(null); sp3.setFillColorActive(null); sp3.setLineColor(Color.pink); sp3.setLineColorActive(Color.green); sp2.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { System.out.println("sp2 entered"); } public void mouseExited(MouseEvent e) { System.out.println("sp2 exited"); } public void mousePressed(MouseEvent e) { System.out.println("sp2 pressed"); } public void mouseReleased(MouseEvent e) { System.out.println("sp2 released"); } }); sp1.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { System.out.println("sp1 entered"); } public void mouseExited(MouseEvent e) { System.out.println("sp1 exited"); } public void mousePressed(MouseEvent e) { System.out.println("sp1 pressed"); } public void mouseReleased(MouseEvent e) { System.out.println("sp1 released"); } }); f.show(); } }