KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > nbprefuse > FindUsagesFocusControl


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.nbprefuse;
21
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.awt.event.MouseEvent JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import java.beans.PropertyChangeSupport JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import javax.swing.Action JavaDoc;
31 import org.netbeans.modules.refactoring.api.RefactoringElement;
32 import org.netbeans.modules.xml.nbprefuse.util.GraphUtilities;
33 import org.openide.filesystems.FileObject;
34 import prefuse.Visualization;
35 import prefuse.data.tuple.TupleSet;
36 import prefuse.util.ui.UILib;
37 import prefuse.visual.AggregateItem;
38 import prefuse.visual.NodeItem;
39 import prefuse.visual.VisualItem;
40
41 /**
42  *
43  * @author Jeri Lockhart
44  */

45 public class FindUsagesFocusControl extends NbFocusControl{
46     
47     protected SelectionMode selectionMode = SelectionMode.SINGLE;
48     protected PropertyChangeSupport JavaDoc pcSupport;
49     
50     public enum SelectionMode {SINGLE, MULTIPLE};
51     
52     
53     /**
54      * Creates a new FocusControl that changes the focus to another item
55      * when that item is clicked once.
56      */

57     public FindUsagesFocusControl() {
58         super();
59         initialize();
60         
61     }
62     
63     /**
64      * Creates a new FocusControl that changes the focus to another item
65      * when that item is clicked once.
66      * @param focusGroup the name of the focus group to use
67      */

68     public FindUsagesFocusControl(String JavaDoc focusGroup) {
69         super(focusGroup);
70         initialize();
71     }
72     
73     /**
74      * Creates a new FocusControl that changes the focus when an item is
75      * clicked the specified number of times. A click value of zero indicates
76      * that the focus should be changed in response to mouse-over events.
77      * @param clicks the number of clicks needed to switch the focus.
78      */

79     public FindUsagesFocusControl(int clicks) {
80         super(clicks);
81         initialize();
82     }
83     
84     /**
85      * Creates a new FocusControl that changes the focus when an item is
86      * clicked the specified number of times. A click value of zero indicates
87      * that the focus should be changed in response to mouse-over events.
88      * @param focusGroup the name of the focus group to use
89      * @param clicks the number of clicks needed to switch the focus.
90      */

91     public FindUsagesFocusControl(String JavaDoc focusGroup, int clicks) {
92         super(focusGroup, clicks);
93         initialize();
94     }
95     
96     /**
97      * Creates a new FocusControl that changes the focus when an item is
98      * clicked the specified number of times. A click value of zero indicates
99      * that the focus should be changed in response to mouse-over events.
100      * @param clicks the number of clicks needed to switch the focus.
101      * @param act an action run to upon focus change
102      */

103     public FindUsagesFocusControl(int clicks, String JavaDoc act) {
104         super(clicks, act);
105         initialize();
106     }
107     
108     /**
109      * Creates a new FocusControl that changes the focus when an item is
110      * clicked the specified number of times. A click value of zero indicates
111      * that the focus should be changed in response to mouse-over events.
112      * @param focusGroup the name of the focus group to use
113      * @param clicks the number of clicks needed to switch the focus.
114      * @param act an action run to upon focus change
115      */

116     public FindUsagesFocusControl(String JavaDoc focusGroup, int clicks, String JavaDoc act) {
117         super(focusGroup, clicks, act);
118         initialize();
119     }
120     
121     public void itemPressed(VisualItem item, MouseEvent JavaDoc e) {
122     super.itemPressed(item, e);
123     if (e.isPopupTrigger()) {
124         // select node before popup shows
125
selectNode(item,e);
126     }
127     }
128     
129     public void itemReleased(VisualItem item, MouseEvent JavaDoc e) {
130     super.itemReleased(item, e);
131     if (e.isPopupTrigger()) {
132         // select node before popup shows
133
selectNode(item,e);
134     }
135     }
136     
137     private void selectNode(VisualItem item, MouseEvent JavaDoc e) {
138     // Only handle nodes (not edges)
139
Visualization vis = item.getVisualization();
140     NodeItem nodeItem = null;
141     if (item instanceof NodeItem){
142         nodeItem = NodeItem.class.cast(item);
143     } else {
144         return;
145     }
146     selectNode(e, nodeItem, vis);
147     runActivity(vis);
148     }
149     
150     /**
151      * @see prefuse.controls.Control#itemClicked(prefuse.visual.VisualItem, java.awt.event.MouseEvent)
152      */

153     public void itemClicked(VisualItem item, MouseEvent JavaDoc e) {
154         if ( UILib.isButtonPressed(e, button) &&
155                 e.getClickCount() == ccount) {
156             Visualization vis = item.getVisualization();
157             if (ccount == 1){
158         selectNode(item,e);
159             } // end if ccount == 1
160
else if (ccount == 2){
161                 // expand or collapse Schema File node or the AggregateItem
162
// that contains the File Node
163
int aggregateItemFileGroup = -1;
164                 if (item.canGetBoolean(AnalysisConstants.IS_FILE_GROUP_AGGREGATE) &&
165                         item.getBoolean(AnalysisConstants.IS_FILE_GROUP_AGGREGATE) &&
166                         item.canGetInt(AnalysisConstants.ID)){
167                     aggregateItemFileGroup = item.getInt(AnalysisConstants.ID);
168                 }
169                 if ((item.canGetBoolean(AnalysisConstants.IS_FILE_NODE)
170                 && item.getBoolean(AnalysisConstants.IS_FILE_NODE) )
171                 ||
172                         aggregateItemFileGroup > -1) {
173                     // If the item is the AggregateItem containing the File Node
174
// find the FileNode
175
NodeItem fileNode = null;
176                     if (item instanceof AggregateItem){
177                         fileNode = findFileNode(aggregateItemFileGroup, item);
178                     } else {
179                         fileNode = (NodeItem)item;
180                     }
181                     GraphUtilities.expandCollapseFileNode(fileNode);
182                 } // end if FileNode or AggregateItem containing the FileNode
183

184                 // Double click on a Component node:
185
// Perform the default action on the UIHelper org.openide.nodes.Node
186
// that is stored in the NodeItem.
187
// (For a SchemaComponent, the default action is to open the
188
// schema view with the component highlighted
189
// TODO run Default Action on double click
190

191                 // Use Object instead of Component in order
192
// to remove dependency on XAM module
193
/* else if (item.canGet(AnalysisConstants.XAM_COMPONENT, Object.class)) {
194                     Object comp = item.get(AnalysisConstants.XAM_COMPONENT);
195                     assert item.canGet(
196                             AnalysisConstants.OPENIDE_NODE, org.openide.nodes.Node.class):
197                                 "NodeItem is missing UIHelper display org.openide.nodes.Node instance.";
198                     org.openide.nodes.Node helperNode =
199                             (org.openide.nodes.Node)item.get(AnalysisConstants.OPENIDE_NODE);
200                     assert helperNode != null:"UIHelper node should not be null";
201                     Action preferredAction = helperNode.getPreferredAction();
202                     if (!(preferredAction == null && comp == null)){
203                         final ActionEvent event = new ActionEvent(
204                                 comp,
205                                 0,
206                                 ""); //NOI18N
207                         preferredAction.actionPerformed(event);
208                     }
209                 }*/

210                 
211                 else if (item.canGet(AnalysisConstants.REFACTORING_ELEMENT, RefactoringElement.class)) {
212                     RefactoringElement comp = (RefactoringElement) item.get(AnalysisConstants.REFACTORING_ELEMENT);
213                     
214                    // if(comp != null)
215
// comp.openInEditor();
216
}
217   
218             if (item instanceof NodeItem){
219                 selectNode(e, NodeItem.class.cast(item), vis);
220             }
221             runActivity(vis);
222             
223             
224         }// end if ccount ==2
225
}
226 }
227
228 /**
229  * Finds the schema File Node in the AggregateItem
230  * The AggregateItem contains the schema file node and
231  * the SchemaComponent nodes for the file
232  *
233  */

234 private NodeItem findFileNode(final int aggregateItemFileGroup, final VisualItem item) {
235     NodeItem fileNode = null;
236     AggregateItem agIt = AggregateItem.class.cast(item);
237     Iterator JavaDoc agItems = agIt.items();
238     while(agItems.hasNext()){
239         VisualItem agItem = (VisualItem)agItems.next();
240         int fileGroup = -1;
241         if (agItem.canGetInt(AnalysisConstants.FILE_NODE_FILE_GROUP)) {
242             fileGroup = agItem.getInt(AnalysisConstants.FILE_NODE_FILE_GROUP);
243             if (fileGroup == aggregateItemFileGroup &&
244                     agItem.canGetBoolean(AnalysisConstants.IS_EXPANDED)){
245                 fileNode = NodeItem.class.cast(agItem);
246                 break;
247             }
248         }
249     }
250     return fileNode;
251 }
252
253 private void selectNode(final MouseEvent JavaDoc e, final NodeItem nodeItem, final Visualization vis) {
254     TupleSet ts = vis.getFocusGroup(Visualization.FOCUS_ITEMS);
255     NodeItem curSelected = null;
256     List JavaDoc<NodeItem> selected = getNodeItemList(ts);
257     if (!selected.isEmpty()){
258         // assuming SINGLE selection mode
259
curSelected = selected.get(0);
260 // curSelected.setStroke(AnalysisConstants.UNSELECTED_STROKE);
261
}
262     // get graph node object,
263
// which is either a SchemaComponent or a FileObject
264
Object JavaDoc curComp = getGraphNodeUserObject(curSelected);
265     Object JavaDoc newComp = getGraphNodeUserObject(nodeItem);
266     
267 // HighlightManager hm = HighlightManager.getDefault();
268
// Lookup hmLookup = Lookups.singleton(hm);
269

270     
271     boolean ctrl = e.isControlDown();
272     if ( !ctrl) {
273         pcSupport.firePropertyChange(
274                 AnalysisViewer.PROP_GRAPH_NODE_SELECTION_CHANGE,
275                 curComp, newComp); // select
276
curFocus = nodeItem;
277         ts.setTuple(nodeItem);
278 // highlightSchemaComponent(nodeItem, hmLookup);
279
// nodeItem.setStroke(AnalysisConstants.SELECTED_STROKE);
280

281     } else if ( ts.containsTuple(nodeItem) ) {
282         pcSupport.firePropertyChange(
283                 AnalysisViewer.PROP_GRAPH_NODE_SELECTION_CHANGE,
284                 newComp, null); // unselect
285
ts.removeTuple(nodeItem);
286         // MouseoverActionControl sets MOUSEOVER to true
287
// Set MOUSEOVER to false so the node is
288
// rendered without MOUSEOVER color
289
// This mimics Windows selection behaviour for trees and
290
// lists.
291
if (nodeItem instanceof NodeItem &&
292                 nodeItem.canSetBoolean(AnalysisConstants.MOUSEOVER)){
293             nodeItem.setBoolean(AnalysisConstants.MOUSEOVER, false);
294         }
295         
296 // nodeItem.setStroke(AnalysisConstants.UNSELECTED_STROKE);
297
// HighlightProvider.hideResults(hmLookup);
298

299     } else {
300         if (selectionMode == SelectionMode.MULTIPLE){
301             // This shouldn't happen --
302
// Find Usages node selection is always SINGLE
303
ts.addTuple(nodeItem);
304         } else {
305             // AnalysisViewer is listening to this event
306
// AnalysisViewer will notify RefactoringPanel
307
// RefactoringPanel will select the corresponding node
308
// in the RefactoringPanel explorer JTree
309
pcSupport.firePropertyChange(
310                     AnalysisViewer.PROP_GRAPH_NODE_SELECTION_CHANGE,
311                     curComp, newComp); // select
312
curFocus = nodeItem;
313             ts.setTuple(nodeItem);
314 // highlightSchemaComponent(nodeItem, hmLookup);
315
}
316     }
317 }
318
319 //private void highlightSchemaComponent(final NodeItem nodeItem, final Lookup hmLookup) {
320
// HighlightProvider.hideResults(hmLookup);
321
// if (nodeItem.canGet(AnalysisConstants.XAM_COMPONENT, Component.class)){
322
// Component c = (Component)nodeItem.get(AnalysisConstants.XAM_COMPONENT);
323
// if (c instanceof SchemaComponent){
324
// HighlightProvider.showResults(
325
// Collections.singleton(SchemaComponent.class.cast(c)),
326
// hmLookup);
327
// }
328
// }
329
//}
330

331 // ***************************************************************************
332
// Extensions
333
// ***************************************************************************
334

335
336
337 private void initialize() {
338     pcSupport = new PropertyChangeSupport JavaDoc(this);
339 }
340
341 /**
342  * WhereUsedView.showView() adds the AnalysisViewer instance as a listener
343  * AnalysisViewer then notifies RefactoringPanel
344  * so that RefactoringPanel can select the corresponding
345  * RefactoringPanel JTreenode
346  *
347  */

348 public void addGraphNodeSelectionChangeListener(PropertyChangeListener JavaDoc l){
349     pcSupport.addPropertyChangeListener(
350             AnalysisViewer.PROP_GRAPH_NODE_SELECTION_CHANGE, l);
351 }
352
353
354
355 /**
356  * @param ts should be a set of NodeItems
357  *
358  */

359 private List JavaDoc<NodeItem> getNodeItemList(TupleSet ts){
360     ArrayList JavaDoc<NodeItem> list = null;
361     int count = ts.getTupleCount();
362     if (count > 0){
363         list = new ArrayList JavaDoc<NodeItem>(count);
364     } else {
365         return Collections.emptyList();
366     }
367     Iterator JavaDoc it = ts.tuples();
368     while (it.hasNext()){
369         // should only be one (Single select mode)
370
list.add((NodeItem)it.next());
371     }
372     return list;
373 }
374
375
376 /**
377  * the graph nodes can represent XAM Components or
378  * FileObjects
379  *
380  */

381 private Object JavaDoc getGraphNodeUserObject(NodeItem item ){
382     if (item == null){
383         return null;
384     }
385
386     FileObject fo = (FileObject) item.get(AnalysisConstants.FILE_OBJECT);
387     if (fo != null) {
388         return fo;
389     }
390     return item.get(AnalysisConstants.USER_OBJECT);
391 }
392 }
393
Popular Tags