1
28 package demo.view.realizer;
29
30 import demo.view.DemoBase;
31 import demo.view.application.DragAndDropDemo;
32 import y.geom.YDimension;
33 import y.view.AbstractCustomHotSpotPainter;
34 import y.view.AbstractCustomNodePainter;
35 import y.view.BevelNodePainter;
36 import y.view.EditMode;
37 import y.view.GeneralPathNodePainter;
38 import y.view.GenericNodeRealizer;
39 import y.view.ImageNodePainter;
40 import y.view.NodeLabel;
41 import y.view.NodeRealizer;
42 import y.view.ShadowNodePainter;
43 import y.view.ShapeNodePainter;
44 import y.view.ShinyPlateNodePainter;
45 import y.view.SimpleUserDataHandler;
46 import y.view.SmartNodeLabelModel;
47 import y.view.YRenderingHints;
48
49 import javax.swing.Icon;
50 import javax.swing.ImageIcon;
51 import javax.swing.JList;
52 import javax.swing.JScrollPane;
53 import java.awt.BasicStroke;
54 import java.awt.BorderLayout;
55 import java.awt.Color;
56 import java.awt.Component;
57 import java.awt.EventQueue;
58 import java.awt.GradientPaint;
59 import java.awt.Graphics;
60 import java.awt.Graphics2D;
61 import java.awt.Paint;
62 import java.awt.Shape;
63 import java.awt.Stroke;
64 import java.awt.geom.Area;
65 import java.awt.geom.Ellipse2D;
66 import java.awt.geom.GeneralPath;
67 import java.awt.geom.Rectangle2D;
68 import java.awt.geom.RectangularShape;
69 import java.awt.geom.RoundRectangle2D;
70 import java.net.URL;
71 import java.util.ArrayList;
72 import java.util.Iterator;
73 import java.util.List;
74 import java.util.Locale;
75 import java.util.Map;
76
77
86 public class GenericNodeRealizerDemo extends DemoBase {
87
88
89 public GenericNodeRealizerDemo() {
90 super();
91
92 List configurations = createConfigurations();
94
95 JList realizerList = createDnDList(configurations);
97 realizerList.setBackground(Color.WHITE);
98
99 contentPane.add(new JScrollPane(realizerList), BorderLayout.WEST);
101
102 realizerList.setSelectedIndex(0);
103 GenericNodeRealizer gnr = (GenericNodeRealizer) realizerList.getSelectedValue();
104
105 view.getGraph2D().setDefaultNodeRealizer(gnr.createCopy());
106
107 loadGraph("resource/genericNodeRealizer.graphml");
109 }
110
111
115 private JList createDnDList(List configurations) {
116
118 final List realizers = createRealizers(configurations);
119 return new DragAndDropDemo.DragAndDropSupport(realizers, view).getList();
121 }
122
123
128 private List createConfigurations() {
129 List configNames = new ArrayList();
130
131 GenericNodeRealizer.Factory factory = GenericNodeRealizer.getFactory();
133
134 String configName = "Simple Rectangle";
136 factory.addConfiguration(configName, createSimpleRectangleConfiguration(factory));
137 configNames.add(configName);
138
139 configName = "Diamond";
141 factory.addConfiguration(configName, createDiamondConfiguration(factory));
142 configNames.add(configName);
143
144 configName = "Ellipse";
146 factory.addConfiguration(configName, createEllipseConfiguration(factory));
147 configNames.add(configName);
148
149 configName = "Circle";
150 factory.addConfiguration(configName, createCircleConfiguration(factory));
151 configNames.add(configName);
152
153 configName = "Bevel";
155 factory.addConfiguration(configName, createBevelNodeConfiguration(factory));
156 configNames.add(configName);
157
158 configName = "Shiny Plate";
160 factory.addConfiguration(configName, createShinyPlateNodeConfiguration(factory));
161 configNames.add(configName);
162
163 Map roundRectConfiguration = createRoundRectConfiguration(factory);
165 configName = "Round Rectangle";
166 factory.addConfiguration(configName, roundRectConfiguration);
167 configNames.add(configName);
168
169 configName = "Note";
170 factory.addConfiguration(configName, createNoteNodeConfiguration(factory));
171 configNames.add(configName);
172
173 configName = "Butterfly";
175 factory.addConfiguration(configName, createButterflyConfiguration(roundRectConfiguration));
176 configNames.add(configName);
177
178 configName = "Flat Button";
180 factory.addConfiguration(configName, createFlatButtonConfiguration(factory));
181 configNames.add(configName);
182
183 configName = "Floating";
185 factory.addConfiguration(configName, createFloatingConfiguration(factory));
186 configNames.add(configName);
187
188 configName = "Raster Graphics";
190 factory.addConfiguration(configName, createRasterGraphicsConfiguration(factory));
191 configNames.add(configName);
192
193
198 configName = "Vector Graphics";
200 Map vectorGraphicsConfig = createVectorGraphicsConfiguration(factory);
201
205 configName = "Decorated Rect";
207 factory.addConfiguration(configName, createDecoratedRectPainterConfiguration(factory));
208 configNames.add(configName);
209
210 return configNames;
211 }
212
213 private List createRealizers(List configurations) {
214 List realizers = new ArrayList(configurations.size());
215 for (Iterator iterator = configurations.iterator(); iterator.hasNext();) {
216 String configName = String.valueOf(iterator.next());
217 GenericNodeRealizer nr = new GenericNodeRealizer(configName);
218 nr.setLabelText(configName);
219 nr.setWidth(120);
220 nr.setFillColor(Color.ORANGE);
221
222 NodeLabel label = nr.getLabel();
223 SmartNodeLabelModel model = new SmartNodeLabelModel();
224 label.setLabelModel(model, model.getDefaultParameter());
225
226 if ("Simple Rectangle".equals(configName)) {
228 } else if ("Diamond".equals(configName)) {
229 } else if ("Ellipse".equals(configName)) {
230 nr.setLineColor(Color.ORANGE);
231 } else if ("Bevel".equals(configName)) {
232 nr.setLineColor(Color.ORANGE);
233 } else if ("Shiny Plate".equals(configName)) {
234 } else if ("Round Rectangle".equals(configName)) {
235 } else if ("Butterfly".equals(configName)) {
236 } else if ("Flat Button".equals(configName)) {
237 } else if ("Floating".equals(configName)) {
238 } else if ("Raster Graphics".equals(configName)) {
239 nr.setLabelText("");
240 } else if ("Vector Graphics".equals(configName)) {
241 nr.setLabelText("");
242 } else if ("Decorated Rect".equals(configName)) {
243 label.setModelParameter(model.createDiscreteModelParameter(SmartNodeLabelModel.POSITION_LEFT));
244 }
245
246 realizers.add(nr);
247 }
248
249 return realizers;
250 }
251
252
259 private Map createSimpleRectangleConfiguration(GenericNodeRealizer.Factory factory) {
260 Map implementationsMap = factory.createDefaultConfigurationMap();
264
265 ShapeNodePainter painter = new ShapeNodePainter(ShapeNodePainter.RECT);
266 implementationsMap.put(GenericNodeRealizer.Painter.class, painter);
267
268 return implementationsMap;
269 }
270
271
278 private Map createDiamondConfiguration(GenericNodeRealizer.Factory factory) {
279 Map implementationsMap = factory.createDefaultConfigurationMap();
280
281 ShapeNodePainter painter = new ShapeNodePainter(ShapeNodePainter.DIAMOND);
282 implementationsMap.put(GenericNodeRealizer.Painter.class, painter);
283
284 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
285 return implementationsMap;
286 }
287
288
299 private Map createEllipseConfiguration(GenericNodeRealizer.Factory factory) {
300 Map implementationsMap = factory.createDefaultConfigurationMap();
301
302 ShapeNodePainter painter = new ShapeNodePainter(ShapeNodePainter.ELLIPSE);
303 GenericNodeRealizer.Painter wrappedPainter = new ShadowNodePainter(painter);
304 implementationsMap.put(GenericNodeRealizer.Painter.class, wrappedPainter);
305 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
306
307 CustomHotSpotPainter chsp = new CustomHotSpotPainter(165, new Ellipse2D.Double(), null);
310 implementationsMap.put(GenericNodeRealizer.HotSpotPainter.class, chsp);
311 implementationsMap.put(GenericNodeRealizer.HotSpotHitTest.class, chsp);
312
313 return implementationsMap;
314 }
315
316 private Map createCircleConfiguration(GenericNodeRealizer.Factory factory) {
317 Map implementationsMap = factory.createDefaultConfigurationMap();
318
319 CircleNodePainter painter = new CircleNodePainter();
320 GenericNodeRealizer.Painter wrappedPainter = new ShadowNodePainter(painter);
321 implementationsMap.put(GenericNodeRealizer.Painter.class, wrappedPainter);
322 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
323
324 return implementationsMap;
325 }
326
327
337 private Map createBevelNodeConfiguration(GenericNodeRealizer.Factory factory) {
338 Map implementationsMap = factory.createDefaultConfigurationMap();
339
340 BevelNodePainter painter = new BevelNodePainter();
341 painter.setDrawShadow(true);
344 implementationsMap.put(GenericNodeRealizer.Painter.class, painter);
345 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
346
347 implementationsMap.put(GenericNodeRealizer.UserDataHandler.class,
350 new SimpleUserDataHandler(SimpleUserDataHandler.REFERENCE_ON_FAILURE));
351
352 return implementationsMap;
353 }
354
355
366 private Map createShinyPlateNodeConfiguration(GenericNodeRealizer.Factory factory) {
367 Map implementationsMap = factory.createDefaultConfigurationMap();
368
369 ShinyPlateNodePainter painter = new ShinyPlateNodePainter();
370 painter.setDrawShadow(true);
373 implementationsMap.put(GenericNodeRealizer.Painter.class, painter);
374 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
375
376 GenericNodeRealizer.GenericSizeConstraintProvider scp = new GenericNodeRealizer.GenericSizeConstraintProvider() {
377 public YDimension getMinimumSize(NodeRealizer context) {
378 return new YDimension(15, 15);
379 }
380
381 public YDimension getMaximumSize(NodeRealizer context) {
382 return new YDimension(250, 100);
383 }
384 };
385 implementationsMap.put(GenericNodeRealizer.GenericSizeConstraintProvider.class, scp);
386
387 return implementationsMap;
388 }
389
390
402 private Map createRoundRectConfiguration(GenericNodeRealizer.Factory factory) {
403 Map implementationsMap = factory.createDefaultConfigurationMap();
404
405 RectangularShapePainter painter = new RectangularShapePainter(new RoundRectangle2D.Double(50, 50, 50, 50, 15, 15));
406 implementationsMap.put(GenericNodeRealizer.Painter.class, new ShadowNodePainter(painter));
407 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
408
409 implementationsMap.put(GenericNodeRealizer.UserDataHandler.class,
412 new SimpleUserDataHandler(SimpleUserDataHandler.REFERENCE_ON_FAILURE));
413
414 CustomHotSpotPainter chsp = new CustomHotSpotPainter(255, new Ellipse2D.Double(), Color.red);
417 implementationsMap.put(GenericNodeRealizer.HotSpotPainter.class, chsp);
418 implementationsMap.put(GenericNodeRealizer.HotSpotHitTest.class, chsp);
419
420 return implementationsMap;
421 }
422
423 private Map createNoteNodeConfiguration(GenericNodeRealizer.Factory factory) {
424 Map implementationsMap = factory.createDefaultConfigurationMap();
425
426 final NoteNodePainter painter = new NoteNodePainter();
427 implementationsMap.put(GenericNodeRealizer.Painter.class, new ShadowNodePainter(painter));
428 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
429
430 return implementationsMap;
431 }
432
433
445 private Map createButterflyConfiguration(Map implementationsMap) {
446 GeneralPath gp = new GeneralPath();
448 gp.moveTo(1.0f, 0.5f);
449 gp.lineTo(0.0f, 1.0f);
450 gp.quadTo(0.0f, 0.5f, 0.3f, 0.5f);
451 gp.quadTo(0.0f, 0.5f, 0.0f, 0.0f);
452 gp.closePath();
453
454 GeneralPathNodePainter painter = new GeneralPathNodePainter(gp);
455 implementationsMap.put(GenericNodeRealizer.Painter.class, new ShadowNodePainter(painter));
456 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
457
458 return implementationsMap;
459 }
460
461
465 private Map createFlatButtonConfiguration(GenericNodeRealizer.Factory factory) {
466 Map implementationsMap = factory.createDefaultConfigurationMap();
467
468 FlatButtonPainter painter = new FlatButtonPainter();
469 implementationsMap.put(GenericNodeRealizer.Painter.class, painter);
470
471 return implementationsMap;
472 }
473
474
481 private Map createFloatingConfiguration(GenericNodeRealizer.Factory factory) {
482 Map implementationsMap = factory.createDefaultConfigurationMap();
483
484 FloatingPainter painter = new FloatingPainter();
485 implementationsMap.put(GenericNodeRealizer.Painter.class, new ShadowNodePainter(painter));
486 implementationsMap.put(GenericNodeRealizer.ContainsTest.class, painter);
487
488 return implementationsMap;
489 }
490
491
496 private Map createRasterGraphicsConfiguration(GenericNodeRealizer.Factory factory) {
497 Map implementationsMap = factory.createDefaultConfigurationMap();
498 ImageNodePainter painter = new ImageNodePainter(getSharedResource("resource/yWorksNode.png"));
499 implementationsMap.put(GenericNodeRealizer.Painter.class, new ShadowNodePainter(painter));
500 return implementationsMap;
501 }
502
503
512 private Map createVectorGraphicsConfiguration(GenericNodeRealizer.Factory factory) {
513 Map implementationsMap = factory.createDefaultConfigurationMap();
514 return implementationsMap;
518 }
519
520
523 private Map createDecoratedRectPainterConfiguration(GenericNodeRealizer.Factory factory) {
524 Map implementationsMap = factory.createDefaultConfigurationMap();
525 IconDecoratorPainter painter = new IconDecoratorPainter(new ShapeNodePainter());
526 implementationsMap.put(GenericNodeRealizer.Painter.class, new ShadowNodePainter(painter));
527 return implementationsMap;
528 }
529
530 protected EditMode createEditMode() {
531 EditMode editMode = new EditMode();
532 editMode.assignNodeLabel(false);
533 return editMode;
534 }
535
536
537 public static void main(String[] args) {
538 EventQueue.invokeLater(new Runnable() {
539 public void run() {
540 Locale.setDefault(Locale.ENGLISH);
541 initLnF();
542 (new GenericNodeRealizerDemo()).start("GenericNodeRealizer Demo");
543 }
544 });
545 }
546
547 private static boolean useGradientStyle( final Graphics2D graphics ) {
548 return YRenderingHints.isGradientPaintingEnabled(graphics);
549 }
550
551
552
557 static final class CustomHotSpotPainter extends AbstractCustomHotSpotPainter {
558 private RectangularShape shape;
559 private Color color;
560
561 CustomHotSpotPainter(int mask, RectangularShape shape, Color color) {
562 super(mask);
563 this.shape = shape;
564 this.color = color;
565 }
566
567 protected void initGraphics(NodeRealizer context, Graphics2D g) {
568 super.initGraphics(context, g);
569 if (color == null) {
570 Color fc = context.getFillColor();
571 if (fc != null) {
572 g.setColor(fc);
573 }
574 } else {
575 g.setColor(color);
576 }
577 }
578
579 protected void paint(byte hotSpot, double centerX, double centerY, Graphics2D graphics) {
580 shape.setFrame(centerX - 2, centerY - 2, 5, 5);
581 graphics.fill(shape);
582 }
583
584 protected boolean isHit(byte hotSpot, double centerX, double centerY, double testX, double testY) {
585 return Math.abs(testX - centerX) < 3 && Math.abs(testY - centerY) < 3;
586 }
587 }
588
589
590 public static final class RectangularShapePainter extends AbstractCustomNodePainter implements GenericNodeRealizer.ContainsTest {
591 private RectangularShape shape;
592
593 public RectangularShapePainter(RectangularShape shape) {
594 this.shape = shape;
595 }
596
597
598 protected Color getFillColor(NodeRealizer context, boolean selected) {
599 if (selected) {
600 return Color.red;
601 } else {
602 return super.getFillColor(context, selected);
603 }
604 }
605
606 protected void paintNode(NodeRealizer context, Graphics2D graphics, boolean sloppy) {
607 shape.setFrame(context.getX(), context.getY(), context.getWidth(), context.getHeight());
608 if (initializeFill(context, graphics)) {
609 graphics.fill(shape);
610 }
611 if (initializeLine(context, graphics)) {
612 graphics.draw(shape);
613 }
614 }
615
616 public boolean contains(NodeRealizer context, double x, double y) {
617 shape.setFrame(context.getX(), context.getY(), context.getWidth(), context.getHeight());
618 return shape.contains(x, y);
619 }
620 }
621
622
633 public static class FloatingPainter extends AbstractCustomNodePainter implements GenericNodeRealizer.ContainsTest {
634 private final RoundRectangle2D innerShape;
635 private final RoundRectangle2D outerShape;
636 private RoundRectangle2D measureRect;
637 private double radius = 8;
638
639 public FloatingPainter() {
640 this.innerShape = new RoundRectangle2D.Double(0, 0, -1, -1, radius, radius);
641 this.outerShape = new RoundRectangle2D.Double(0, 0, -1, -1, radius, radius);
642 }
643
644 protected void paintNode(NodeRealizer context, Graphics2D graphics, boolean sloppy) {
645 double inset = getInset(context);
646 innerShape.setFrame(context.getX() + inset, context.getY() + inset, context.getWidth() - 2 * inset,
647 context.getHeight() - 2 * inset);
648 if (initializeFill(context, graphics)) {
649 graphics.fill(innerShape);
650 }
651 outerShape.setFrame(context.getX(), context.getY(), context.getWidth(), context.getHeight());
652 if (initializeLine(context, graphics)) {
653 graphics.draw(outerShape);
654 }
655 }
656
657
666 protected double getInset(NodeRealizer context) {
667 Object o = ((GenericNodeRealizer)context).getStyleProperty("FloatingPainter.Inset");
668 if (o instanceof Number){
669 return ((Number)o).doubleValue();
670 } else {
671 return 4;
672 }
673 }
674
675 protected Paint getLinePaint(final NodeRealizer context, final boolean selected) {
676 return getFillPaint(context, selected);
677 }
678
679 protected Color getLineColor( final NodeRealizer context, final boolean selected ) {
680 return getFillColor(context, selected);
681 }
682
683 public boolean contains(NodeRealizer context, double x, double y) {
684 if (null == measureRect) {
685 measureRect = new RoundRectangle2D.Double();
686 }
687 double inset = getInset(context);
688 measureRect.setRoundRect(context.getX() + inset, context.getY() + inset, context.getWidth() - 2 * inset,
689 context.getHeight() - 2 * inset, radius, radius);
690 return measureRect.contains(x, y);
691 }
692 }
693
694
695 static class FlatButtonPainter extends AbstractCustomNodePainter {
696 protected void paintNode(NodeRealizer context, Graphics2D g, boolean sloppy) {
697 double x = context.getX();
698 double y = context.getY();
699 double w = context.getWidth();
700 double h = context.getHeight();
701
702 Shape shape = new RoundRectangle2D.Double(x, y, w, h, 10, 10);
703 Color c1 = context.getFillColor();
704 paintBorder(g, c1, (float) 2, shape);
705 paintContent(g, shape, c1, 0, x, y, w, h);
706 }
707
708 private void paintBorder(Graphics2D g, Color c1, float thick, Shape shape) {
709 float ratio = 0.75f;
710 g.setColor(mixColors(new Color(128, 128, 128, 64), c1, ratio));
711 g.setStroke(new BasicStroke(thick, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
712 g.draw(shape);
713
714 g.setColor(mixColors(new Color(255, 255, 255, 196), c1, ratio));
715 g.setStroke(new BasicStroke(thick / 2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
716 g.translate(thick / 4, thick / 4);
717 g.draw(shape);
718
719 g.setColor(mixColors(new Color(0, 0, 0, 64), c1, ratio));
720 g.setStroke(new BasicStroke(thick / 2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
721 g.translate(-thick / 2, -thick / 2);
722 g.draw(shape);
723 g.translate(thick / 4, thick / 4);
724 }
725
726 private void paintContent(Graphics2D g, Shape shape, Color c1, int thick, double x, double y, double w, double h) {
727 Color c2 = Color.WHITE;
728 Color c3 = mixColors(c1, c2, 0.5f);
729 BasicStroke stroke = new BasicStroke(thick, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
730 g.setStroke(stroke);
731 g.setPaint(new GradientPaint((float) x, (float) y - thick - 1, c3, (float) x,
732 (float) (y + h + thick + 1), c1));
733
734 Shape strokedShape = stroke.createStrokedShape(shape);
735 Area area = new Area(strokedShape);
736 area.add(new Area(shape));
737
738 g.fill(area);
739
740 Shape oldClip = g.getClip();
741
742 g.clip(area);
743 g.clip(new Ellipse2D.Double(x - w, y - h * 0.5, w * 3, h * 0.75));
744
745 if (useGradientStyle(g)) {
746 g.setPaint(new GradientPaint((float) x, (float) (y - 5), new Color(1.0f, 1.0f, 1.0f, 0.3f), (float) x,
747 (float) (y + h), new Color(1.0f, 1.0f, 1.0f, 0.0f)));
748 } else {
749 g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.3f));
750 }
751
752 g.fill(
753 new Rectangle2D.Double(x - thick - thick, y - thick, w + thick + thick + thick + thick, h + thick + thick));
754
755 g.setClip(oldClip);
756 }
757
758 private Color mixColors(Color c1, Color c2, float ratio) {
759 float b = 1 - ratio;
760 return new Color((c1.getRed() * ratio + c2.getRed() * b) / 255f,
761 (c1.getGreen() * ratio + c2.getGreen() * b) / 255f,
762 (c1.getBlue() * ratio + c2.getGreen() * b) / 255f, (c1.getAlpha() * ratio + c2.getAlpha() * b) / 255f);
763 }
764 }
765
766 static class IconDecoratorPainter implements GenericNodeRealizer.Painter {
767 private final GenericNodeRealizer.Painter innerPainter;
768 private Icon icon;
769
770 public IconDecoratorPainter(GenericNodeRealizer.Painter innerPainter) {
771 this.innerPainter = innerPainter;
772 icon = createIcon();
773 }
774
775 public void paint( final NodeRealizer context, final Graphics2D graphics ) {
776 innerPainter.paint(context, graphics);
777 paintIcon(context, graphics);
778 }
779
780 public void paintSloppy( final NodeRealizer context, final Graphics2D graphics ) {
781 innerPainter.paintSloppy(context, graphics);
782 paintIcon(context, graphics);
783 }
784
785 private void paintIcon( final NodeRealizer context, final Graphics2D graphics ) {
786 int x = (int) (context.getX() + context.getWidth() - icon.getIconWidth() - 2);
787 int y = (int) (context.getY() + 2);
788 icon.paintIcon(null, graphics, x, y);
789 }
790
791 protected Icon createIcon() {
792 URL imageURL = ClassLoader.getSystemResource("demo/view/resource/yicon.png");
793 final ImageIcon imageIcon = new ImageIcon(imageURL);
794 final double zoom = 16.0d / Math.min(imageIcon.getIconHeight(), imageIcon.getIconWidth());
795
796 return new Icon() {
797 public void paintIcon(Component c, Graphics g, int x, int y) {
798 g.drawImage(imageIcon.getImage(), x, y, getIconWidth(), getIconHeight(), null);
799 }
800
801 public int getIconWidth() {
802 return (int) (imageIcon.getIconWidth() * zoom);
803 }
804
805 public int getIconHeight() {
806 return (int) (imageIcon.getIconHeight() * zoom);
807 }
808 };
809 }
810 }
811
812
816 static class CircleNodePainter
817 extends AbstractCustomNodePainter
818 implements GenericNodeRealizer.ContainsTest {
819 private final Ellipse2D.Double circle = new Ellipse2D.Double();
820
821 protected void paintNode(
822 final NodeRealizer context,
823 final Graphics2D graphics,
824 final boolean sloppy
825 ) {
826 final double w = context.getWidth();
827 final double h = context.getHeight();
828 final double d = Math.min(w, h);
829 circle.setFrame(
830 context.getX() + (w - d) * 0.5,
831 context.getY() + (h - d) * 0.5, d, d);
832
833 final boolean useSelectionStyle = useSelectionSyle(context, graphics);
834 final Color fc = getFillColor(context, useSelectionStyle);
835 if (fc != null) {
836 graphics.setColor(fc);
837 graphics.fill(circle);
838 }
839
840 final Color lc = getLineColor(context, useSelectionStyle);
841 final Stroke ls = getLineStroke(context, useSelectionStyle);
842 if (lc != null && ls != null) {
843 graphics.setColor(lc);
844 graphics.setStroke(ls);
845 graphics.draw(circle);
846 }
847 }
848
849 public boolean contains(
850 final NodeRealizer context,
851 final double x,
852 final double y
853 ) {
854 final double w = context.getWidth();
855 final double h = context.getHeight();
856 final double tx = context.getX() + w * 0.5 - x;
857 final double ty = context.getY() + h * 0.5 - y;
858 return Math.sqrt(tx*tx + ty*ty) <= Math.min(w, h) * 0.5;
859 }
860
861 private static boolean useSelectionSyle(
862 final NodeRealizer context,
863 final Graphics2D graphics
864 ) {
865 return context.isSelected() &&
866 YRenderingHints.isSelectionPaintingEnabled(graphics);
867 }
868 }
869
870
874 static class NoteNodePainter
875 extends AbstractCustomNodePainter
876 implements GenericNodeRealizer.ContainsTest {
877 private static final double DOG_EAR_SIZE = 15;
878
879 private final GeneralPath shape;
880 private final Rectangle2D.Double fallback;
881
882 private Color dogEarColor;
883
884 public NoteNodePainter() {
885 shape = new GeneralPath();
886 fallback = new Rectangle2D.Double();
887 dogEarColor = Color.LIGHT_GRAY;
888 }
889
890 public Color getDogEarColor() {
891 return dogEarColor;
892 }
893
894 public void setDogEarColor( final Color dogEarColor ) {
895 this.dogEarColor = dogEarColor;
896 }
897
898 protected void paintNode(
899 final NodeRealizer context,
900 final Graphics2D graphics,
901 final boolean sloppy
902 ) {
903 final boolean useSelectionStyle = useSelectionSyle(context, graphics);
904
905 final double w = context.getWidth();
906 final double h = context.getHeight();
907 if (w < DOG_EAR_SIZE + 5 && h < DOG_EAR_SIZE + 5) {
908 fallback.setFrame(context.getX(), context.getY(), w, h);
910 final Paint fp =
911 useGradientStyle(graphics)
912 ? getFillPaint(context, useSelectionStyle)
913 : getFillColor(context, useSelectionStyle);
914 if (fp != null) {
915 graphics.setPaint(fp);
916 graphics.fill(fallback);
917 }
918
919 final Color lc = getLineColor(context, useSelectionStyle);
920 final Stroke ls = getLineStroke(context, useSelectionStyle);
921 if (lc != null && ls != null) {
922 graphics.setColor(lc);
923 graphics.setStroke(ls);
924 graphics.draw(fallback);
925 }
926 } else {
927 shape.reset();
929 final double x = context.getX();
930 final double y = context.getY();
931 final double maxX = x + w;
932 final double maxY = y + h;
933
934 shape.moveTo((float) x, (float) y);
935 shape.lineTo((float) (maxX - DOG_EAR_SIZE), (float) y);
936 shape.lineTo((float) maxX, (float) (y + DOG_EAR_SIZE));
937 shape.lineTo((float) maxX, (float) maxY);
938 shape.lineTo((float) x, (float) maxY);
939 shape.closePath();
940
941 final Paint fp =
943 useGradientStyle(graphics)
944 ? getFillPaint(context, useSelectionStyle)
945 : getFillColor(context, useSelectionStyle);
946 if (fp != null) {
947 graphics.setPaint(fp);
948 graphics.fill(shape);
949 }
950
951 final Color lc = getLineColor(context, useSelectionStyle);
953 final Stroke ls = getLineStroke(context, useSelectionStyle);
954 if (lc != null && ls != null) {
955 graphics.setColor(lc);
956 graphics.setStroke(ls);
957 graphics.draw(shape);
958 }
959
960 final Color dogEarColor = getDogEarColor(context);
962 if (dogEarColor != null) {
963 shape.reset();
964 shape.moveTo((float) (maxX - DOG_EAR_SIZE), (float) y);
965 shape.lineTo((float) (maxX - DOG_EAR_SIZE), (float) (y + DOG_EAR_SIZE));
966 shape.lineTo((float) maxX, (float) (y + DOG_EAR_SIZE));
967 shape.closePath();
968
969 graphics.setColor(dogEarColor);
970 graphics.fill(shape);
971 }
972
973 if (lc != null && ls != null) {
975 shape.reset();
976 shape.moveTo((float) (maxX - DOG_EAR_SIZE), (float) y);
977 shape.lineTo((float) (maxX - DOG_EAR_SIZE), (float) (y + DOG_EAR_SIZE));
978 shape.lineTo((float) maxX, (float) (y + DOG_EAR_SIZE));
979
980 graphics.setColor(lc);
981 graphics.setStroke(ls);
982 graphics.draw(shape);
983 }
984 }
985 }
986
987 private Color getDogEarColor( final NodeRealizer context ) {
988 if (context instanceof GenericNodeRealizer) {
989 final Object property =
990 ((GenericNodeRealizer) context).getStyleProperty("dogEarColor");
991 if (property instanceof Color) {
992 return (Color) property;
993 }
994 }
995
996 return getDogEarColor();
997 }
998
999 public boolean contains(
1000 final NodeRealizer context,
1001 final double tx,
1002 final double ty
1003 ) {
1004 final double w = context.getWidth();
1005 final double h = context.getHeight();
1006 if (w < DOG_EAR_SIZE + 5 && h < DOG_EAR_SIZE + 5) {
1007 fallback.setFrame(context.getX(), context.getY(), w, h);
1008 return fallback.contains(tx, ty);
1009 } else {
1010 shape.reset();
1011 final double x = context.getX();
1012 final double y = context.getY();
1013 shape.moveTo((float) x, (float) y);
1014 shape.lineTo((float) (x + w - DOG_EAR_SIZE), (float) y);
1015 shape.lineTo((float) (x + w), (float) (y + DOG_EAR_SIZE));
1016 shape.lineTo((float) (x + w), (float) (y + h));
1017 shape.lineTo((float) x, (float) (y + h));
1018 shape.closePath();
1019
1020 return shape.contains(tx, ty);
1021 }
1022 }
1023
1024 private static boolean useSelectionSyle(
1025 final NodeRealizer context,
1026 final Graphics2D graphics
1027 ) {
1028 return context.isSelected() &&
1029 YRenderingHints.isSelectionPaintingEnabled(graphics);
1030 }
1031 }
1032}
1033