1 package com.bonevich.erj.ui;
2
3 import com.bonevich.erj.model.*;
4 import com.bonevich.erj.ui.editor.SchemaEditor;
5 import com.bonevich.erj.ui.editor.RelationEditor;
6 import com.bonevich.util.dependency.Dynamic;
7 import com.bonevich.util.dependency.UpdateAction;
8 import com.bonevich.util.dependency.VisualDependent;
9
10 import org.tigris.gef.base.Cmd;
11 import org.tigris.gef.base.Editor;
12 import org.tigris.gef.base.Globals;
13 import org.tigris.gef.base.SelectionManager;
14 import org.tigris.gef.presentation.Fig;
15
16 import java.awt.dnd.*;
17 import java.awt.datatransfer.Transferable;
18 import java.awt.event.*;
19 import javax.swing.*;
20 import javax.swing.tree.*;
21 import javax.swing.event.*;
22
23 import java.util.*;
24
25 /***
26 *
27 * @author Jeffrey Bonevich <bonevich@telocity.com>
28 * @version $Id: ErjTree.html,v 1.1 2009/03/07 17:55:33 jbonevic Exp $
29 */
30 public class ErjTree extends JTree
31 implements DragGestureListener
32 {
33 //////////////////////////////////////////////////////////
34 // Attributes
35 private DefaultTreeModel _treeModel;
36 private List _expandedPaths = new LinkedList();
37
38 /*** The drag source listener for this tree. Note: this is an
39 * instance of DragSourceAdapter, a JDK1.4 class. */
40 private DragSourceListener _dragSrcListener = new DragSourceAdapter() {};
41
42 //////////////////////////////////////////////////////////
43 // Dependency sentries
44 private VisualDependent _dep_visibleTree;
45
46 public ErjTree(DefaultTreeModel model)
47 {
48 super(model);
49 _treeModel = model;
50 initUI();
51
52 // we initialize the dependent here cuz they must have access to
53 // the root from the model, which appears to be null before this point
54 _dep_visibleTree = new VisualDependent(
55 new UpdateAction()
56 {
57 public void onUpdate()
58 {
59 //System.err.println("(tree) nodes onUpdate called!");
60 Object rootNode = ErjTree.this._treeModel.getRoot();
61 if (rootNode instanceof ErjTreeNode)
62 {
63 ErjTreeNode node = (ErjTreeNode) rootNode;
64 node.checkDependents();
65 }
66 ErjTree.this.forceUpdate();
67 }
68 }
69 );
70
71 // register this tree as a drag source
72 DragSource dragSource = DragSource.getDefaultDragSource();
73 dragSource.createDefaultDragGestureRecognizer(
74 this, DnDConstants.ACTION_COPY_OR_MOVE, this
75 );
76
77 //FIXME: should also be a target, for attributes to be copied to relation nodes
78 }
79
80 public void expandPath(TreePath path)
81 {
82 super.expandPath(path);
83 if (path == null || _expandedPaths.contains(path)) return;
84 _expandedPaths.add(path);
85 }
86
87 public void collapsePath(TreePath path)
88 {
89 super.collapsePath(path);
90 if (path == null || !_expandedPaths.contains(path)) return;
91 _expandedPaths.remove(path);
92 }
93
94 private void initUI()
95 {
96 ErjTreeCellRenderer renderer = new ErjTreeCellRenderer();
97 setCellRenderer(renderer);
98 TreeCellEditor editor = new ErjTreeCellEditor(renderer);
99 setCellEditor(editor);
100 setEditable(true);
101 setAutoscrolls(true); //for drag-n-drop
102
103 setShowsRootHandles(true);
104 setRootVisible(true);
105 getSelectionModel().setSelectionMode(
106 TreeSelectionModel.SINGLE_TREE_SELECTION
107 );
108
109 putClientProperty("JTree.lineStyle", "Angled");
110 addListeners();
111 }
112
113 private void addListeners()
114 {
115 addMouseListener( new ErjTreeMouseListener() );
116
117 addTreeSelectionListener(
118 new TreeSelectionListener()
119 {
120 public void valueChanged(TreeSelectionEvent e)
121 {
122 ErjTreeNode cmp = (ErjTreeNode)getLastSelectedPathComponent();
123 if (cmp == null) return;
124
125 Object node = cmp.getUserObject();
126 if (node == null) return;
127 if (node instanceof Attribute) node = ((Attribute)node).getRelation();
128 if (node instanceof Relation || node instanceof ForeignKey)
129 {
130 Editor ce = Globals.curEditor();
131 SelectionManager sm = ce.getSelectionManager();
132 Fig f = ce.getLayerManager().presentationFor(node);
133 if (f != null)
134 {
135 sm.select(f);
136 }
137 }
138 }
139 }
140 );
141
142 addTreeExpansionListener(
143 new TreeExpansionListener()
144 {
145 public void treeCollapsed(TreeExpansionEvent e)
146 {
147 TreePath path = e.getPath();
148 ErjTreeNode node = (ErjTreeNode) path.getLastPathComponent();
149 }
150 public void treeExpanded(TreeExpansionEvent e)
151 {
152 TreePath path = e.getPath();
153 ErjTreeNode node = (ErjTreeNode) path.getLastPathComponent();
154 DefaultTreeModel m = (DefaultTreeModel)getModel();
155 m.nodeStructureChanged(node);
156 }
157 }
158 );
159
160 _treeModel.addTreeModelListener(
161 new TreeModelListener()
162 {
163 public void treeNodesInserted(TreeModelEvent e)
164 {
165 //System.err.println("(modelListener) treeNodesInserted called!");
166 TreePath path = e.getTreePath();
167 expandPath(path);
168 scrollPathToVisible(path);
169 makeVisible(path);
170 }
171 public void treeNodesRemoved(TreeModelEvent e)
172 {
173 //System.err.println("(modelListener) treeNodesRemoved called!");
174 }
175 public void treeNodesChanged(TreeModelEvent e)
176 {
177 //System.err.println("(modelListener) treeNodesChanged called!");
178 }
179 public void treeStructureChanged(TreeModelEvent e)
180 {
181 //System.err.println("(modelListener) treeStructureChanged called!");
182 }
183 }
184 );
185 }
186
187 private void forceUpdate()
188 {
189 _treeModel.nodeStructureChanged((TreeNode)_treeModel.getRoot());
190 Iterator paths = _expandedPaths.iterator();
191 while (paths.hasNext())
192 {
193 TreePath path = (TreePath) paths.next();
194 super.expandPath(path);
195 }
196 }
197
198 //////////////////////////////////////////////////////////
199 // DragGestureListener implementation
200 public void dragGestureRecognized(DragGestureEvent e)
201 {
202 TreePath path = getSelectionPath();
203 if (path != null)
204 {
205 ErjTreeNode node = (ErjTreeNode) path.getLastPathComponent();
206
207 if (node.isRelation() || node.isAttribute() || node.isForeignKey())
208 {
209 Transferable data = new TransferableModelElement((ModelElement) node.getUserObject());
210 // start the drag, but pass it a null Cursor - we want the
211 // UI peers to manage cursor swapping
212 e.startDrag(null, data, _dragSrcListener);
213 }
214 }
215 }
216
217 //////////////////////////////////////////////////////////
218 // Inner classes
219 class ErjTreeMouseListener extends MouseAdapter
220 {
221 public void mousePressed(MouseEvent e)
222 {
223 if (e.isPopupTrigger() ||
224 e.getModifiers() == InputEvent.BUTTON3_MASK)
225 {
226 TreePath path = getPathForLocation(e.getX(), e.getY());
227 if (path == null) return;
228
229 JPopupMenu popup = new JPopupMenu("");
230 setSelectionPath(path);
231 ErjTreeNode node = (ErjTreeNode) path.getLastPathComponent();
232 Enumeration actions = node.getPopUpActions(e).elements();
233 while (actions.hasMoreElements())
234 {
235 Object action = actions.nextElement();
236 if (action instanceof Action)
237 {
238 popup.add((Action) action);
239 }
240 else if (action instanceof JMenuItem)
241 {
242 popup.add((JMenuItem) action);
243 }
244 }
245 popup.show(ErjTree.this, e.getX(), e.getY() + 25);
246 e.consume();
247 }
248 }
249 } /*** end class ErjTreeMouseListener */
250
251 } /*** end class ErjTree */
This page was automatically generated by Maven