Coverage details for edu.uci.ics.jung.visualization.control.PickingGraphMousePlugin

LineHitsSource
1 /*
2  * Copyright (c) 2005, the JUNG Project and the Regents of the University
3  * of California
4  * All rights reserved.
5  *
6  * This software is open-source under the BSD license; see either
7  * "license.txt" or
8  * http://jung.sourceforge.net/license.txt for a description.
9  * Created on Mar 8, 2005
10  *
11  */
12 package edu.uci.ics.jung.visualization.control;
13  
14 import java.awt.Color;
15 import java.awt.Cursor;
16 import java.awt.Graphics;
17 import java.awt.Graphics2D;
18 import java.awt.Point;
19 import java.awt.event.InputEvent;
20 import java.awt.event.MouseEvent;
21 import java.awt.event.MouseListener;
22 import java.awt.event.MouseMotionListener;
23 import java.awt.geom.Point2D;
24 import java.awt.geom.Rectangle2D;
25 import java.util.ConcurrentModificationException;
26 import java.util.Iterator;
27  
28 import javax.swing.JComponent;
29  
30 import edu.uci.ics.jung.graph.Edge;
31 import edu.uci.ics.jung.graph.Vertex;
32 import edu.uci.ics.jung.visualization.Layout;
33 import edu.uci.ics.jung.visualization.PickSupport;
34 import edu.uci.ics.jung.visualization.PickedState;
35 import edu.uci.ics.jung.visualization.VisualizationViewer;
36 import edu.uci.ics.jung.visualization.VisualizationViewer.Paintable;
37  
38 /**
39  * PickingGraphMousePlugin supports the picking of graph elements
40  * with the mouse. MouseButtonOne picks a single vertex
41  * or edge, and MouseButtonTwo adds to the set of selected Vertices
42  * or Edges. If a Vertex is selected and the mouse is dragged while
43  * on the selected Vertex, then that Vertex will be repositioned to
44  * follow the mouse until the button is released.
45  *
46  * @author Tom Nelson
47  */
48 public class PickingGraphMousePlugin extends AbstractGraphMousePlugin
49     implements MouseListener, MouseMotionListener {
50  
51     /**
52      * the picked Vertex, if any
53      */
54     protected Vertex vertex;
55     
56     /**
57      * the picked Edge, if any
58      */
59     protected Edge edge;
60     
61     /**
62      * the x distance from the picked vertex center to the mouse point
63      */
64     protected double offsetx;
65     
66     /**
67      * the y distance from the picked vertex center to the mouse point
68      */
69     protected double offsety;
70     
71     /**
72      * controls whether the Vertices may be moved with the mouse
73      */
74     protected boolean locked;
75     
76     /**
77      * additional modifiers for the action of adding to an existing
78      * selection
79      */
80     protected int addToSelectionModifiers;
81     
82     /**
83      * used to draw a rectangle to contain picked vertices
84      */
850    protected Rectangle2D rect = new Rectangle2D.Float();
86     
87     /**
88      * the Paintable for the lens picking rectangle
89      */
90     protected Paintable lensPaintable;
91     
92     /**
93      * color for the picking rectangle
94      */
950    protected Color lensColor = Color.cyan;
96  
97     /**
98      * create an instance with default settings
99      */
100     public PickingGraphMousePlugin() {
1010        this(InputEvent.BUTTON1_MASK, InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK);
1020    }
103  
104     /**
105      * create an instance with overides
106      * @param selectionModifiers for primary selection
107      * @param addToSelectionModifiers for additional selection
108      */
109     public PickingGraphMousePlugin(int selectionModifiers, int addToSelectionModifiers) {
1100        super(selectionModifiers);
1110        this.addToSelectionModifiers = addToSelectionModifiers;
1120        this.lensPaintable = new LensPaintable();
1130        this.cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
1140    }
115     
116     /**
117      * @return Returns the lensColor.
118      */
119     public Color getLensColor() {
1200        return lensColor;
121     }
122  
123     /**
124      * @param lensColor The lensColor to set.
125      */
126     public void setLensColor(Color lensColor) {
1270        this.lensColor = lensColor;
1280    }
129  
130     /**
131      * a Paintable to draw the rectangle used to pick multiple
132      * Vertices
133      * @author Tom Nelson - RABA Technologies
134      *
135      */
136     class LensPaintable implements Paintable {
137  
138         public void paint(Graphics g) {
139             Color oldColor = g.getColor();
140             g.setColor(lensColor);
141             ((Graphics2D)g).draw(rect);
142             g.setColor(oldColor);
143         }
144  
145         public boolean useTransform() {
146             return false;
147         }
148     }
149  
150     /**
151      * For primary modifiers (default, MouseButton1):
152      * pick a single Vertex or Edge that
153      * is under the mouse pointer. If no Vertex or edge is under
154      * the pointer, unselect all picked Vertices and edges, and
155      * set up to draw a rectangle for multiple selection
156      * of contained Vertices.
157      * For additional selection (default Shift+MouseButton1):
158      * Add to the selection, a single Vertex or Edge that is
159      * under the mouse pointer. If a previously picked Vertex
160      * or Edge is under the pointer, it is un-picked.
161      * If no vertex or Edge is under the pointer, set up
162      * to draw a multiple selection rectangle (as above)
163      * but do not unpick previously picked elements.
164      *
165      * @param e the event
166      */
167     public void mousePressed(MouseEvent e) {
1680        down = e.getPoint();
1690        VisualizationViewer vv = (VisualizationViewer)e.getSource();
1700        PickSupport pickSupport = vv.getPickSupport();
1710        PickedState pickedState = vv.getPickedState();
1720        if(pickSupport != null && pickedState != null) {
1730            Layout layout = vv.getGraphLayout();
1740            if(e.getModifiers() == modifiers) {
1750                vv.addPostRenderPaintable(lensPaintable);
1760                rect.setFrameFromDiagonal(down,down);
177                 // p is the screen point for the mouse event
1780                Point2D p = e.getPoint();
179                 // take away the view transform
1800                Point2D ip = vv.inverseViewTransform(p);
181                 
1820                vertex = pickSupport.getVertex(ip.getX(), ip.getY());
1830                if(vertex != null) {
1840                    if(pickedState.isPicked(vertex) == false) {
1850                        pickedState.clearPickedVertices();
1860                        pickedState.pick(vertex, true);
187                     }
188                     // layout.getLocation applies the layout transformer so
189                     // q is transformed by the layout transformer only
1900                    Point2D q = layout.getLocation(vertex);
191                     // transform the mouse point to graph coordinate system
1920                    Point2D gp = vv.inverseLayoutTransform(ip);
193  
1940                    offsetx = (float) (gp.getX()-q.getX());
1950                    offsety = (float) (gp.getY()-q.getY());
1960                } else if((edge = pickSupport.getEdge(ip.getX(), ip.getY())) != null) {
1970                    pickedState.clearPickedEdges();
1980                    pickedState.pick(edge, true);
199                 } else {
2000                    pickedState.clearPickedEdges();
2010                    pickedState.clearPickedVertices();
202                 }
203                 
2040            } else if(e.getModifiers() == addToSelectionModifiers) {
2050                vv.addPostRenderPaintable(lensPaintable);
2060                rect.setFrameFromDiagonal(down,down);
2070                Point2D p = e.getPoint();
208                 // remove view transform
2090                Point2D ip = vv.inverseViewTransform(p);
2100                vertex = pickSupport.getVertex(ip.getX(), ip.getY());
2110                if(vertex != null) {
2120                    boolean wasThere = pickedState.pick(vertex, !pickedState.isPicked(vertex));
2130                    if(wasThere) {
2140                        vertex = null;
215                     } else {
216  
217                         // layout.getLocation applies the layout transformer so
218                         // q is transformed by the layout transformer only
2190                        Point2D q = layout.getLocation(vertex);
220                         // translate mouse point to graph coord system
2210                        Point2D gp = vv.inverseLayoutTransform(ip);
222  
2230                        offsetx = (float) (gp.getX()-q.getX());
2240                        offsety = (float) (gp.getY()-q.getY());
225                     }
2260                } else if((edge = pickSupport.getEdge(ip.getX(), ip.getY())) != null) {
2270                    pickedState.pick(edge, !pickedState.isPicked(edge));
228                 }
229             }
230         }
2310        if(vertex != null) e.consume();
2320    }
233  
234     /**
235      * If the mouse is dragging a rectangle, pick the
236      * Vertices contained in that rectangle
237      *
238      * clean up settings from mousePressed
239      */
240     public void mouseReleased(MouseEvent e) {
2410        VisualizationViewer vv = (VisualizationViewer)e.getSource();
2420        if(e.getModifiers() == modifiers) {
2430            if(down != null) {
2440                Point2D out = e.getPoint();
2450                if(vertex == null && heyThatsTooClose(down, out, 5) == false) {
2460                    pickContainedVertices(vv, true);
247                 }
248             }
2490        } else if(e.getModifiers() == this.addToSelectionModifiers) {
2500            if(down != null) {
2510                Point2D out = e.getPoint();
2520                if(vertex == null && heyThatsTooClose(down,out,5) == false) {
2530                    pickContainedVertices(vv, false);
254                 }
255             }
256         }
2570        down = null;
2580        vertex = null;
2590        edge = null;
2600        rect.setFrame(0,0,0,0);
2610        vv.removePostRenderPaintable(lensPaintable);
2620    }
263     
264     /**
265      * If the mouse is over a picked vertex, drag all picked
266      * vertices with the mouse.
267      * If the mouse is not over a Vertex, draw the rectangle
268      * to select multiple Vertices
269      *
270      */
271     public void mouseDragged(MouseEvent e) {
2720        if(locked == false) {
2730            VisualizationViewer vv = (VisualizationViewer)e.getSource();
2740            if(vertex != null) {
2750                Point p = e.getPoint();
2760                Point2D graphPoint = vv.inverseTransform(p);
2770                Point2D graphDown = vv.inverseTransform(down);
2780                Layout layout = vv.getGraphLayout();
2790                double dx = graphPoint.getX()-graphDown.getX();
2800                double dy = graphPoint.getY()-graphDown.getY();
2810                PickedState ps = vv.getPickedState();
282                 
2830                for(Iterator iterator=ps.getPickedVertices().iterator(); iterator.hasNext(); ) {
2840                    Vertex v = (Vertex)iterator.next();
2850                    Point2D vp = layout.getLocation(v);
2860                    layout.forceMove(v, vp.getX()+dx, vp.getY()+dy);
287                 }
2880                down = p;
289  
290             } else {
2910                Point2D out = e.getPoint();
2920                if(e.getModifiers() == this.addToSelectionModifiers ||
293                         e.getModifiers() == modifiers) {
2940                    rect.setFrameFromDiagonal(down,out);
295                 }
296             }
2970            if(vertex != null) e.consume();
298         }
2990    }
300     
301     /**
302      * rejects picking if the rectangle is too small, like
303      * if the user meant to select one vertex but moved the
304      * mouse slightly
305      * @param p
306      * @param q
307      * @param min
308      * @return
309      */
310     private boolean heyThatsTooClose(Point2D p, Point2D q, double min) {
3110        return Math.abs(p.getX()-q.getX()) < min &&
312                 Math.abs(p.getY()-q.getY()) < min;
313     }
314     
315     /**
316      * pick the vertices inside the rectangle
317      *
318      */
319     protected void pickContainedVertices(VisualizationViewer vv, boolean clear) {
320         
3210        Layout layout = vv.getGraphLayout();
3220        PickedState pickedState = vv.getPickedState();
3230        if(pickedState != null) {
3240            if(clear) {
3250                pickedState.clearPickedVertices();
326             }
327             while(true) {
328                 try {
3290                    for (Iterator iter=layout.getGraph().getVertices().iterator(); iter.hasNext(); ) {
3300                        Vertex v = (Vertex) iter.next();
3310                        if(rect.contains(vv.transform(layout.getLocation(v)))) {
3320                            pickedState.pick(v, true);
333                         }
334                     }
3350                    break;
3360                } catch(ConcurrentModificationException cme) {}
337             }
338         }
3390    }
340  
341     public void mouseClicked(MouseEvent e) {
3420    }
343  
344     public void mouseEntered(MouseEvent e) {
3450        JComponent c = (JComponent)e.getSource();
3460        c.setCursor(cursor);
3470    }
348  
349     public void mouseExited(MouseEvent e) {
3500        JComponent c = (JComponent)e.getSource();
3510        c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
3520    }
353  
354     public void mouseMoved(MouseEvent e) {
3550    }
356  
357     /**
358      * @return Returns the locked.
359      */
360     public boolean isLocked() {
3610        return locked;
362     }
363  
364     /**
365      * @param locked The locked to set.
366      */
367     public void setLocked(boolean locked) {
3680        this.locked = locked;
3690    }
370 }

this report was generated by version 1.0.5 of jcoverage.
visit www.jcoverage.com for updates.

copyright © 2003, jcoverage ltd. all rights reserved.
Java is a trademark of Sun Microsystems, Inc. in the United States and other countries.