1
28 package demo.view.networkmonitoring;
29
30 import y.geom.YRectangle;
31 import y.view.DefaultLabelConfiguration;
32 import y.view.NodeLabel;
33 import y.view.NodeRealizer;
34 import y.view.YLabel;
35
36 import java.awt.BasicStroke;
37 import java.awt.Color;
38 import java.awt.Graphics2D;
39 import java.awt.Insets;
40 import java.awt.Shape;
41 import java.awt.Stroke;
42 import java.awt.font.FontRenderContext;
43 import java.awt.geom.Arc2D;
44 import java.awt.geom.Area;
45 import java.awt.geom.Ellipse2D;
46 import java.awt.geom.GeneralPath;
47 import java.awt.geom.Line2D;
48 import java.awt.geom.Point2D;
49 import java.awt.geom.RoundRectangle2D;
50
51
54 public class NetworkInfoLabelPainter extends DefaultLabelConfiguration {
55 private static final BasicStroke STROKE_ROUNDED_CAP = new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
56
57 private static final double STATUS_ICON_WIDTH = 20;
58 private static final double STATUS_ICON_HEIGHT = 20;
59 private static final double CLOSE_ICON_WIDTH = 10;
60 private static final double CLOSE_ICON_HEIGHT = 10;
61 private static final double STATE_CHANGE_ICON_WIDTH = 15;
62 private static final double STATE_CHANGE_ICON_HEIGHT = 15;
63 private static final double GAP = 5;
64
65 public void paintBox(YLabel label, Graphics2D gfx, double x, double y, double width, double height) {
66 final Color oldColor = gfx.getColor();
67 final Stroke oldStroke = gfx.getStroke();
68
69
70 if (label instanceof NodeLabel) {
71 Shape shape = new RoundRectangle2D.Double(x, y, width, height, Math.min(width / 3, 10), Math.min(height / 3, 10));
73
74 final NodeRealizer realizer = ((NodeLabel) label).getRealizer();
76 final double nodeCenterX = realizer.getCenterX();
77 final double nodeCenterY = realizer.getCenterY();
78 final double labelCenterX = x + width * 0.5d;
79 final double labelCenterY = y + height * 0.5d;
80
81 final Point2D intersection = new Point2D.Double();
83 realizer.findIntersection(nodeCenterX, nodeCenterY, labelCenterX, labelCenterY, intersection);
84 final double intersectionX = intersection.getX();
85 final double intersectionY = intersection.getY();
86
87 final double dx = labelCenterX - intersectionX;
89 final double dy = labelCenterY - intersectionY;
90 final double l = Math.sqrt(dx * dx + dy * dy);
91 if (l > 0) {
92 final double size = Math.min(width, height) * 0.25;
93 final GeneralPath p = new GeneralPath();
94 p.moveTo((float) intersectionX, (float) intersectionY);
95 p.lineTo((float) (labelCenterX + dy * size / l), (float) (labelCenterY - dx * size / l));
96 p.lineTo((float) (labelCenterX - dy * size / l), (float) (labelCenterY + dx * size / l));
97 p.closePath();
98 final Area area = new Area(shape);
99 area.add(new Area(p));
100 shape = area;
101 }
102
103 final Color backgroundColor = label.getBackgroundColor();
105 if (backgroundColor != null) {
106 gfx.setColor(backgroundColor);
108 gfx.fill(shape);
109 }
110
111 final Color lineColor = label.getLineColor();
113 if (lineColor != null) {
114 gfx.setColor(lineColor);
115 gfx.draw(shape);
116 }
117 }
118
119 gfx.setColor(oldColor);
120 gfx.setStroke(oldStroke);
121 }
122
123 public void paintContent(YLabel label, Graphics2D graphics, double x, double y, double width, double height) {
124 final Color oldColor = graphics.getColor();
125 final Shape oldClip = graphics.getClip();
126 final Stroke oldStroke = graphics.getStroke();
127 final Color oldTextColor = label.getTextColor();
128
129 try {
130 if (label instanceof NodeLabel) {
131 final NodeLabel nodeLabel = (NodeLabel) label;
132 final NetworkData networkData = NetworkMonitoringFactory.getNetworkData(
133 nodeLabel.getGraph2D().getRealizer(nodeLabel.getNode()));
134 final Insets insets = getInsets(nodeLabel);
135
136 if (!networkData.isOK()) {
138 label.setTextColor(Color.GRAY);
139 }
140 super.paintContent(label, graphics, x, y, width, height);
141
142
143 final double closeX = x + width - CLOSE_ICON_WIDTH - insets.right;
145 final double closeY = y + insets.top;
146 final Ellipse2D ellipse = new Ellipse2D.Double(closeX, closeY, CLOSE_ICON_WIDTH, CLOSE_ICON_HEIGHT);
147 graphics.setColor(label.getBackgroundColor().darker());
148 graphics.fill(ellipse);
149 final Line2D line = new Line2D.Double(closeX + CLOSE_ICON_WIDTH * 0.25, closeY + CLOSE_ICON_HEIGHT * 0.25,
150 closeX + CLOSE_ICON_WIDTH * 0.75, closeY + CLOSE_ICON_HEIGHT * 0.75);
151 graphics.setColor(Color.WHITE);
152 graphics.draw(line);
153 line.setLine(closeX + CLOSE_ICON_WIDTH * 0.25, closeY + CLOSE_ICON_HEIGHT * 0.75,
154 closeX + CLOSE_ICON_WIDTH * 0.75, closeY + CLOSE_ICON_HEIGHT * 0.25);
155 graphics.draw(line);
156
157 final double iconX = x + insets.left;
159 final double iconY = y + height - STATUS_ICON_HEIGHT - insets.bottom;
160 if (networkData.isBroken()) {
161 NetworkMonitoringFactory.paintWarningSign(iconX, iconY, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT, graphics);
162 } else {
163 ellipse.setFrame(iconX, iconY, STATUS_ICON_WIDTH, STATUS_ICON_HEIGHT);
164 graphics.setColor(NetworkMonitoringFactory.getStatusColor(networkData));
165 graphics.fill(ellipse);
166 graphics.setColor(Color.WHITE);
167 graphics.draw(ellipse);
168 }
169
170 if (networkData.isBroken()) {
172 graphics.setStroke(STROKE_ROUNDED_CAP);
173 graphics.setColor(NetworkMonitoringFactory.COLOR_WORKLOAD_NONE);
174 final double stateChangeX = x + width - STATE_CHANGE_ICON_WIDTH - insets.right;
175 final double stateChangeY = y + height - STATE_CHANGE_ICON_HEIGHT - insets.bottom;
176 final Arc2D arc = new Arc2D.Double(stateChangeX, stateChangeY, STATE_CHANGE_ICON_WIDTH,
177 STATE_CHANGE_ICON_WIDTH, 495, 270, Arc2D.OPEN);
178 graphics.draw(arc);
179 final GeneralPath path = new GeneralPath();
180 path.moveTo((float) (stateChangeX + STATE_CHANGE_ICON_WIDTH * 0.6), (float) stateChangeY);
181 path.lineTo((float) (stateChangeX + STATE_CHANGE_ICON_WIDTH * 0.95), (float) stateChangeY);
182 path.lineTo((float) (stateChangeX + STATE_CHANGE_ICON_WIDTH * 0.75),
183 (float) (stateChangeY + STATE_CHANGE_ICON_HEIGHT * 0.3));
184 path.closePath();
185 graphics.fill(path);
186 } else {
187 if (networkData.isOK()) {
188 graphics.setColor(Color.RED);
189 } else {
190 graphics.setColor(NetworkMonitoringFactory.COLOR_WORKLOAD_NONE);
191 }
192 graphics.setStroke(STROKE_ROUNDED_CAP);
193 final double stateChangeX = x + width - STATE_CHANGE_ICON_WIDTH - insets.right;
194 final double stateChangeY = y + height - STATE_CHANGE_ICON_HEIGHT - insets.bottom;
195 final Arc2D arc = new Arc2D.Double(stateChangeX, stateChangeY, STATE_CHANGE_ICON_WIDTH, STATE_CHANGE_ICON_WIDTH, 495, 270, Arc2D.OPEN);
196 graphics.draw(arc);
197 line.setLine(stateChangeX + STATE_CHANGE_ICON_WIDTH * 0.5, stateChangeY,
198 stateChangeX + STATE_CHANGE_ICON_WIDTH * 0.5, stateChangeY + STATE_CHANGE_ICON_HEIGHT * 0.5);
199 graphics.draw(line);
200 }
201 }
202 } finally {
203 graphics.setColor(oldColor);
204 graphics.setClip(oldClip);
205 graphics.setStroke(oldStroke);
206 label.setTextColor(oldTextColor);
207 }
208 }
209
210
213 public void calculateContentSize(YLabel label, FontRenderContext frc) {
214 super.calculateContentSize(label, frc);
215 if (label instanceof NodeLabel) {
216 final NodeLabel nodeLabel = (NodeLabel) label;
217 final Insets insets = getInsets(nodeLabel);
218 final double contentWidth = Math.max(nodeLabel.getContentWidth(),
219 STATUS_ICON_WIDTH + insets.left + insets.right + STATE_CHANGE_ICON_WIDTH + GAP) + GAP + CLOSE_ICON_WIDTH;
220 final double contentHeight = label.getContentHeight() + GAP + Math.max(STATUS_ICON_HEIGHT, STATE_CHANGE_ICON_HEIGHT);
221 label.setContentSize(contentWidth, contentHeight);
222 }
223 }
224
225
228 public static boolean hitsCloseIcon(NodeLabel label, double x, double y) {
229 final YRectangle box = label.getBox();
230 final Insets insets = getInsets(label);
231 final double closeX = box.getX() + box.getWidth() - CLOSE_ICON_WIDTH - insets.right;
232 final double closeY = box.getY() + insets.top;
233 return x > closeX && x < closeX + CLOSE_ICON_WIDTH
234 && y > closeY && y < closeY + CLOSE_ICON_HEIGHT;
235 }
236
237
240 public static boolean hitsStateChangeIcon(NodeLabel label, double x, double y) {
241 final YRectangle box = label.getBox();
242 final Insets insets = getInsets(label);
243 final double closeX = box.getX() + box.getWidth() - STATE_CHANGE_ICON_WIDTH - insets.right;
244 final double closeY = box.getY() + box.getHeight() - STATE_CHANGE_ICON_HEIGHT - insets.bottom;
245 return x > closeX && x < closeX + STATE_CHANGE_ICON_WIDTH
246 && y > closeY && y < closeY + STATE_CHANGE_ICON_HEIGHT;
247 }
248
249
253 private static Insets getInsets(NodeLabel label) {
254 return label.getInsets() != null ? label.getInsets() : YLabel.defaultInsets;
255 }
256 }
257