1
28 package demo.layout.tree;
29
30 import y.base.Node;
31 import y.base.NodeCursor;
32 import y.layout.tree.AbstractRotatableNodePlacer;
33 import y.layout.tree.AbstractRotatableNodePlacer.Matrix;
34 import y.layout.tree.AbstractRotatableNodePlacer.RootAlignment;
35 import y.layout.tree.BusPlacer;
36 import y.layout.tree.DoubleLinePlacer;
37 import y.layout.tree.GridNodePlacer;
38 import y.layout.tree.LeftRightPlacer;
39 import y.layout.tree.NodePlacer;
40 import y.layout.tree.SimpleNodePlacer;
41 import y.util.DataProviderAdapter;
42 import y.view.Arrow;
43 import y.view.EdgeRealizer;
44 import y.view.Graph2D;
45 import y.view.Graph2DSelectionEvent;
46 import y.view.Graph2DSelectionListener;
47 import y.view.LineType;
48 import y.view.PolyLineEdgeRealizer;
49
50 import javax.swing.DefaultComboBoxModel;
51 import javax.swing.DefaultListCellRenderer;
52 import javax.swing.JButton;
53 import javax.swing.JComboBox;
54 import javax.swing.JLabel;
55 import javax.swing.JList;
56 import javax.swing.JPanel;
57 import javax.swing.JSplitPane;
58 import java.awt.BorderLayout;
59 import java.awt.Component;
60 import java.awt.EventQueue;
61 import java.awt.FlowLayout;
62 import java.awt.GridBagConstraints;
63 import java.awt.GridBagLayout;
64 import java.awt.Insets;
65 import java.awt.event.ActionEvent;
66 import java.awt.event.ActionListener;
67 import java.awt.event.ItemEvent;
68 import java.awt.event.ItemListener;
69 import java.util.Locale;
70
71
78 public class RotatableNodePlacersDemo extends AbstractTreeDemo {
79 private JComboBox nodePlacerCombo;
80 private JComboBox rootAlignmentCombo;
81 private JButton rotLeftButton;
82 private JButton rotRightButton;
83 private JButton mirHorButton;
84 private JButton mirVertButton;
85
86 public static void main(String[] args) {
87 EventQueue.invokeLater(new Runnable() {
88 public void run() {
89 Locale.setDefault(Locale.ENGLISH);
90 initLnF();
91 (new RotatableNodePlacersDemo()).start();
92 }
93 });
94 }
95
96 public RotatableNodePlacersDemo() {
97 Graph2D graph = view.getGraph2D();
98
99
102 graph.addGraph2DSelectionListener(new Graph2DSelectionListener() {
103 public void onGraph2DSelectionEvent(Graph2DSelectionEvent e) {
104 if (view.getGraph2D().selectedNodes().ok()) {
105 readComboValues();
106 } else {
107 setEnabled(false);
108 }
109 }
110 });
111
112 EdgeRealizer defaultER = graph.getDefaultEdgeRealizer();
114 defaultER.setArrow(Arrow.STANDARD);
115 ((PolyLineEdgeRealizer) defaultER).setSmoothedBends(true);
116 defaultER.setLineType(LineType.LINE_2);
117
118
119 JPanel configPanel = new JPanel(new GridBagLayout());
120 GridBagConstraints constraints = new GridBagConstraints();
121
122 constraints.fill = GridBagConstraints.HORIZONTAL;
123 constraints.insets = new Insets(10, 10, 10, 10);
124 configPanel.add(new JLabel("Settings for actual selection"), constraints);
125
126 constraints.gridy = 1;
127 constraints.insets = new Insets(5, 5, 0, 0);
128 configPanel.add(new JLabel("NodePlacer:"), constraints);
129
130 constraints.gridy = 2;
131 constraints.insets = new Insets(0, 0, 0, 0);
132 nodePlacerCombo = new JComboBox();
133 nodePlacerCombo.setModel(new DefaultComboBoxModel(new String[]{"SimpleNodePlacer", "DoubleLinePlacer", "BusPlacer", "LeftRightPlacer", "GridNodePlacer"}));
134 nodePlacerCombo.addItemListener(new ItemListener() {
135 public void itemStateChanged(ItemEvent e) {
136 if (e.getStateChange() == ItemEvent.SELECTED) {
137 changeNodePlacersForSelection();
138 }
139 }
140 });
141 configPanel.add(nodePlacerCombo, constraints);
142
143 constraints.gridy = 3;
144 constraints.insets = new Insets(5, 5, 0, 0);
145 configPanel.add(new JLabel("Rotation:"), constraints);
146
147 constraints.gridy = 4;
148 constraints.insets = new Insets(0, 0, 0, 0);
149
150 JPanel rotationPanel = new JPanel();
151 configPanel.add(rotationPanel, constraints);
152 rotationPanel.setLayout(new FlowLayout());
153 rotLeftButton = new JButton("Left");
154 rotLeftButton.addActionListener(new ActionListener() {
155 public void actionPerformed(ActionEvent e) {
156 rotate(Matrix.ROT90);
157 }
158 });
159 rotationPanel.add(rotLeftButton);
160 rotRightButton = new JButton("Right");
161 rotRightButton.addActionListener(new ActionListener() {
162 public void actionPerformed(ActionEvent e) {
163 rotate(Matrix.ROT270);
164 }
165 });
166 rotationPanel.add(rotRightButton);
167
168 constraints.gridy = 6;
169 rotationPanel = new JPanel();
170 configPanel.add(rotationPanel, constraints);
171 rotationPanel.setLayout(new FlowLayout());
172 mirHorButton = new JButton("Mir Hor");
173 mirHorButton.addActionListener(new ActionListener() {
174 public void actionPerformed(ActionEvent e) {
175 rotate(Matrix.MIR_HOR);
176 }
177 });
178 rotationPanel.add(mirHorButton);
179 mirVertButton = new JButton("Mir Vert");
180 mirVertButton.addActionListener(new ActionListener() {
181 public void actionPerformed(ActionEvent e) {
182 rotate(Matrix.MIR_VERT);
183 }
184 });
185 rotationPanel.add(mirVertButton);
186
187
188 constraints.gridy = 7;
189 constraints.insets = new Insets(5, 5, 0, 0);
190 configPanel.add(new JLabel("Root Alignment:"), constraints);
191
192 constraints.gridy = 8;
193 constraints.insets = new Insets(0, 0, 0, 0);
194 rootAlignmentCombo = new JComboBox();
195
196 rootAlignmentCombo.addItem(AbstractRotatableNodePlacer.RootAlignment.CENTER);
197 rootAlignmentCombo.addItem(AbstractRotatableNodePlacer.RootAlignment.CENTER_OVER_CHILDREN);
198 rootAlignmentCombo.addItem(AbstractRotatableNodePlacer.RootAlignment.MEDIAN);
199 rootAlignmentCombo.addItem(AbstractRotatableNodePlacer.RootAlignment.LEADING);
200 rootAlignmentCombo.addItem(AbstractRotatableNodePlacer.RootAlignment.LEFT);
201 rootAlignmentCombo.addItem(AbstractRotatableNodePlacer.RootAlignment.RIGHT);
202 rootAlignmentCombo.addItem(AbstractRotatableNodePlacer.RootAlignment.TRAILING);
203 rootAlignmentCombo.addItemListener(new ItemListener() {
204 public void itemStateChanged(ItemEvent e) {
205 if (e.getStateChange() == ItemEvent.SELECTED) {
206 changeNodePlacersForSelection();
207 }
208 }
209 });
210 rootAlignmentCombo.setRenderer(new DefaultListCellRenderer() {
211 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
212 boolean cellHasFocus) {
213 JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
214 RootAlignment rootAlignment = (RootAlignment) value;
215 if (rootAlignment == RootAlignment.CENTER) {
216 label.setText("Center");
217 }
218 if (rootAlignment == RootAlignment.LEADING) {
219 label.setText("Leading");
220 }
221 if (rootAlignment == RootAlignment.LEFT) {
222 label.setText("Left");
223 }
224 if (rootAlignment == RootAlignment.RIGHT) {
225 label.setText("Right");
226 }
227 if (rootAlignment == RootAlignment.TRAILING) {
228 label.setText("Trailing");
229 }
230 if (rootAlignment == RootAlignment.MEDIAN) {
231 label.setText("Median");
232 }
233 if (rootAlignment == RootAlignment.CENTER_OVER_CHILDREN) {
234 label.setText("Center over children");
235 }
236 return label;
237 }
238 });
239 configPanel.add(rootAlignmentCombo, constraints);
240
241 JPanel left = new JPanel(new BorderLayout());
242 left.add(configPanel, BorderLayout.NORTH);
243
244 JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, view);
245 sp.setOneTouchExpandable(true);
246 sp.setContinuousLayout(false);
247 contentPane.add(sp, BorderLayout.CENTER);
248 createSampleGraph(graph);
249
250 graph.addDataProvider(GridNodePlacer.GRID_DPKEY, new DataProviderAdapter() {
252 public int getInt( final Object dataHolder ) {
253 final int idx = indexOf((Node) dataHolder);
254 if (idx < 0) {
255 return 0;
256 } else {
257 return idx / 5;
258 }
259 }
260
261 private int indexOf( final Node child ) {
262 int i = 0;
263 final Node parent = child.firstInEdge().source();
264 for (NodeCursor nc = parent.successors(); nc.ok(); nc.next()) {
265 if (nc.node() == child) {
266 return i;
267 }
268 ++i;
269 }
270 return -1;
271 }
272 });
273
274 setEnabled(false);
275
276 createSampleGraph(view.getGraph2D());
277 calcLayout();
278
279 graph.addDataProvider(LeftRightPlacer.LEFT_RIGHT_DPKEY, new LeftRightPlacer.LeftRightDataProvider(nodePlacerMap));
281 }
282
283
287 private void setEnabled(boolean enabled) {
288 rootAlignmentCombo.setEnabled(enabled);
289 rotLeftButton.setEnabled(enabled);
290 rotRightButton.setEnabled(enabled);
291 mirHorButton.setEnabled(enabled);
292 mirVertButton.setEnabled(enabled);
293 nodePlacerCombo.setEnabled(enabled);
294 }
295
296
300 private void rotate(Matrix rotation) {
301 for (NodeCursor nodeCursor = view.getGraph2D().selectedNodes(); nodeCursor.ok(); nodeCursor.next()) {
302 Node node = nodeCursor.node();
303 AbstractRotatableNodePlacer oldPlacer = (AbstractRotatableNodePlacer) nodePlacerMap.get(node);
304 Matrix matrix = oldPlacer == null ? rotation.multiply(Matrix.DEFAULT) : rotation.multiply(oldPlacer.getModificationMatrix());
305
306 AbstractRotatableNodePlacer placer = createPlacerFromComboBox(matrix);
307 nodePlacerMap.set(node, placer);
308 }
309 calcLayout();
310 }
311
312
315 private boolean blockLayout;
316
317
320 private void readComboValues() {
321 blockLayout = true;
322
323 setEnabled(true);
324
325 NodeCursor nodeCursor = view.getGraph2D().selectedNodes();
326 if (!nodeCursor.ok()) {
327 setEnabled(false);
328 } else {
329 Node node = nodeCursor.node();
330
331 AbstractRotatableNodePlacer nodePlacer = (AbstractRotatableNodePlacer) nodePlacerMap.get(node);
332 if (nodePlacer == null) {
333 return;
334 }
335
336 if (nodePlacer instanceof SimpleNodePlacer) {
337 rootAlignmentCombo.setEnabled(true);
338 rootAlignmentCombo.setSelectedItem(((SimpleNodePlacer) nodePlacer).getRootAlignment());
339 nodePlacerCombo.setSelectedIndex(0);
340 } else if (nodePlacer instanceof DoubleLinePlacer) {
341 rootAlignmentCombo.setEnabled(true);
342 rootAlignmentCombo.setSelectedItem(((DoubleLinePlacer) nodePlacer).getRootAlignment());
343 nodePlacerCombo.setSelectedIndex(1);
344 } else if (nodePlacer instanceof BusPlacer){
345 rootAlignmentCombo.setEnabled(false);
346 nodePlacerCombo.setSelectedIndex(2);
347 } else if (nodePlacer instanceof LeftRightPlacer){
348 rootAlignmentCombo.setEnabled(false);
349 nodePlacerCombo.setSelectedIndex(3);
350 }else if (nodePlacer instanceof GridNodePlacer){
351 rootAlignmentCombo.setEnabled(true);
352 rootAlignmentCombo.setSelectedItem(((GridNodePlacer) nodePlacer).getRootAlignment());
353 nodePlacerCombo.setSelectedIndex(4);
354 }
355 }
356
357 blockLayout = false;
358 }
359
360
363 private void changeNodePlacersForSelection() {
364 if (blockLayout) {
365 return;
366 }
367
368 for (NodeCursor nodeCursor = view.getGraph2D().selectedNodes(); nodeCursor.ok(); nodeCursor.next()) {
369 Node node = nodeCursor.node();
370 AbstractRotatableNodePlacer oldPlacer = (AbstractRotatableNodePlacer) nodePlacerMap.get(node);
371 Matrix matrix = oldPlacer != null ? oldPlacer.getModificationMatrix() : AbstractRotatableNodePlacer.Matrix.DEFAULT;
372
373 AbstractRotatableNodePlacer placer = createPlacerFromComboBox(matrix);
374 nodePlacerMap.set(node, placer);
375 }
376 calcLayout();
377 }
378
379
385 private AbstractRotatableNodePlacer createPlacerFromComboBox(Matrix modificationMatrix ) {
386 RootAlignment rootAlignment = (RootAlignment) rootAlignmentCombo.getSelectedItem();
387 AbstractRotatableNodePlacer placer = null;
388 int selection = nodePlacerCombo.getSelectedIndex();
389 switch (selection){
390 case 0:
391 placer =new SimpleNodePlacer(modificationMatrix);
392 ((SimpleNodePlacer) placer).setRootAlignment(rootAlignment);
393 rootAlignmentCombo.setEnabled(true);
394 break;
395 case 1:
396 placer = new DoubleLinePlacer(modificationMatrix);
397 ((DoubleLinePlacer) placer).setRootAlignment(rootAlignment);
398 rootAlignmentCombo.setEnabled(true);
399 break;
400 case 2:
401 placer = new BusPlacer(modificationMatrix);
402 rootAlignmentCombo.setEnabled(false);
403 break;
404 case 3:
405 placer = new LeftRightPlacer(modificationMatrix);
406 rootAlignmentCombo.setEnabled(false);
407 break;
408 case 4:
409 placer = new GridNodePlacer(modificationMatrix, rootAlignment);
410 rootAlignmentCombo.setEnabled(true);
411 break;
412 }
413 return placer;
414 }
415
416
420 protected boolean isDeletionEnabled() {
421 return false;
422 }
423
424
428 protected boolean isClipboardEnabled() {
429 return false;
430 }
431
432
436 private void createSampleGraph(Graph2D graph) {
437 graph.clear();
438 Node root = graph.createNode();
439 graph.getRealizer(root).setFillColor(layerColors[0]);
440 nodePlacerMap.set(root, new SimpleNodePlacer());
441 createChildren(graph, root);
442 calcLayout();
443 }
444
445 private void createChildren(Graph2D graph, Node root) {
446 for (int i = 0; i < 5; i++) {
447 Node child = graph.createNode();
448 graph.createEdge(root, child);
449 graph.getRealizer(child).setFillColor(layerColors[1]);
450 SimpleNodePlacer nodePlacer = new SimpleNodePlacer(Matrix.MIR_VERT_ROT90);
451 nodePlacer.setRootAlignment(RootAlignment.LEADING);
452 nodePlacerMap.set(child, nodePlacer);
453 switch (i){
454 case 0: createSimpleNodePlacerBranch(graph, child); break;
455 case 1: createDoubleLinePlacerBranch(graph, child); break;
456 case 2: createBusPlacerBranch(graph, child); break;
457 case 3: createLeftRightPlacerBranch(graph, child); break;
458 case 4: createGridNodePlacerBranch(graph, child); break;
459 }
460 }
461 }
462
463 private void createLeafs(Graph2D graph, Node root, int number){
464 for (int i = 0; i < number; i++) {
465 Node child = graph.createNode();
466 graph.createEdge(root, child);
467 graph.getRealizer(child).setFillColor(layerColors[3]);
468 SimpleNodePlacer nodePlacer = new SimpleNodePlacer( Matrix.DEFAULT);
469 nodePlacerMap.set(child, nodePlacer);
470 }
471 }
472
473 private void createSimpleNodePlacerBranch(Graph2D graph, Node root){
474 for (int i = 0; i < 4; i++) {
475 Node child = graph.createNode();
476 graph.createEdge(root, child);
477 graph.getRealizer(child).setFillColor(layerColors[2]);
478 Matrix rotation = Matrix.DEFAULT;
479 switch (i){
480 case 1:
481 rotation = Matrix.MIR_HOR; break;
482 case 2:
483 rotation = Matrix.ROT180; break;
484 case 3:
485 rotation = Matrix.MIR_HOR; break;
486 }
487 SimpleNodePlacer nodePlacer = new SimpleNodePlacer(rotation);
488 nodePlacer.setRootAlignment(RootAlignment.LEADING);
489 nodePlacerMap.set(child, nodePlacer);
490 createLeafs(graph, child, 3);
491 }
492 }
493
494 private void createDoubleLinePlacerBranch(Graph2D graph, Node root){
495 for (int i = 0; i < 3; i++) {
496 Node child = graph.createNode();
497 graph.createEdge(root, child);
498 graph.getRealizer(child).setFillColor(layerColors[2]);
499 Matrix rotation = Matrix.DEFAULT;
500 switch (i){
501 case 1:
502 rotation = Matrix.ROT90; break;
503 case 2:
504 rotation = Matrix.MIR_VERT_ROT90; break;
505 }
506 DoubleLinePlacer nodePlacer = new DoubleLinePlacer(rotation);
507 nodePlacer.setRootAlignment(RootAlignment.LEADING);
508 nodePlacerMap.set(child, nodePlacer);
509 createLeafs(graph, child, 5);
510 }
511 }
512
513 private void createBusPlacerBranch(Graph2D graph, Node root){
514 for (int i = 0; i < 3; i++) {
515 Node child = graph.createNode();
516 graph.createEdge(root, child);
517 graph.getRealizer(child).setFillColor(layerColors[2]);
518 Matrix rotation = Matrix.DEFAULT;
519 switch (i){
520 case 1:
521 rotation = Matrix.MIR_HOR; break;
522 case 2:
523 rotation = Matrix.ROT180; break;
524 }
525 BusPlacer nodePlacer = new BusPlacer(rotation);
526 nodePlacerMap.set(child, nodePlacer);
527 createLeafs(graph, child, 5);
528 }
529 }
530
531 private void createLeftRightPlacerBranch(Graph2D graph, Node root){
532 for (int i = 0; i < 2; i++) {
533 Node child = graph.createNode();
534 graph.createEdge(root, child);
535 graph.getRealizer(child).setFillColor(layerColors[2]);
536 Matrix rotation = Matrix.DEFAULT;
537 switch (i){
538 case 1:
539 rotation = Matrix.ROT90; break;
540 }
541 LeftRightPlacer nodePlacer = new LeftRightPlacer(rotation);
542 nodePlacerMap.set(child, nodePlacer);
543 createLeafs(graph, child, 5);
544 }
545 }
546
547 private void createGridNodePlacerBranch(Graph2D graph, Node root){
548 Node child = graph.createNode();
549 graph.createEdge(root, child);
550 graph.getRealizer(child).setFillColor(layerColors[2]);
551 GridNodePlacer nodePlacer = new GridNodePlacer();
552 nodePlacer.setRootAlignment(RootAlignment.LEADING);
553 nodePlacerMap.set(child, nodePlacer);
554 createLeafs(graph, child, 20);
555 }
556 }
557