View Javadoc

    1   /*
    2    * @(#) InputListener.java Mar 2, 2004
    3    *
    4    * Copyright (c) 2002-2005 Delft University of Technology Jaffalaan 5, 2628 BX
    5    * Delft, the Netherlands. All rights reserved.
    6    *
    7    * This software is proprietary information of Delft University of Technology
    8    * The code is published under the Lesser General Public License
    9    */
    10  package nl.tudelft.simulation.dsol.gui.animation2D.mouse;
    11
    12  import java.awt.event.ActionEvent;
    13  import java.awt.event.KeyEvent;
    14  import java.awt.event.KeyListener;
    15  import java.awt.event.MouseEvent;
    16  import java.awt.event.MouseListener;
    17  import java.awt.event.MouseMotionListener;
    18  import java.awt.event.MouseWheelEvent;
    19  import java.awt.event.MouseWheelListener;
    20  import java.awt.geom.Point2D;
    21  import java.awt.geom.Rectangle2D;
    22  import java.rmi.RemoteException;
    23  import java.text.NumberFormat;
    24  import java.util.ArrayList;
    25  import java.util.Iterator;
    26  import java.util.List;
    27
    28  import javax.swing.JPopupMenu;
    29  import javax.swing.JSeparator;
    30  import javax.vecmath.Point4i;
    31
    32  import nl.tudelft.simulation.dsol.animation.LocatableInterface;
    33  import nl.tudelft.simulation.dsol.animation.D2.Renderable2DInterface;
    34  import nl.tudelft.simulation.dsol.gui.DSOLApplicationInterface;
    35  import nl.tudelft.simulation.dsol.gui.animation2D.AnimationPanel;
    36  import nl.tudelft.simulation.dsol.gui.animation2D.GridPanel;
    37  import nl.tudelft.simulation.dsol.gui.animation2D.actions.IntrospectionAction;
    38  import nl.tudelft.simulation.dsol.gui.animation2D.actions.PanDownAction;
    39  import nl.tudelft.simulation.dsol.gui.animation2D.actions.PanLeftAction;
    40  import nl.tudelft.simulation.dsol.gui.animation2D.actions.PanRightAction;
    41  import nl.tudelft.simulation.dsol.gui.animation2D.actions.PanUpAction;
    42  import nl.tudelft.simulation.dsol.gui.animation2D.actions.ZoomInAction;
    43  import nl.tudelft.simulation.dsol.gui.animation2D.actions.ZoomOutAction;
    44  import nl.tudelft.simulation.introspection.gui.IntroSpectionDialog;
    45  import nl.tudelft.simulation.logger.Logger;
    46
    47  /***
    48   * A InputListener <br>
    49   * (c) copyright 2002-2005 <a href="http://www.simulation.tudelft.nl">Delft
    50   * University of Technology </a>, the Netherlands. <br>
    51   * See for project information <a
    52   * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
    53   * License of use: <a href="http://www.gnu.org/copyleft/lesser.html">Lesser
    54   * General Public License (LGPL) </a>, no warranty.
    55   *
    56   * @version $Revision$ $Date$
    57   * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja">Peter Jacobs </a>
    58   */
    59  public class InputListener implements MouseListener, MouseWheelListener,
    60  		MouseMotionListener, KeyListener
    61  {
    62  	/*** the simulator to control */
    63  	protected DSOLApplicationInterface application;
    64
    65  	/*** the panel to use */
    66  	protected AnimationPanel panel;
    67
    68  	/*** the mouseClicked point in screen coordinates */
    69  	protected Point2D mouseClicked = null;
    70
    71  	/*** the formatter */
    72  	private NumberFormat formatter = NumberFormat.getInstance();
    73
    74  	/***
    75  	 * constructs a new InputListener
    76  	 *
    77  	 * @param application the application
    78  	 * @param panel the panel
    79  	 */
    80  	public InputListener(final DSOLApplicationInterface application,
    81  			final AnimationPanel panel)
    82  	{
    83  		super();
    84  		this.application = application;
    85  		this.panel = panel;
    86  	}
    87
    88  	/***
    89  	 * @see java.awt.event.MouseListener
    90  	 *      #mouseClicked(java.awt.event.MouseEvent)
    91  	 */
    92  	public void mouseClicked(final MouseEvent e)
    93  	{
    94  		this.panel.requestFocus();
    95  		this.mouseClicked = e.getPoint();
    96  		if (!e.isPopupTrigger())
    97  		{
    98  			Object selected = this.getSelectedObject(this.getSelectedObjects(e
    99  					.getPoint()));
    100 			if (selected != null)
    101 			{
    102 				new IntroSpectionDialog(selected);
    103 			}
    104 		}
    105 	}
    106
    107 	/***
    108 	 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
    109 	 */
    110 	public void mousePressed(final MouseEvent e)
    111 	{
    112 		this.panel.requestFocus();
    113 		this.mouseClicked = e.getPoint();
    114 		if (e.isPopupTrigger())
    115 		{
    116 			this.popup(e);
    117 			return;
    118 		}
    119 	}
    120
    121 	/***
    122 	 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
    123 	 */
    124 	public void mouseReleased(final MouseEvent e)
    125 	{
    126 		if (e.isPopupTrigger())
    127 		{
    128 			this.popup(e);
    129 		} else
    130 		{
    131 			// Pan if either shift is down or the middle mouse button is used.
    132 			if ((e.isShiftDown()) || (e.getButton() == MouseEvent.BUTTON2))
    133 			{
    134 				this.pan(this.mouseClicked, e.getPoint());
    135 				this.panel.repaint();
    136 			}
    137 		}
    138 	}
    139
    140 	/***
    141 	 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
    142 	 */
    143 	public void mouseEntered(final MouseEvent e)
    144 	{
    145 		// Nothing to be done.
    146 	}
    147
    148 	/***
    149 	 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
    150 	 */
    151 	public void mouseExited(final MouseEvent e)
    152 	{
    153 		// Nothing to be done
    154 	}
    155
    156 	/***
    157 	 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
    158 	 */
    159 	public void mouseWheelMoved(final MouseWheelEvent e)
    160 	{
    161 		// Use mouse wheel to zoom
    162 		int amount = e.getUnitsToScroll();
    163 		if (amount > 0)
    164 		{
    165 			this.panel.zoom(GridPanel.IN, 0.95 * amount);
    166 		} else if (amount < 0)
    167 		{
    168 			this.panel.zoom(GridPanel.OUT, 0.95 * -amount);
    169 		}
    170 	}
    171
    172 	/***
    173 	 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
    174 	 */
    175 	public void mouseDragged(final MouseEvent e)
    176 	{
    177 		if (e.isShiftDown())
    178 		{
    179 			this.setDragLine(e.getPoint());
    180 		}
    181 		this.panel.repaint();
    182 	}
    183
    184 	/***
    185 	 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
    186 	 */
    187 	public void mouseMoved(final MouseEvent mouseEvent)
    188 	{
    189 		Point2D point = Renderable2DInterface.Util.getWorldCoordinates(
    190 				mouseEvent.getPoint(), this.panel.getExtent(), this.panel
    191 						.getSize());
    192 		String worldPoint = "null";
    193 		if (point != null)
    194 		{
    195 			worldPoint = "world(x=" + this.formatter.format(point.getX())
    196 					+ " ; y=" + this.formatter.format(point.getY()) + ")";
    197 		}
    198 		String mousePoint = "screen(x="
    199 				+ this.formatter.format(mouseEvent.getPoint().getX()) + " ; y="
    200 				+ this.formatter.format(mouseEvent.getPoint().getY()) + ")";
    201 		this.panel.setToolTipText(worldPoint + "  " + mousePoint);
    202 	}
    203
    204 	/***
    205 	 * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
    206 	 */
    207 	public void keyPressed(final KeyEvent e)
    208 	{
    209 		switch (e.getKeyCode())
    210 		{
    211 			case KeyEvent.VK_LEFT :
    212 				new PanLeftAction(this.panel).actionPerformed(new ActionEvent(
    213 						this, 0, "LEFT"));
    214 				break;
    215 			case KeyEvent.VK_RIGHT :
    216 				new PanRightAction(this.panel).actionPerformed(new ActionEvent(
    217 						this, 0, "RIGHT"));
    218 				break;
    219 			case KeyEvent.VK_UP :
    220 				new PanUpAction(this.panel).actionPerformed(new ActionEvent(
    221 						this, 0, "UP"));
    222 				break;
    223 			case KeyEvent.VK_DOWN :
    224 				new PanDownAction(this.panel).actionPerformed(new ActionEvent(
    225 						this, 0, "DOWN"));
    226 				break;
    227 			case KeyEvent.VK_MINUS :
    228 				new ZoomOutAction(this.panel).actionPerformed(new ActionEvent(
    229 						this, 0, "OUT"));
    230 				break;
    231 			case KeyEvent.VK_EQUALS :
    232 				new ZoomInAction(this.panel).actionPerformed(new ActionEvent(
    233 						this, 0, "IN"));
    234 				break;
    235 			default :
    236 		}
    237 	}
    238
    239 	/***
    240 	 * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
    241 	 */
    242 	public void keyReleased(final KeyEvent e)
    243 	{
    244 		// nothing to be done
    245 	}
    246
    247 	/***
    248 	 * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
    249 	 */
    250 	public void keyTyped(final KeyEvent e)
    251 	{
    252 		// nothing to be done
    253 	}
    254
    255 	/***
    256 	 * What to do if the middle mouse button was released
    257 	 *
    258 	 * @param mouseClickedPoint the point where the mouse was clicked
    259 	 * @param mouseReleasedPoint the point where the mouse was released
    260 	 */
    261 	protected void pan(final Point2D mouseClickedPoint,
    262 			final Point2D mouseReleasedPoint)
    263 	{
    264 		// Drag extend to new location
    265 		double dx = mouseReleasedPoint.getX() - mouseClickedPoint.getX();
    266 		double dy = mouseReleasedPoint.getY() - mouseClickedPoint.getY();
    267 		double scale = Renderable2DInterface.Util.getScale(this.panel
    268 				.getExtent(), this.panel.getSize());
    269
    270 		Rectangle2D.Double extent = (Rectangle2D.Double) this.panel.getExtent();
    271 		extent.setRect((extent.getMinX() - dx * scale), (extent.getMinY() + dy
    272 				* scale), extent.getWidth(), extent.getHeight());
    273 	}
    274
    275 	/***
    276 	 * returns the list of selected objects at a certain mousePoint
    277 	 *
    278 	 * @param mousePoint the mousePoint
    279 	 * @return the selected objects
    280 	 */
    281 	protected List getSelectedObjects(final Point2D mousePoint)
    282 	{
    283 		List targets = new ArrayList();
    284 		try
    285 		{
    286 			Point2D point = Renderable2DInterface.Util.getWorldCoordinates(
    287 					mousePoint, this.panel.getExtent(), this.panel.getSize());
    288 			for (Iterator i = this.panel.getElements().iterator(); i.hasNext();)
    289 			{
    290 				Renderable2DInterface renderable = (Renderable2DInterface) i
    291 						.next();
    292 				if (renderable.contains(point, this.panel.getExtent(),
    293 						this.panel.getSize()))
    294 				{
    295 					targets.add(renderable.getSource());
    296 				}
    297 			}
    298 		} catch (Exception exception)
    299 		{
    300 			Logger.warning(this, "getSelectedObjects", exception);
    301 		}
    302 		return targets;
    303 	}
    304
    305 	/***
    306 	 * popsup on a mouseEvent
    307 	 *
    308 	 * @param e the mouseEvent
    309 	 */
    310 	protected void popup(final MouseEvent e)
    311 	{
    312 		List targets = this.getSelectedObjects(e.getPoint());
    313 		if (targets.size() > 0)
    314 		{
    315 			JPopupMenu popupMenu = new JPopupMenu();
    316 			popupMenu.add("Introspect");
    317 			popupMenu.add(new JSeparator());
    318 			for (Iterator i = targets.iterator(); i.hasNext();)
    319 			{
    320 				popupMenu.add(new IntrospectionAction(i.next()));
    321 			}
    322 			popupMenu.show(this.panel, e.getX(), e.getY());
    323 		}
    324 	}
    325
    326 	/***
    327 	 * edits a selected Renderable2D
    328 	 *
    329 	 * @param targets which are selected by the mouse.
    330 	 * @return the selected Object (e.g. the one with the highest zValue).
    331 	 */
    332 	protected Object getSelectedObject(final List targets)
    333 	{
    334 		Object selectedObject = null;
    335 		try
    336 		{
    337 			double zValue = -Double.MAX_VALUE;
    338 			for (Iterator i = targets.iterator(); i.hasNext();)
    339 			{
    340 				LocatableInterface next = (LocatableInterface) i.next();
    341 				double z = next.getLocation().z;
    342 				if (z > zValue)
    343 				{
    344 					zValue = z;
    345 					selectedObject = next;
    346 				}
    347 			}
    348 		} catch (RemoteException exception)
    349 		{
    350 			Logger.warning(this, "edit", exception);
    351 		}
    352 		return selectedObject;
    353 	}
    354
    355 	/***
    356 	 * set the drag line: a line that shows where the user is dragging
    357 	 *
    358 	 * @param mousePosition the position of the mouse pointer
    359 	 */
    360 	private void setDragLine(final Point2D mousePosition)
    361 	{
    362 		if ((mousePosition != null) && (this.mouseClicked != null))
    363 		{
    364 			Point4i dragLine = this.panel.getDragLine();
    365 			dragLine.w = (int) mousePosition.getX();
    366 			dragLine.x = (int) mousePosition.getY();
    367 			dragLine.y = (int) this.mouseClicked.getX();
    368 			dragLine.z = (int) this.mouseClicked.getY();
    369 			this.panel.setDragLineEnabled(true);
    370 		}
    371 	}
    372 }