View Javadoc

1   package de.fzi.wim.guibase.graphview.controller;
2   
3   import java.util.Collection;
4   import java.util.Collections;
5   import java.util.HashSet;
6   import java.util.Iterator;
7   import java.awt.Point;
8   import java.awt.Stroke;
9   import java.awt.Rectangle;
10  import java.awt.BasicStroke;
11  import java.awt.Color;
12  import java.awt.Graphics2D;
13  import java.awt.geom.Point2D;
14  import java.awt.event.MouseEvent;
15  
16  import de.fzi.wim.guibase.graphview.graph.*;
17  import de.fzi.wim.guibase.graphview.view.*;
18  import de.fzi.wim.guibase.graphview.selection.*;
19  
20  /***
21   * A manipulator that provides the selection user interface.
22   */
23  public class SelectionManipulator extends AbstractManipulator {
24      /*** The name of this manipulator. */
25      public static final String NAME="SelectionManipulator";
26      /*** The dashed stroke. */
27      protected static final Stroke DASHED_STROKE=new BasicStroke(1.0f,BasicStroke.CAP_SQUARE,BasicStroke.JOIN_BEVEL,2.0f,new float[] { 15.0f,10.0f },0.0f);
28  
29      /*** The node selection model.*/
30      protected NodeSelectionModel m_nodeSelectionModel;
31      /*** The graph position of the fixed point. */
32      protected Point2D m_selectionRectangleFixedGraph;
33      /*** The fixed point of the selection rectangle. */
34      protected Point m_selectionRectangleFixed;
35      /*** The moving point of the selection rectangle. */
36      protected Point m_selectionRectangleMoving;
37  
38      /***
39       * Creates an instance of this class.
40       *
41       * @param nodeSelectionModel                the model for node selection
42       */
43      public SelectionManipulator(NodeSelectionModel nodeSelectionModel) {
44          m_nodeSelectionModel=nodeSelectionModel;
45          m_nodeSelectionModel.addNodeSelectionListener(new NodeSelectionHandler());
46          m_selectionRectangleFixedGraph=new Point2D.Double();
47      }
48      protected boolean shouldSelectNode(Node node) {
49          return true;
50      }
51      public String getName() {
52          return NAME;
53      }
54      public NodeSelectionModel getNodeSelectionModel() {
55          return m_nodeSelectionModel;
56      }
57      public void paint(Graphics2D g) {
58          if (m_selectionRectangleFixed!=null) {
59              Color oldColor=g.getColor();
60              g.setColor(Color.gray);
61              Stroke oldStroke=g.getStroke();
62              g.setStroke(DASHED_STROKE);
63              int x=Math.min(m_selectionRectangleFixed.x,m_selectionRectangleMoving.x);
64              int y=Math.min(m_selectionRectangleFixed.y,m_selectionRectangleMoving.y);
65              int width=Math.abs(m_selectionRectangleFixed.x-m_selectionRectangleMoving.x);
66              int height=Math.abs(m_selectionRectangleFixed.y-m_selectionRectangleMoving.y);
67              g.drawRect(x,y,width,height);
68              g.setStroke(oldStroke);
69              g.setColor(oldColor);
70          }
71      }
72      public void mousePressed(MouseEvent e) {
73          if (m_graphPane.isEnabled() && (e.getModifiers() & MouseEvent.BUTTON1_MASK)!=0 && isStartSelectionEvent(e)) {
74              Node node=m_graphPane.getNodeAtPoint(e.getPoint());
75              if (node!=null) {
76                  Collection rawSelection=Collections.singletonList(node);
77                  changeSelection(rawSelection,e);
78              }
79              else {
80                  Edge edge=m_graphPane.getNearestEdge(e.getPoint());
81                  if (edge==null) {
82                      updateLastMouseEventScreenPoint(e);
83                      m_selectionRectangleFixed=e.getPoint();
84                      m_graphPane.screenToGraphPoint(m_selectionRectangleFixed,m_selectionRectangleFixedGraph);
85                      m_selectionRectangleMoving=m_selectionRectangleFixed;
86                      e.consume();
87                  }
88              }
89          }
90      }
91      public void mouseReleased(MouseEvent e) {
92          if (m_selectionRectangleFixed!=null && (e.getModifiers() & MouseEvent.BUTTON1_MASK)!=0) {
93              m_selectionRectangleMoving=e.getPoint();
94              int x=Math.min(m_selectionRectangleFixed.x,m_selectionRectangleMoving.x);
95              int y=Math.min(m_selectionRectangleFixed.y,m_selectionRectangleMoving.y);
96              int width=Math.abs(m_selectionRectangleFixed.x-m_selectionRectangleMoving.x);
97              int height=Math.abs(m_selectionRectangleFixed.y-m_selectionRectangleMoving.y);
98              Rectangle rectangle=new Rectangle(x,y,width,height);
99              Collection nodesInRectangle=m_graphPane.getNodesInRectangle(rectangle);
100             changeSelection(nodesInRectangle,e);
101             m_selectionRectangleFixed=null;
102             m_selectionRectangleMoving=null;
103             m_lastMouseEventScreenPoint=null;
104             m_graphPane.repaint();
105             e.consume();
106         }
107     }
108     public void mouseDragged(MouseEvent e) {
109         if (m_selectionRectangleFixed!=null) {
110             autoscroll(e);
111             updateLastMouseEventScreenPoint(e);
112             m_selectionRectangleMoving=e.getPoint();
113             m_graphPane.repaint();
114             e.consume();
115         }
116     }
117     public void notifyGraphPaneScrolled() {
118         if (m_selectionRectangleFixed!=null) {
119             m_graphPane.graphToScreenPoint(m_selectionRectangleFixedGraph,m_selectionRectangleFixed);
120             m_selectionRectangleMoving=getLastMouseEventPoint();
121             m_graphPane.repaint();
122         }
123     }
124     protected void changeSelection(Collection rawSelection,MouseEvent e) {
125         Collection newSelection=new HashSet();
126         Iterator iterator=rawSelection.iterator();
127         while (iterator.hasNext()) {
128             Node node=(Node)iterator.next();
129             if (shouldSelectNode(node))
130                 newSelection.add(node);
131         }
132         if (!newSelection.isEmpty()) {
133             Collection existingSelection=m_nodeSelectionModel.getSelectedNodes();
134             if (isToggleSelectionEvent(e)) {
135                 Collection addElements=new HashSet();
136                 Collection removeElements=new HashSet();
137                 iterator=newSelection.iterator();
138                 while (iterator.hasNext()) {
139                     Node node=(Node)iterator.next();
140                     if (existingSelection.contains(node))
141                         removeElements.add(node);
142                     else
143                         addElements.add(node);
144                 }
145                 if (!removeElements.isEmpty())
146                     m_nodeSelectionModel.removeNodes(removeElements);
147                 if (!addElements.isEmpty())
148                     m_nodeSelectionModel.addNodes(addElements);
149             }
150             else {
151                 if (!existingSelection.containsAll(newSelection) || existingSelection.size()!=newSelection.size()) {
152                     m_nodeSelectionModel.clear();
153                     m_nodeSelectionModel.addNodes(newSelection);
154                 }
155             }
156         }
157     }
158     protected boolean isStartSelectionEvent(MouseEvent e) {
159         return (e.getModifiers() & MouseEvent.SHIFT_MASK)==0;
160     }
161     protected boolean isToggleSelectionEvent(MouseEvent e) {
162         return (e.getModifiers() & MouseEvent.CTRL_MASK)!=0;
163     }
164 
165     /***
166      * The handles of the node selection events.
167      */
168     protected class NodeSelectionHandler implements NodeSelectionListener {
169         public void nodesAddedToSelection(NodeSelectionModel nodeSelectionModel,Collection nodes) {
170             m_graphPane.repaint();
171         }
172         public void nodesRemovedFromSelection(NodeSelectionModel nodeSelectionModel,Collection nodes) {
173             m_graphPane.repaint();
174         }
175         public void selectionCleared(NodeSelectionModel nodeSelectionModel) {
176             m_graphPane.repaint();
177         }
178     }
179 }