1
28 package demo.view.application;
29
30 import demo.view.DemoBase;
31 import demo.view.DemoDefaults;
32 import y.base.Node;
33 import y.geom.YInsets;
34 import y.layout.FixNodeLayoutStage;
35 import y.layout.LayoutOrientation;
36 import y.layout.NodeLabelModel;
37 import y.layout.hierarchic.IncrementalHierarchicLayouter;
38 import y.layout.hierarchic.incremental.SimplexNodePlacer;
39 import y.option.RealizerCellRenderer;
40 import y.util.DataProviders;
41 import y.view.CreateEdgeMode;
42 import y.view.Drawable;
43 import y.view.DropSupport;
44 import y.view.EditMode;
45 import y.view.GenericNodeRealizer;
46 import y.view.Graph2D;
47 import y.view.Graph2DLayoutExecutor;
48 import y.view.Graph2DView;
49 import y.view.Graph2DViewActions;
50 import y.view.HitInfo;
51 import y.view.LineType;
52 import y.view.MultiplexingNodeEditor;
53 import y.view.NodeRealizer;
54 import y.view.ShapeNodePainter;
55 import y.view.Graph2DListener;
56 import y.view.Graph2DEvent;
57 import y.view.NodeLabel;
58 import y.view.hierarchy.GenericGroupNodeRealizer;
59 import y.view.hierarchy.HierarchyManager;
60 import y.view.tabular.ColumnDropTargetListener;
61 import y.view.tabular.RowDropTargetListener;
62 import y.view.tabular.TableGroupNodeRealizer;
63 import y.view.tabular.TableGroupNodeRealizer.ColumnNodeLabelModel;
64 import y.view.tabular.TableGroupNodeRealizer.Column;
65 import y.view.tabular.TableGroupNodeRealizer.Row;
66 import y.view.tabular.TableGroupNodeRealizer.RowNodeLabelModel;
67 import y.view.tabular.TableLabelEditor;
68 import y.view.tabular.TableNodePainter;
69 import y.view.tabular.TableOrderEditor;
70 import y.view.tabular.TableSelectionEditor;
71 import y.view.tabular.TableSizeEditor;
72 import y.view.tabular.TableStyle;
73 import y.view.tabular.TableSupport;
74
75 import java.awt.BorderLayout;
76 import java.awt.Color;
77 import java.awt.Component;
78 import java.awt.Dimension;
79 import java.awt.EventQueue;
80 import java.awt.Graphics;
81 import java.awt.Graphics2D;
82 import java.awt.Paint;
83 import java.awt.Rectangle;
84 import java.awt.Stroke;
85 import java.awt.dnd.DnDConstants;
86 import java.awt.dnd.DragGestureEvent;
87 import java.awt.dnd.DragGestureListener;
88 import java.awt.dnd.DragSource;
89 import java.awt.event.ActionEvent;
90 import java.awt.geom.Rectangle2D;
91 import java.net.URL;
92 import java.util.Collection;
93 import java.util.Iterator;
94 import java.util.List;
95 import java.util.Locale;
96 import java.util.Map;
97 import javax.swing.AbstractAction;
98 import javax.swing.Action;
99 import javax.swing.ActionMap;
100 import javax.swing.DefaultListCellRenderer;
101 import javax.swing.Icon;
102 import javax.swing.InputMap;
103 import javax.swing.JComponent;
104 import javax.swing.JList;
105 import javax.swing.JToolBar;
106 import javax.swing.ListSelectionModel;
107 import javax.swing.ListCellRenderer;
108 import javax.swing.border.LineBorder;
109
110
127 public class SwimlaneDemo extends DemoBase {
128 static final String CONFIGURATION_GROUP_NODE = "CONFIGURATION_GROUP_NODE";
129 static final String CONFIGURATION_TABLE_NODE = "CONFIGURATION_TABLE_NODE";
130
131 static {
132 initConfigurations();
133 }
134
135
136 private YInsets rowInsets;
137 private YInsets columnInsets;
138 private MinimumSizeManager minimumSizeManager;
139
140
141 public static void main( String[] args ) {
142 EventQueue.invokeLater(new Runnable() {
143 public void run() {
144 Locale.setDefault(Locale.ENGLISH);
145 initLnF();
146 (new SwimlaneDemo("resource/swimlanehelp.html")).start();
147 }
148 });
149 }
150
151 public SwimlaneDemo() {
152 this(null);
153 }
154
155 public SwimlaneDemo( final String helpFilePath ) {
156 addHelpPane(helpFilePath);
157 }
158
159 private NodeRealizer createConfiguredNormalNodeRealizer() {
160 final NodeRealizer normalNode = view.getGraph2D().getDefaultNodeRealizer().createCopy();
161 normalNode.setSize(80, 50);
162 return normalNode;
163 }
164
165 private NodeRealizer createConfiguredGroupNodeRealizer() {
166 final GenericGroupNodeRealizer ggnr = new GenericGroupNodeRealizer();
167 ggnr.setConfiguration(CONFIGURATION_GROUP_NODE);
168 ggnr.setFillColor(null);
169 ggnr.setLineType(LineType.DASHED_DOTTED_1);
170 ggnr.removeLabel(ggnr.getLabel());
171 ggnr.setGroupClosed(false);
172 ggnr.setSize(80, 50);
173 return ggnr;
174 }
175
176 private NodeRealizer createConfiguredTableNodeRealizer() {
177 final TableGroupNodeRealizer tgnr = new TableGroupNodeRealizer();
178 tgnr.setConfiguration(CONFIGURATION_TABLE_NODE);
179
180 tgnr.setFillColor(new Color(236, 245, 255));
182
183 final Color columnFillColor = new Color(113, 146, 178);
185 tgnr.setStyleProperty(
186 TableNodePainter.COLUMN_STYLE_ID,
187 new TableStyle.SimpleStyle(
188 tgnr.getLineType(),
189 tgnr.getLineColor(),
190 columnFillColor,
191 null,
192 null,
193 columnFillColor
194 )
195 );
196
197 final LineType lt = tgnr.getLineType();
198 final Color columnSelectedFillColor = new Color(55, 93, 129);
199 tgnr.setStyleProperty(
200 TableNodePainter.COLUMN_SELECTION_STYLE_ID,
201 new TableStyle.SimpleStyle(
202 LineType.createLineType((int) Math.ceil(lt.getLineWidth()) + 2, lt.getLineStyle()),
203 tgnr.getLineColor(),
204 columnSelectedFillColor,
205 null,
206 null,
207 columnSelectedFillColor
208 )
209 );
210
211 tgnr.setDefaultColumnWidth(600);
215 tgnr.setDefaultMinimumColumnWidth(200);
216 tgnr.setDefaultColumnInsets(columnInsets);
217 tgnr.setDefaultRowHeight(150);
218 tgnr.setDefaultMinimumRowHeight(50);
219 tgnr.setDefaultRowInsets(rowInsets);
220 tgnr.setAutoResize(true);
221
222 final TableGroupNodeRealizer.Table table = tgnr.getTable();
223 table.setInsets(new YInsets(30, 0, 0, 0));
224
225 tgnr.setSize(250, 200);
226 return tgnr;
227 }
228
229
233 private static void initConfigurations() {
234 final GenericNodeRealizer.Factory factory = GenericNodeRealizer.getFactory();
235
236 final Map groupMap = createGroupNodeConfiguration();
237 factory.addConfiguration(CONFIGURATION_GROUP_NODE, groupMap);
238
239 final Map tableMap = createTableNodeConfiguration();
240 factory.addConfiguration(CONFIGURATION_TABLE_NODE, tableMap);
241 }
242
243 protected void initialize() {
244 new HierarchyManager(view.getGraph2D());
246
247 minimumSizeManager = new MinimumSizeManager(view.getGraph2D());
248
249 rowInsets = new YInsets(0, 30, 0, 0);
250 columnInsets = new YInsets(30, 5, 0, 5);
251 final DropSupport dropSupport = createDropSupport(view);
252
253 contentPane.add(createDragNDropList(dropSupport), BorderLayout.WEST);
254
255 loadGraph( "resource/SwimlaneDemo.graphml" );
256
257 view.getGraph2D().addDataProvider(
258 FixNodeLayoutStage.FIXED_NODE_DPKEY,
259 DataProviders.createConstantDataProvider(Boolean.TRUE));
260
261 view.setPreferredSize(new Dimension(950, 550));
262 view.fitContent();
263 view.updateView();
264 }
265
266 protected void loadGraph( final URL resource ) {
267 minimumSizeManager.setEnabled(false);
270 try {
271 super.loadGraph(resource);
272 } finally {
273 minimumSizeManager.setEnabled(true);
274 }
275 }
276
277 protected void registerViewActions() {
278 super.registerViewActions();
280
281 ActionMap amap = view.getCanvasComponent().getActionMap();
282 if (amap != null) {
283 if (isDeletionEnabled()) {
284 amap.put(Graph2DViewActions.DELETE_SELECTION, createDeleteSelectionActionImpl());
288 }
289 }
290 }
291
292 private static DropSupport createDropSupport(Graph2DView view) {
293 DropSupport dropSupport = new DropSupport(view) {
295
296 protected boolean dropNodeRealizer(Graph2DView view, NodeRealizer r, double worldCoordX, double worldCoordY) {
297 final HierarchyManager hm = HierarchyManager.getInstance(view.getGraph2D());
298 final HitInfo hitInfo = DemoBase.checkNodeHit(view, worldCoordX, worldCoordY);
299 if (hm != null &&
300 hitInfo.hasHitNodes()) {
301 final Node node = (Node) hitInfo.hitNodes().current();
302 if (hm.isGroupNode(node) &&
303 ! (r instanceof TableGroupNodeRealizer)) {
304 return super.dropNodeRealizer(view, r, worldCoordX, worldCoordY);
306 }
307 } else if (r instanceof TableGroupNodeRealizer) {
308 return super.dropNodeRealizer(view, r, worldCoordX, worldCoordY);
309 }
310 return false;
311 }
312 };
313 dropSupport.setSnappingEnabled(true);
314 dropSupport.getSnapContext().setNodeToNodeDistance(30);
315 dropSupport.getSnapContext().setNodeToEdgeDistance(20);
316 dropSupport.getSnapContext().setUsingSegmentSnapLines(true);
317 dropSupport.setPreviewEnabled(true);
318 return dropSupport;
319 }
320
321 private JList createDragNDropList(final DropSupport support) {
322 final Object[] listContent = new Object[] {
323 createConfiguredTableNodeRealizer(),
324 DropItemListCellRenderer.DROP_TYPE_ROW,
325 DropItemListCellRenderer.DROP_TYPE_COLUMN,
326 createConfiguredNormalNodeRealizer(),
327 createConfiguredGroupNodeRealizer()
328 };
329
330 final Color lightBlueFillColor = new Color(126, 179, 240, 128);
331 final Color unselectedBorderColor = new Color(58, 82, 109);
332 final Stroke borderStroke = LineType.LINE_1;
333
334 final DropDrawable rowIcon = new DropDrawable(unselectedBorderColor, lightBlueFillColor, borderStroke);
336 rowIcon.insets = new YInsets(0, 15, 0, 0);
337 rowIcon.setBounds(0, 0, 80, 50);
338
339 final DropDrawable columnIcon = new DropDrawable(unselectedBorderColor, lightBlueFillColor, borderStroke);
340 columnIcon.insets = new YInsets(15, 0, 0, 0);
341 columnIcon.setBounds(0, 0, 80, 50);
342
343 final DropItemListCellRenderer cellRenderer =
344 new DropItemListCellRenderer(columnIcon, rowIcon);
345
346 final JList dropItemList = new JList(listContent);
348 dropItemList.setCellRenderer(cellRenderer);
349 dropItemList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
350 dropItemList.setSelectedIndex(0);
351 dropItemList.setFixedCellHeight(100);
352 dropItemList.setFixedCellWidth(100);
353 dropItemList.setBorder(LineBorder.createBlackLineBorder());
354
355 final DragSource dragSource = new DragSource();
356
357 final RowDropTargetListener rowListener =
359 new RowDropTargetListener(view) {
360 DropDrawable drawable = new DropDrawable(unselectedBorderColor, lightBlueFillColor, borderStroke);
361
362 protected Drawable createDrawable(Rectangle2D bounds, YInsets insets) {
363 drawable.insets = insets;
364 drawable.setBounds(bounds);
365 return drawable;
366 }
367 };
368 rowListener.setDefaultHeight(50);
369 rowListener.setDefaultMinimumHeight(30);
370 rowListener.setDrawableWidth(200);
371 rowListener.setDefaultInsets(rowInsets);
372 rowListener.setMaxLevel(2);
373
374
375 final ColumnDropTargetListener columnListener =
376 new ColumnDropTargetListener(view) {
377 DropDrawable drawable = new DropDrawable(unselectedBorderColor, lightBlueFillColor, borderStroke);
378
379 protected Drawable createDrawable(Rectangle2D bounds, YInsets insets) {
380 drawable.insets = insets;
381 drawable.setBounds(bounds);
382 return drawable;
383 }
384 };
385 columnListener.setDefaultWidth(100);
386 columnListener.setDefaultMinimumWidth(200);
387 columnListener.setDrawableHeight(180);
388 columnListener.setDefaultInsets(columnInsets);
389 columnListener.setMaxLevel(2);
390
391
392 dragSource.createDefaultDragGestureRecognizer(dropItemList, DnDConstants.ACTION_MOVE,
394 new DragGestureListener() {
395 public void dragGestureRecognized(DragGestureEvent event) {
396 final Object value = dropItemList.getSelectedValue();
397 if (value.equals(DropItemListCellRenderer.DROP_TYPE_ROW)) {
398 support.startDrag(dragSource,
399 rowListener,
400 event,
401 DragSource.DefaultMoveDrop);
402 } else if (value.equals(DropItemListCellRenderer.DROP_TYPE_COLUMN)) {
403 support.startDrag(dragSource,
404 columnListener,
405 event,
406 DragSource.DefaultMoveDrop);
407 } else if (value instanceof NodeRealizer) {
408 NodeRealizer nr = (NodeRealizer) value;
409 support.startDrag(dragSource, nr, event, DragSource.DefaultMoveDrop);
410 }
411 }
412 });
413 return dropItemList;
414 }
415
416
417
422 protected EditMode createEditMode() {
423 final EditMode editMode = super.createEditMode();
424
425 editMode.getMouseInputMode().setNodeSearchingEnabled(true);
427
428 editMode.allowNodeCreation(false);
430
431 editMode.setSnappingEnabled(true);
433
434 editMode.setOrthogonalEdgeRouting(true);
436
437 final CreateEdgeMode cem = new CreateEdgeMode();
439 cem.setFuzzyTargetPortDetermination(true);
440 cem.setSnapToOrthogonalSegmentsDistance(5);
441 cem.setUsingNodeCenterSnapping(true);
442 cem.setSnappingOrthogonalSegments(true);
443 cem.setIndicatingTargetNode(true);
444 cem.setRemovingInnerBends(true);
445 cem.setOrthogonalEdgeCreation(true);
446 editMode.setCreateEdgeMode(cem);
447
448 return editMode;
449 }
450
451
454 protected JToolBar createToolBar() {
455 final JToolBar toolBar = super.createToolBar();
456
457 toolBar.addSeparator();
458
459 final AbstractAction layoutAction = new AbstractAction(
460 "Layout", SHARED_LAYOUT_ICON) {
461 public void actionPerformed( ActionEvent e ) {
462 layout(view.getGraph2D());
463 view.updateView();
464 }
465 };
466
467 toolBar.add(createActionControl(layoutAction));
468
469 return toolBar;
470 }
471
472
478 protected Action createLoadAction() {
479 final Action action = super.createLoadAction();
480 return new AbstractAction((String) action.getValue(Action.NAME)) {
481 public void actionPerformed( final ActionEvent e ) {
482 action.actionPerformed(e);
483 getUndoManager().resetQueue();
484 }
485 };
486 }
487
488
491 private void layout( final Graph2D graph ) {
492 graph.firePreEvent();
493 try {
494 graph.backupRealizers();
496
497 final IncrementalHierarchicLayouter ihl = new IncrementalHierarchicLayouter();
498 ihl.setLayoutOrientation(LayoutOrientation.LEFT_TO_RIGHT);
499 ihl.setOrthogonallyRouted(true);
500 ihl.setRecursiveGroupLayeringEnabled(false);
501 ((SimplexNodePlacer) ihl.getNodePlacer()).setBaryCenterModeEnabled(true);
502
503 final Graph2DLayoutExecutor layoutExecutor = new Graph2DLayoutExecutor(Graph2DLayoutExecutor.BUFFERED);
504 layoutExecutor.setConfiguringTableNodeRealizers(true);
505 layoutExecutor.getTableLayoutConfigurator().setCompactionEnabled(false);
506 layoutExecutor.getTableLayoutConfigurator().setHorizontalLayoutConfiguration(true);
507 layoutExecutor.doLayout(graph, new FixNodeLayoutStage(ihl));
508 } finally {
509 graph.firePostEvent();
510 }
511 }
512
513 protected Action createDeleteSelectionAction() {
514 final Action action = createDeleteSelectionActionImpl();
515 action.putValue(Action.SMALL_ICON, getIconResource("resource/delete.png"));
516 action.putValue(Action.SHORT_DESCRIPTION, "Delete Selection");
517 return action;
518 }
519
520 private Action createDeleteSelectionActionImpl() {
521 final Graph2DViewActions.DeleteSelectionAction action =
522 new Graph2DViewActions.DeleteSelectionAction(view);
523 action.setDeletionMask(Graph2DViewActions.DeleteSelectionAction.ALL_TYPES_MASK);
524 action.setKeepingTableNodesOnTableContentDeletion(true);
525 action.setKeepingParentGroupNodeSizes(true);
526 return action;
527 }
528
529 private static Map createGroupNodeConfiguration() {
530 final Map map = GenericGroupNodeRealizer.createDefaultConfigurationMap();
531 final ShapeNodePainter painter = new ShapeNodePainter(ShapeNodePainter.ROUND_RECT);
532 map.put(GenericNodeRealizer.ContainsTest.class, painter);
533 map.put(GenericNodeRealizer.Painter.class, painter);
534 map.put(GenericNodeRealizer.GenericMouseInputEditorProvider.class, null);
535 return map;
536 }
537
538 private static Map createTableNodeConfiguration() {
539 final Map map = TableGroupNodeRealizer.createDefaultConfigurationMap();
540
541 final AlternatingPainter rowPainter = new AlternatingPainter();
543 final TableNodePainter tableNodePainter = TableNodePainter.newDefaultInstance();
544 tableNodePainter.setSubPainter(TableNodePainter.PAINTER_ROW_BACKGROUND, rowPainter);
545 map.put(GenericNodeRealizer.Painter.class, tableNodePainter);
546
547 final MultiplexingNodeEditor editor = new MultiplexingNodeEditor();
549 final TableLabelEditor editLabelEditor = new TableLabelEditor();
550 editor.addNodeEditor(editLabelEditor);
551 final TableSelectionEditor tableSelectionEditor = new TableSelectionEditor();
552 tableSelectionEditor.setSelectionPolicy(TableSelectionEditor.RELATE_TO_NODE_SELECTION);
553 editor.addNodeEditor(tableSelectionEditor);
554 final TableSizeEditor resizeEditor = new TableSizeEditor();
555 editor.addNodeEditor(resizeEditor);
556 final TableOrderEditor tableOrderEditor = new TableOrderEditor();
557 tableOrderEditor.setMaxColumnLevel(2);
558 tableOrderEditor.setMaxRowLevel(2);
559 editor.addNodeEditor(tableOrderEditor);
560 map.put(GenericNodeRealizer.GenericMouseInputEditorProvider.class, editor);
561
562 return map;
563 }
564
565
573 private static final class MinimumSizeManager implements Graph2DListener {
574 private boolean enabled;
575
576 MinimumSizeManager( final Graph2D graph ) {
577 graph.addGraph2DListener(this);
578 enabled = true;
579 }
580
581 public boolean isEnabled() {
582 return enabled;
583 }
584
585 public void setEnabled( final boolean enabled ) {
586 this.enabled = enabled;
587 }
588
589 public void onGraph2DEvent( final Graph2DEvent e ) {
590 if (isEnabled()) {
591 if ("text".equals(e.getPropertyName())) {
592 final Object subject = e.getSubject();
593 if (subject instanceof NodeLabel) {
594 final NodeLabel label = (NodeLabel) subject;
595 final NodeLabelModel model = label.getLabelModel();
596 if (model instanceof ColumnNodeLabelModel) {
597 handleColumnLabelEvent(label);
598 } else if (model instanceof RowNodeLabelModel) {
599 handleRowLabelEvent(label);
600 }
601 }
602 }
603 }
604 }
605
606 private void handleRowLabelEvent( final NodeLabel label ) {
607 final Row row = RowNodeLabelModel.getRow(label);
608 if (row != null) {
609 final double h = label.getHeight() + 8;
610 if (h > row.getHeight()) {
611 (new TableSupport()).setHeight(row, h, false);
612 }
613 row.setMinimumHeight(Math.max(
614 h, ((TableGroupNodeRealizer) label.getRealizer())
615 .getDefaultMinimumRowHeight()));
616 }
617 }
618
619 private void handleColumnLabelEvent( final NodeLabel label ) {
620 final Column column = ColumnNodeLabelModel.getColumn(label);
621 if (column != null) {
622 final double w = label.getWidth() + 8;
623 if (w > column.getWidth()) {
624 (new TableSupport()).setWidth(column, w, false);
625 }
626 column.setMinimumWidth(Math.max(
627 w, ((TableGroupNodeRealizer) label.getRealizer())
628 .getDefaultMinimumColumnWidth()));
629 }
630 }
631 }
632
633
634
638
645 static final class AlternatingPainter extends ShapeNodePainter {
646 private static final Color PARENT_ROW_COLOR = new Color(113, 146, 178);
647 private static final Color EVEN_ROW_COLOR = new Color(196, 215, 237);
648 private static final Color ODD_ROW_COLOR = new Color(171, 200, 226);
649 private static final Color SELECTED_ROW_COLOR = new Color(55, 93, 129);
650
651 AlternatingPainter() {
652 super(ShapeNodePainter.RECT);
653 }
654
655 protected Paint getFillPaint( final NodeRealizer context, final boolean selected ) {
656 return getFillColor(context, selected);
657 }
658
659
667 protected Color getFillColor( final NodeRealizer context, final boolean selected ) {
668 final Row row = TableNodePainter.getRow(context);
669 if (row.isSelected()) {
670 return SELECTED_ROW_COLOR;
671 }
672
673 if (row.getRows().isEmpty()) {
674 if (indexOf(row, TableNodePainter.getTable(context).getRows(), new int[]{-1}) % 2 == 0) {
675 return EVEN_ROW_COLOR;
676 } else {
677 return ODD_ROW_COLOR;
678 }
679 } else {
680 return PARENT_ROW_COLOR;
681 }
682 }
683
684
687 public void paint(NodeRealizer context, Graphics2D graphics) {
688 if (!context.isVisible()){
689 return;
690 }
691 backupGraphics(graphics);
692 try {
693 paintNode(context, graphics, false);
694 } finally {
695 restoreGraphics(graphics);
696 }
697 }
698
699
706 private int indexOf( final Row row, final Collection rows, final int[] i ) {
707 for (Iterator it = rows.iterator(); it.hasNext();) {
708 final Row r = (Row) it.next();
709 final List children = r.getRows();
710 if (children.isEmpty()) {
711 ++i[0];
712 if (r.equals(row)) {
713 return i[0];
714 }
715 } else {
716 final int idx = indexOf(row, children, i);
717 if (idx > -1) {
718 return idx;
719 }
720 }
721 }
722
723 return -1;
724 }
725 }
726
727
731
735 static class DropDrawable implements Drawable, Icon {
736 Rectangle bounds;
737 YInsets insets;
738
739 Color borderColor;
740 Color fillColor;
741 Stroke stroke;
742
743
750 DropDrawable(Color borderColor, Color fillColor, Stroke stroke) {
751 this.borderColor = borderColor;
752 this.fillColor = fillColor;
753 this.stroke = stroke;
754 }
755
756
762 public void paint(Graphics2D g) {
763 g.setStroke(stroke);
764 paintIcon(null, g, bounds.x, bounds.y);
765 }
766
767
775 public void paintIcon(Component c, Graphics g, int x, int y) {
776 if (bounds == null ||
778 bounds.getX() != x ||
779 bounds.getY() != y) {
780 int newWidth = (bounds == null) ? 0 : bounds.width;
781 int newHeight = (bounds == null) ? 0 : bounds.height;
782 bounds = new Rectangle(x, y, newWidth, newHeight);
783 }
784
785 int cWidth = 0;
787 if (c != null) {
788 cWidth = c.getWidth() - 2;
789 }
790 int offX = (cWidth > getIconWidth()) ? (cWidth - getIconWidth())/2 : 0;
791
792 g.setColor(fillColor);
793 g.fillRect(bounds.x + offX, bounds.y, bounds.width, bounds.height);
794
795 g.setColor(borderColor);
796 g.drawRect(bounds.x + offX, bounds.y, bounds.width, bounds.height);
797
798 if (insets != null &&
799 (insets.top + insets.bottom < bounds.height &&
800 insets.left + insets.right < bounds.width)) {
801 g.setColor(fillColor);
802 g.fillRect((int) (bounds.x + offX + insets.left),
803 (int) (bounds.y + insets.top),
804 (int) (bounds.width - insets.left - insets.right),
805 (int) (bounds.height - insets.top - insets.bottom));
806 g.setColor(borderColor);
807 g.drawRect((int) (bounds.x + offX + insets.left),
808 (int) (bounds.y + insets.top),
809 (int) (bounds.width - insets.left - insets.right),
810 (int) (bounds.height - insets.top - insets.bottom));
811 }
812 }
813
814 public Rectangle getBounds() {
815 return bounds;
816 }
817
818
822 public void setBounds(Rectangle2D bounds) {
823 this.bounds = new Rectangle((int) bounds.getX(), (int) bounds.getY(),
824 (int) Math.ceil(bounds.getWidth()), (int) Math.ceil(bounds.getHeight()));
825 }
826
827
834 public void setBounds(int x, int y, int width, int height) {
835 this.bounds = new Rectangle(x, y, width, height);
836 }
837
838 public int getIconWidth() {
839 return bounds != null ? bounds.width : 0;
840 }
841
842 public int getIconHeight() {
843 return bounds != null ? bounds.height : 0;
844 }
845 }
846
847
851 static class DropItemListCellRenderer implements ListCellRenderer {
852
855 static final Object DROP_TYPE_ROW = "DROP_TYPE_ROW";
856
859 static final Object DROP_TYPE_COLUMN = "DROP_TYPE_COLUMN";
860
861
862 private static final Dimension PREFERRED_SIZE = new Dimension(100, 100);
863
864 private final DefaultListCellRenderer dlcr;
865 private final RealizerCellRenderer realizerRenderer;
866
867 private final Icon rowIcon;
868 private final Icon columnIcon;
869
870
876 DropItemListCellRenderer(
877 final Icon columnIcon,
878 final Icon rowIcon
879 ) {
880 this.columnIcon = columnIcon;
881 this.rowIcon = rowIcon;
882
883 realizerRenderer = new RealizerCellRenderer(
884 PREFERRED_SIZE.width, PREFERRED_SIZE.height);
885 dlcr = new DefaultListCellRenderer();
886 }
887
888 public Component getListCellRendererComponent(
889 JList list,
890 Object value,
891 int index,
892 boolean isSelected,
893 boolean cellHasFocus
894 ) {
895 if (value instanceof NodeRealizer) {
896 final Component c = realizerRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
897 if (c instanceof JComponent) {
898 if (value instanceof GenericNodeRealizer) {
899 final String configuration = ((GenericNodeRealizer) value).getConfiguration();
900 if (SwimlaneDemo.CONFIGURATION_GROUP_NODE.equals(configuration)) {
901 ((JComponent) c).setToolTipText("Create new group node");
902 }
903 if (SwimlaneDemo.CONFIGURATION_TABLE_NODE.equals(configuration)) {
904 ((JComponent) c).setToolTipText("Create new table node");
905 }
906 if (DemoDefaults.NODE_CONFIGURATION.equals(configuration)) {
907 ((JComponent) c).setToolTipText("Create new child node");
908 }
909 } else {
910 ((JComponent) c).setToolTipText("Create new node");
911 }
912 }
913 return c;
914 } else {
915 dlcr.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
916 dlcr.setText("");
917 dlcr.setPreferredSize(PREFERRED_SIZE);
918 if (DROP_TYPE_COLUMN.equals(value)) {
919 dlcr.setIcon(columnIcon);
920 dlcr.setToolTipText("Create new column");
921 } else if (DROP_TYPE_ROW.equals(value)) {
922 dlcr.setIcon(rowIcon);
923 dlcr.setToolTipText("Create new row");
924 } else {
925 dlcr.setIcon(null);
926 dlcr.setToolTipText(null);
927 }
928 return dlcr;
929 }
930 }
931 }
932 }
933