KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > antlr > xjlib > appkit > swing > XJTree


1 package org.antlr.xjlib.appkit.swing;
2
3 import javax.swing.*;
4 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
5 import javax.swing.tree.TreePath JavaDoc;
6 import java.awt.*;
7 import java.awt.datatransfer.Transferable JavaDoc;
8 import java.awt.dnd.*;
9 import java.awt.event.ActionEvent JavaDoc;
10 import java.awt.event.ActionListener JavaDoc;
11 import java.awt.event.MouseEvent JavaDoc;
12 import java.awt.image.BufferedImage JavaDoc;
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 /*
17
18 [The "BSD licence"]
19 Copyright (c) 2005 Jean Bovet
20 All rights reserved.
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions
24 are met:
25
26 1. Redistributions of source code must retain the above copyright
27 notice, this list of conditions and the following disclaimer.
28 2. Redistributions in binary form must reproduce the above copyright
29 notice, this list of conditions and the following disclaimer in the
30 documentation and/or other materials provided with the distribution.
31 3. The name of the author may not be used to endorse or promote products
32 derived from this software without specific prior written permission.
33
34 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
35 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
38 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
39 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
40 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
41 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
45 */

46
47 /* Portion of this code has been inspired by the following Java Tips:
48
49     http://www.javaworld.com/javaworld/javatips/jw-javatip97.html (Rob Kenworthy)
50     http://www.javaworld.com/javaworld/javatips/jw-javatip114.html (Andrew Armstrong)
51
52 */

53
54 public class XJTree extends JTree implements DragGestureListener, DropTargetListener, DragSourceListener, Autoscroll {
55
56     protected XJTreeDelegate delegate;
57     protected DragSource dragSource;
58     protected TreePath JavaDoc oldSelectedPath;
59
60     protected Timer autoExpandTimer;
61     protected TreePath JavaDoc lastPath;
62     protected Point lastPoint = new Point();
63     protected Rectangle cueLine = new Rectangle();
64
65     protected BufferedImage JavaDoc dragImage;
66     protected Point dragImageOffset = new Point();
67
68     protected final int AUTOSCROLL_MARGIN = 12;
69
70     protected int dropLocation;
71     public static final int DROP_ABOVE = 0;
72     public static final int DROP_ONTO = 1;
73     public static final int DROP_BELOW = 2;
74
75     public XJTree() {
76         super();
77         autoExpandTimer = new Timer(1000, new ActionListener JavaDoc() {
78             public void actionPerformed(ActionEvent JavaDoc e) {
79                 if(isRootVisible() && getRowForPath(lastPath) == 0) {
80                     // Do not expand the root
81
return;
82                 }
83
84                 if(isExpanded(lastPath))
85                     collapsePath(lastPath);
86                 else
87                     expandPath(lastPath);
88             }
89         });
90         autoExpandTimer.setRepeats(false);
91     }
92
93     public void setDelegate(XJTreeDelegate delegate) {
94         this.delegate = delegate;
95     }
96
97     public void setEnableDragAndDrop() {
98         dragSource = DragSource.getDefaultDragSource();
99         dragSource.createDefaultDragGestureRecognizer(this, getDelegateConstants(), this);
100         new DropTarget(this, this);
101     }
102
103     public int getDelegateConstants() {
104         return delegate.xjTreeDragAndDropConstants(this);
105     }
106
107     public DefaultMutableTreeNode JavaDoc getOldSelectedNode() {
108         return (DefaultMutableTreeNode JavaDoc)oldSelectedPath.getLastPathComponent();
109     }
110
111     public DefaultMutableTreeNode JavaDoc getSelectedNode() {
112         if(getSelectionPath() == null)
113             return null;
114         else
115             return (DefaultMutableTreeNode JavaDoc)getSelectionPath().getLastPathComponent();
116     }
117
118     public List JavaDoc getSelectedNodes() {
119         List JavaDoc nodes = new ArrayList JavaDoc();
120         if(getSelectionPaths() != null) {
121             for (int i = 0; i < getSelectionPaths().length; i++) {
122                 TreePath JavaDoc treePath = getSelectionPaths()[i];
123                 nodes.add(treePath.getLastPathComponent());
124             }
125         }
126         return nodes;
127     }
128
129     /** This method deselects the current selection of the item
130      * under the mouse location if it is not part of the current selection
131      */

132
133     public void modifySelectionIfNecessary(MouseEvent JavaDoc me) {
134         boolean partOfSelection = false;
135         int row = getRowForLocation(me.getX(), me.getY());
136         if(getSelectionRows() != null) {
137             for (int i = 0; i < getSelectionRows().length; i++) {
138                 int selRow = getSelectionRows()[i];
139                 if(selRow == row)
140                     partOfSelection = true;
141             }
142         }
143
144         if(!partOfSelection)
145             setSelectionRow(row);
146     }
147
148     protected void cleanUpAfterDrag() {
149         paintImmediately(cueLine);
150     }
151
152     // AutoScroll interface
153

154     public Insets getAutoscrollInsets() {
155         Rectangle outer = getBounds();
156         Rectangle inner = getParent().getBounds();
157
158         return new Insets(inner.y-outer.y+AUTOSCROLL_MARGIN, inner.x-outer.x+AUTOSCROLL_MARGIN,
159                 outer.height-inner.height+AUTOSCROLL_MARGIN,
160                 outer.width-inner.width+AUTOSCROLL_MARGIN);
161     }
162
163     public void autoscroll(Point point) {
164         int row = getRowForLocation(point.x, point.y);
165         if(row < 0)
166             return;
167
168         Rectangle outer = getBounds();
169         if(point.y + outer.y <= AUTOSCROLL_MARGIN)
170             row = row <= 0 ? 0 : row - 1;
171         else
172             row = row < getRowCount() - 1 ? row + 1 : row;
173
174         scrollRowToVisible(row);
175     }
176
177     // DragGestureListener interface method
178

179     public void dragGestureRecognized(DragGestureEvent event) {
180         try {
181             createDragImage(event);
182             dragSource.startDrag(event, delegate.xjTreeDragSourceDefaultCursor(this), dragImage, new Point(5,5), (Transferable JavaDoc)getSelectedNode().getUserObject(), this);
183         } catch(Exception JavaDoc e) {
184             // Ignore currently
185
}
186     }
187
188     public void createDragImage(DragGestureEvent event) {
189         Point dragOrigin = event.getDragOrigin();
190         TreePath JavaDoc path = getPathForLocation(dragOrigin.x, dragOrigin.y);
191         Rectangle r = getPathBounds(path);
192         dragImageOffset.setLocation(dragOrigin.x - r.x, dragOrigin.y - r.y);
193
194         JLabel label = (JLabel)getCellRenderer().getTreeCellRendererComponent(this, path.getLastPathComponent(),
195                 false, isExpanded(path), getModel().isLeaf(path.getLastPathComponent()), 0, false);
196         label.setSize(r.width, r.height);
197
198         dragImage = new BufferedImage JavaDoc(r.width, r.height, BufferedImage.TYPE_INT_ARGB_PRE);
199         Graphics2D g2d = dragImage.createGraphics();
200         g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.5f));
201         label.paint(g2d);
202         g2d.dispose();
203     }
204
205     // DropTargetListener interface method
206

207     public void dragEnter(DropTargetDragEvent event) {
208         oldSelectedPath = getSelectionPath();
209         if(event.getDropAction() != getDelegateConstants()) {
210             cleanUpAfterDrag();
211             event.rejectDrag();
212         } else
213             event.acceptDrag(getDelegateConstants());
214     }
215
216     public void dragOver(DropTargetDragEvent event) {
217         int x = event.getLocation().x;
218         int y = event.getLocation().y;
219         TreePath JavaDoc p = getClosestPathForLocation(x, y);
220         if(p != lastPath) {
221             lastPath = p;
222             autoExpandTimer.restart();
223         }
224
225         if(p == null || event.getDropAction() != getDelegateConstants()) {
226             cleanUpAfterDrag();
227             event.rejectDrag();
228         } else {
229             event.acceptDrag(getDelegateConstants());
230
231             Graphics2D g2d = (Graphics2D)getGraphics();
232             Rectangle rpath = getPathBounds(lastPath);
233             Rectangle oldCueLine = (Rectangle) cueLine.clone();
234             if(y < rpath.y + rpath.height/2) {
235                 if(getRowForPath(lastPath) == 0) {
236                     cueLine.setRect(0, rpath.y, getWidth(), 2);
237                 } else {
238                     cueLine.setRect(0, rpath.y - 1, getWidth(), 2);
239                 }
240                 dropLocation = DROP_ABOVE;
241             } else {
242                 cueLine.setRect(0, rpath.y + rpath.height - 1, getWidth(), 2);
243                 dropLocation = DROP_BELOW;
244             }
245
246             if(!oldCueLine.equals(cueLine)) {
247                 paintImmediately(oldCueLine);
248             }
249
250             g2d.setColor(Color.black);
251             g2d.fill(cueLine);
252         }
253     }
254
255     public void dropActionChanged(DropTargetDragEvent event) {
256         if(event.getDropAction() != getDelegateConstants()) {
257             cleanUpAfterDrag();
258             event.rejectDrag();
259         } else
260             event.acceptDrag(getDelegateConstants());
261     }
262
263     public void dragExit(DropTargetEvent dte) {
264         cleanUpAfterDrag();
265     }
266
267     public void drop(DropTargetDropEvent event) {
268         autoExpandTimer.stop();
269
270         int x = (int)event.getLocation().getX();
271         int y = (int)event.getLocation().getY();
272         int row = getRowForLocation(x, y);
273         if(row == -1) {
274             cleanUpAfterDrag();
275             event.rejectDrop();
276             return;
277         }
278
279         Object JavaDoc targetObject = ((DefaultMutableTreeNode JavaDoc)(getPathForRow(row).getLastPathComponent())).getUserObject();
280
281         if(delegate.xjTreeDrop(this, getOldSelectedNode().getUserObject(), targetObject, dropLocation)) {
282             scrollPathToVisible(getPathForLocation(x, y));
283             event.acceptDrop(getDelegateConstants());
284             event.dropComplete(true);
285         } else
286             event.rejectDrop();
287         cleanUpAfterDrag();
288     }
289
290     // DragSourceListener interface method
291

292     public void dragEnter(DragSourceDragEvent dsde) {
293     }
294
295     public void dragOver(DragSourceDragEvent dsde) {
296     }
297
298     public void dropActionChanged(DragSourceDragEvent dsde) {
299     }
300
301     public void dragExit(DragSourceEvent dse) {
302     }
303
304     public void dragDropEnd(DragSourceDropEvent dsde) {
305     }
306
307 }
308
Popular Tags