View Javadoc
1   /*
2    * Copyright (c) 2005, The JUNG Authors 
3    *
4    * All rights reserved.
5    *
6    * This software is open-source under the BSD license; see either
7    * "license.txt" or
8    * https://github.com/jrtom/jung/blob/master/LICENSE for a description.
9    * Created on Mar 8, 2005
10   *
11   */
12  package edu.uci.ics.jung.visualization.control;
13  
14  import java.awt.Cursor;
15  import java.awt.event.InputEvent;
16  import java.awt.event.MouseEvent;
17  import java.awt.event.MouseListener;
18  import java.awt.event.MouseMotionListener;
19  import java.awt.geom.Point2D;
20  
21  import javax.swing.JComponent;
22  
23  import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor;
24  import edu.uci.ics.jung.algorithms.layout.Layout;
25  import edu.uci.ics.jung.visualization.Layer;
26  import edu.uci.ics.jung.visualization.VisualizationViewer;
27  import edu.uci.ics.jung.visualization.picking.PickedState;
28  
29  /** 
30   * AnimatedPickingGraphMousePlugin supports the picking of one Graph
31   * Vertex. When the mouse is released, the graph is translated so that
32   * the picked Vertex is moved to the center of the view. This translation
33   * is conducted in an animation Thread so that the graph slides to its
34   * new position
35   * 
36   * @author Tom Nelson
37   */
38  public class AnimatedPickingGraphMousePlugin<V, E> extends AbstractGraphMousePlugin
39      implements MouseListener, MouseMotionListener {
40  
41  	/**
42  	 * the picked Vertex
43  	 */
44      protected V vertex;
45      
46      /**
47  	 * Creates an instance with default modifiers of BUTTON1_MASK and CTRL_MASK
48  	 */
49  	public AnimatedPickingGraphMousePlugin() {
50  	    this(InputEvent.BUTTON1_MASK  | InputEvent.CTRL_MASK);
51  	}
52  
53  	/**
54  	 * Creates an instance with the specified mouse event modifiers.
55  	 * @param selectionModifiers the mouse event modifiers to use.
56  	 */
57      public AnimatedPickingGraphMousePlugin(int selectionModifiers) {
58          super(selectionModifiers);
59          this.cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
60      }
61  
62  	/**
63  	 * If the event occurs on a Vertex, pick that single Vertex
64  	 * @param e the event
65  	 */
66      @SuppressWarnings("unchecked")
67      public void mousePressed(MouseEvent e) {
68  		if (e.getModifiers() == modifiers) {
69  			VisualizationViewer<V,E> vv = (VisualizationViewer<V,E>) e.getSource();
70  			GraphElementAccessor<V, E> pickSupport = vv.getPickSupport();
71  			PickedState<V> pickedVertexState = vv.getPickedVertexState();
72              Layout<V,E> layout = vv.getGraphLayout();
73  			if (pickSupport != null && pickedVertexState != null) {
74  				// p is the screen point for the mouse event
75  				Point2D p = e.getPoint();
76  				vertex = pickSupport.getVertex(layout, p.getX(), p.getY());
77  				if (vertex != null) {
78  					if (pickedVertexState.isPicked(vertex) == false) {
79  						pickedVertexState.clear();
80  						pickedVertexState.pick(vertex, true);
81  					}
82  				}
83  			}
84              e.consume();
85  		}
86  	}
87  
88  
89  /**
90   * If a Vertex was picked in the mousePressed event, start a Thread
91   * to animate the translation of the graph so that the picked Vertex
92   * moves to the center of the view
93   * 
94   * @param e the event
95   */
96      @SuppressWarnings("unchecked")
97      public void mouseReleased(MouseEvent e) {
98  		if (e.getModifiers() == modifiers) {
99  			final VisualizationViewer<V,E> vv = (VisualizationViewer<V,E>) e.getSource();
100 			Point2D newCenter = null;
101 			if (vertex != null) {
102 				// center the picked vertex
103 				Layout<V,E> layout = vv.getGraphLayout();
104 				newCenter = layout.apply(vertex);
105 			} else {
106 				// they did not pick a vertex to center, so
107 				// just center the graph
108 				newCenter = vv.getCenter();
109 			}
110 			Point2D lvc = vv.getRenderContext().getMultiLayerTransformer().inverseTransform(vv.getCenter());
111 			final double dx = (lvc.getX() - newCenter.getX()) / 10;
112 			final double dy = (lvc.getY() - newCenter.getY()) / 10;
113 
114 			Runnable animator = new Runnable() {
115 
116 				public void run() {
117 					for (int i = 0; i < 10; i++) {
118 						vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).translate(dx, dy);
119 						try {
120 							Thread.sleep(100);
121 						} catch (InterruptedException ex) {
122 						}
123 					}
124 				}
125 			};
126 			Thread thread = new Thread(animator);
127 			thread.start();
128 		}
129 	}
130     
131     public void mouseClicked(MouseEvent e) {
132     }
133 
134     /**
135      * show a special cursor while the mouse is inside the window
136      */
137     public void mouseEntered(MouseEvent e) {
138         JComponent c = (JComponent)e.getSource();
139         c.setCursor(cursor);
140     }
141 
142     /**
143      * revert to the default cursor when the mouse leaves this window
144      */
145     public void mouseExited(MouseEvent e) {
146         JComponent c = (JComponent)e.getSource();
147         c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
148     }
149 
150     public void mouseMoved(MouseEvent e) {
151     }
152 
153 	public void mouseDragged(MouseEvent arg0) {
154 	}
155 }