1
2
3
4
5
6
7
8
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
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
146 }
147
148 /***
149 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
150 */
151 public void mouseExited(final MouseEvent e)
152 {
153
154 }
155
156 /***
157 * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
158 */
159 public void mouseWheelMoved(final MouseWheelEvent e)
160 {
161
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
245 }
246
247 /***
248 * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
249 */
250 public void keyTyped(final KeyEvent e)
251 {
252
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
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 }