package com.revolsys.swing.map.overlay; import java.awt.Component; import java.awt.Container; import java.awt.Window; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.util.ArrayList; import java.util.List; import javax.swing.JComponent; import javax.swing.JLayeredPane; import javax.swing.SwingUtilities; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.geometry.model.Point; import com.revolsys.logging.Logs; import com.revolsys.swing.SwingUtil; import com.revolsys.swing.map.MapPanel; import com.revolsys.swing.map.Viewport2D; public class MouseOverlay extends JComponent implements MouseListener, MouseMotionListener, MouseWheelListener, KeyListener, FocusListener { private static final long serialVersionUID = 1L; private static int x; private static int y; private static Point point = GeometryFactory.DEFAULT_3D.point(); public static Point getEventPoint() { return point; } public static int getEventX() { return x; } public static int getEventY() { return y; } public static boolean isMouseInMap() { return x != -1; } private final Viewport2D viewport; private final MapPanel mapPanel; public MouseOverlay(final MapPanel mapPanel, final JLayeredPane layeredPane) { this.mapPanel = mapPanel; this.viewport = mapPanel.getViewport(); setFocusable(true); layeredPane.add(this, new Integer(Integer.MAX_VALUE)); addMouseListener(this); addMouseMotionListener(this); addMouseWheelListener(this); addKeyListener(this); addFocusListener(this); } @Override public final void focusGained(final FocusEvent e) { } @Override public void focusLost(final FocusEvent e) { if (!e.isTemporary()) { final Component component = e.getComponent(); if (component != this) { final Component oppositeComponent = e.getOppositeComponent(); if (oppositeComponent != SwingUtilities.getWindowAncestor(this)) { for (final Component overlay : getOverlays()) { if (overlay instanceof FocusListener) { final FocusListener listener = (FocusListener)overlay; listener.focusLost(e); } } } } } } public Point getEventPointRounded() { final GeometryFactory geometryFactory = getGeometryFactory(); final Point point = this.viewport.toModelPointRounded(geometryFactory, x, y); return point; } public java.awt.Point getEventPosition() { return new java.awt.Point(x, y); } private GeometryFactory getGeometryFactory() { return this.viewport.getGeometryFactory(); } private List<Component> getOverlays() { final List<Component> overlays = new ArrayList<>(); final Container parent = getParent(); if (parent instanceof JLayeredPane) { final JLayeredPane layeredPane = (JLayeredPane)parent; for (final Component component : layeredPane.getComponents()) { if (component.isEnabled() && !(component instanceof MouseOverlay)) { overlays.add(component); } } } return overlays; } @Override public void keyPressed(final KeyEvent e) { for (final Component overlay : getOverlays()) { if (overlay instanceof KeyListener) { final KeyListener listener = (KeyListener)overlay; listener.keyPressed(e); if (e.isConsumed()) { return; } } } } @Override public void keyReleased(final KeyEvent e) { for (final Component overlay : getOverlays()) { if (overlay instanceof KeyListener) { final KeyListener listener = (KeyListener)overlay; listener.keyReleased(e); if (e.isConsumed()) { return; } } } } @Override public void keyTyped(final KeyEvent e) { for (final Component overlay : getOverlays()) { if (overlay instanceof KeyListener) { final KeyListener listener = (KeyListener)overlay; listener.keyTyped(e); if (e.isConsumed()) { return; } } } } @Override public void mouseClicked(final MouseEvent e) { updateEventPoint(e); requestFocusInWindow(); for (final Component overlay : getOverlays()) { if (overlay instanceof MouseListener) { final MouseListener listener = (MouseListener)overlay; listener.mouseClicked(e); if (e.isConsumed()) { return; } } } } @Override public void mouseDragged(final MouseEvent e) { updateEventPoint(e); requestFocusInWindow(); for (final Component overlay : getOverlays()) { if (overlay instanceof MouseMotionListener) { final MouseMotionListener listener = (MouseMotionListener)overlay; listener.mouseDragged(e); if (e.isConsumed()) { return; } } } } @Override public void mouseEntered(final MouseEvent e) { updateEventPoint(e); requestFocusInWindow(); for (final Component overlay : getOverlays()) { if (overlay instanceof MouseListener) { final MouseListener listener = (MouseListener)overlay; listener.mouseEntered(e); if (e.isConsumed()) { return; } } } } @Override public void mouseExited(final MouseEvent event) { MouseOverlay.x = -1; MouseOverlay.y = -1; MouseOverlay.point = GeometryFactory.DEFAULT_3D.point(); this.mapPanel.mouseExitedCloseSelected(event); for (final Component overlay : getOverlays()) { if (overlay instanceof MouseListener) { final MouseListener listener = (MouseListener)overlay; listener.mouseExited(event); if (event.isConsumed()) { return; } } } } @Override public void mouseMoved(final MouseEvent event) { updateEventPoint(event); try { requestFocusInWindow(); this.mapPanel.mouseMovedCloseSelected(event); for (final Component overlay : getOverlays()) { if (overlay instanceof MouseMotionListener) { final MouseMotionListener listener = (MouseMotionListener)overlay; listener.mouseMoved(event); if (event.isConsumed()) { return; } } } } catch (final RuntimeException e) { Logs.error(this, "Mouse move error", e); } } @Override public void mousePressed(final MouseEvent e) { updateEventPoint(e); final Window window = SwingUtil.getWindowAncestor(this); window.setAlwaysOnTop(true); window.toFront(); window.setFocusableWindowState(true); window.requestFocus(); window.setAlwaysOnTop(false); requestFocusInWindow(); for (final Component overlay : getOverlays()) { if (overlay instanceof MouseListener) { final MouseListener listener = (MouseListener)overlay; listener.mousePressed(e); if (e.isConsumed()) { return; } } } } @Override public void mouseReleased(final MouseEvent e) { updateEventPoint(e); requestFocusInWindow(); for (final Component overlay : getOverlays()) { if (overlay instanceof MouseListener) { final MouseListener listener = (MouseListener)overlay; listener.mouseReleased(e); if (e.isConsumed()) { return; } } } } @Override public void mouseWheelMoved(final MouseWheelEvent e) { updateEventPoint(e); for (final Component overlay : getOverlays()) { if (overlay instanceof MouseWheelListener) { final MouseWheelListener listener = (MouseWheelListener)overlay; listener.mouseWheelMoved(e); if (e.isConsumed()) { return; } } } } private void updateEventPoint(final MouseEvent e) { MouseOverlay.x = e.getX(); MouseOverlay.y = e.getY(); MouseOverlay.point = this.viewport.toModelPoint(x, y); } }