1 package com.bonevich.erj.diagram;
2
3 import com.bonevich.erj.model.*;
4 import com.bonevich.erj.ui.*;
5 import com.bonevich.erj.ui.editor.RelationEditor;
6 import com.bonevich.erj.ErjConstants;
7 import com.bonevich.util.dependency.Dependent;
8 import com.bonevich.util.dependency.VisualDependent;
9 import com.bonevich.util.dependency.UpdateAction;
10
11 import org.tigris.gef.graph.*;
12 import org.tigris.gef.base.*;
13 import org.tigris.gef.presentation.*;
14
15 import java.awt.*;
16 import java.awt.event.*;
17 import javax.swing.*;
18 import java.util.*;
19
20 /***
21 * A subclass of FigNode that presents tht view of a Relation
22 */
23 public class FigRelation extends FigNode implements ErjConstants
24 {
25 ////////////////////////////////////////////////////////////////
26 // Constants
27 public static final int ROUTING_MARGIN = 18;
28
29 ////////////////////////////////////////////////////////////////
30 // Attributes
31 private FigText _name;
32 private FigGroup _attr;
33 private Fig _bigPort;
34 private JMenu _editMenu;
35 private Action _editRel;
36 private Action _editAttrs;
37 private Action _editKeys;
38 private Action _addAttr;
39 private Action _addKey;
40 private Action _dispose;
41 private boolean _menuInitialized = false;
42
43 //////////////////////////////////////////////////////////
44 // Dependency attributes
45 private Dependent _dep_name = new Dependent(
46 new UpdateAction()
47 {
48 public void onUpdate()
49 {
50 Relation node = (Relation) getOwner();
51 if (node != null)
52 {
53 updateName(node);
54 }
55 }
56 }
57 );
58
59 private Dependent _dep_attr = new Dependent(
60 new UpdateAction()
61 {
62 public void onUpdate()
63 {
64 Relation node = (Relation) getOwner();
65 if (node != null)
66 {
67 updateAttributes(node);
68 }
69 }
70 }
71 );
72
73 private VisualDependent _dep_visibleRelation = new VisualDependent(
74 new UpdateAction()
75 {
76 public void onUpdate()
77 {
78 _dep_name.onGet();
79 _dep_attr.onGet();
80 }
81 }
82 );
83
84 ////////////////////////////////////////////////////////////////
85 // Constructors
86 public FigRelation()
87 {
88 super();
89
90 // N.B. the bounds given below are the initial bounds of this fig relative to
91 // the parent diagram; they are changed after the node is placed
92 _bigPort = new FigRect(10, 10, 30, 35, LABEL_COLOR, SUBLABEL_FILL);
93 _name = new FigText(10, 10, 30, 23);
94 _attr = new FigContainer(10, 23, 30, 12);
95
96 addFig(_bigPort);
97 addFig(_name);
98 addFig(_attr);
99 }
100
101 public FigRelation(GraphModel gm, Object node)
102 {
103 this();
104 setOwner(node);
105 }
106
107 //////////////////////////////////////////////////////////
108 // Operations
109 public void setOwner(Object own)
110 {
111 super.setOwner(own);
112 if (!(own instanceof Relation))
113 {
114 return;
115 }
116 bindPort(own, _bigPort);
117 }
118
119 public void delete()
120 {
121 _attr.delete();
122 super.delete();
123 }
124
125 public void dispose()
126 {
127 Relation r = (Relation)getOwner();
128 Schema s = r.getSchema();
129 s.deleteRelation(r);
130 super.dispose();
131 }
132
133 private void updateName(Relation node)
134 {
135 _name.setAllowsTab(false);
136 _name.setFont(LABEL_FONT);
137 _name.setJustification(FigText.JUSTIFY_CENTER);
138 _name.setLineWidth(1);
139 _name.setMultiLine(false);
140 _name.setTextColor(LABEL_COLOR);
141 _name.setFilled(true);
142 _name.setFillColor(LABEL_FILL);
143 _name.setTextFillColor(LABEL_FILL);
144 _name.setText(node.getIdentifier().toUpperCase());
145 updateBounds();
146 }
147
148 private void updateAttributes(Relation node)
149 {
150 // FIXME: need to improve on this - why reload every
151 // attribute every time
152 _attr.setLineWidth(0);
153 _attr.setFilled(true);
154 _attr.setFillColor(SUBLABEL_FILL);
155 Iterator attributes = node.getAttributeIterator();
156 if (attributes.hasNext())
157 {
158 _attr.removeAll();
159 while (attributes.hasNext())
160 {
161 Attribute attr = (Attribute)attributes.next();
162 FigAttribute attrFig = new FigAttribute(attr);
163 _attr.addFig(attrFig);
164 }
165 }
166 updateBounds();
167 }
168
169 public Vector getPopUpActions(MouseEvent e)
170 {
171 Vector actions = super.getPopUpActions(e);
172 if (!_menuInitialized)
173 {
174 Relation r = (Relation) getOwner();
175 _editRel = new CmdEditRelation(r, RelationEditor.MODE_EDIT_RELATION);
176 _editAttrs = new CmdEditRelation(r, RelationEditor.MODE_EDIT_ATTRIBUTES);
177 _editKeys = new CmdEditRelation(r, RelationEditor.MODE_EDIT_KEYS);
178 _addAttr = new CmdCreateAttribute(r);
179 _addKey = new CmdCreateKey(r);
180 _dispose = new CmdDeleteRelation(r);
181
182 _editMenu = new JMenu("Relation",false);
183 _editMenu.add(_editRel);
184 _editMenu.add(_editAttrs);
185 _editMenu.add(_editKeys);
186
187 _menuInitialized = true;
188 }
189 actions.addElement(_editMenu);
190 actions.addElement(_addAttr);
191 actions.addElement(_addKey);
192 actions.addElement(_dispose);
193 return actions;
194 }
195
196 public Dimension getMinimumSize()
197 {
198 Dimension nameMin = _name.getMinimumSize();
199 Dimension attrMin = _attr.getMinimumSize();
200
201 int h = nameMin.height + attrMin.height;
202 int w = Math.max(nameMin.width, attrMin.width);
203 return new Dimension(w, h);
204 }
205
206 public void setBounds(int x, int y, int w, int h)
207 {
208 Rectangle oldBounds = getBounds();
209
210 // calculate the max width and the cumulative height
211 // of all the figs grouped in this node
212 int maxWidth = w;
213 int maxHeight = h;
214 maxWidth = Math.max(getMinimumSize().width, maxWidth);
215 maxHeight = Math.max(getMinimumSize().height, maxHeight);
216
217 int currentY = y;
218 int nameHeight = _name.getMinimumSize().height;
219 _name.setBounds(x, currentY, maxWidth, nameHeight);
220 currentY += nameHeight;
221 _attr.setBounds(x, currentY, maxWidth, maxHeight - nameHeight);
222
223 _bigPort.setBounds(x, y, maxWidth, maxHeight);
224
225 calcBounds(); //this is super.calcBounds really - figures out a bounding box for all figs
226 updateEdges();
227 firePropChange("bounds", oldBounds, getBounds());
228 }
229
230 private void updateBounds()
231 {
232 setBounds(getBounds());
233 startTrans();
234 }
235
236 /*** Reply a rectangle that arcs should not route through. Basically
237 * this is the bounding box plus some margin around all egdes. */
238 public Rectangle routingRect()
239 {
240 return new Rectangle(_x-ROUTING_MARGIN, _y-ROUTING_MARGIN, _w+ROUTING_MARGIN*2, _h+ROUTING_MARGIN*2);
241 }
242
243 ////////////////////////////////////////////////////////////////
244 // diagram-level operations
245
246 /*** Reply the point's sector within the current view. This version
247 * works with both square and non-square FigNodes.
248 *
249 * <pre>Sectors
250 * \ 1 /
251 * \ /
252 * \ /
253 * 2 \/ -2
254 * /\
255 * / \
256 * / \
257 * / -1 \ </pre>
258 **/
259 public int getSector(Point p)
260 {
261 if (p != null) {
262 Rectangle nodeBBox = getBounds();
263 double ang = getAngleInRadians(nodeBBox,p);
264
265 double ang0 = 2 * Math.PI - getAngleInRadians(nodeBBox,new Point(nodeBBox.x, nodeBBox.y));
266 double ang1 = Math.PI - ang0;
267 double ang2 = Math.PI + ang0;
268 double ang3 = 2 * Math.PI - ang0;
269
270 if (ang < ang0) return 2;
271 else if (ang < ang1) return 1;
272 else if (ang < ang2) return -2;
273 else if (ang < ang3) return -1;
274 else return 2;
275 }
276 return -1;
277 }
278
279 private double getAngleInRadians(Rectangle r, Point p)
280 {
281 int rCenterX = r.x + r.width / 2;
282 int rCenterY = r.y + r.height / 2;
283
284 int dx = (p.x - rCenterX);
285 int dy = (p.y - rCenterY);
286 double dist = Math.sqrt(dx * dx + dy * dy);
287
288 double ang;
289 if (dy > 0) {
290 ang = Math.acos(dx / dist);
291 } else {
292 ang = Math.acos(dx / dist) + Math.PI;
293 }
294 return ang;
295 }
296
297 //////////////////////////////////////////////////////////
298 // Event handling
299 /*** Open the default editor for this node's Relation. */
300 public void mouseClicked(MouseEvent e)
301 {
302 if (e.isConsumed()) return;
303 if (e.getClickCount() >= 2)
304 {
305 Relation node = (Relation) getOwner();
306 CmdEditRelation editor = new CmdEditRelation(node, RelationEditor.MODE_EDIT_RELATION);
307 editor.invoke();
308 e.consume();
309 }
310 }
311
312 } /* end class FigRelation */
This page was automatically generated by Maven