| NetworkMonitoringDemo.java |
1 /****************************************************************************
2 * This demo file is part of yFiles for Java 2.14.
3 * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28,
4 * 72070 Tuebingen, Germany. All rights reserved.
5 *
6 * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution
7 * of demo files in source code or binary form, with or without
8 * modification, is not permitted.
9 *
10 * Owners of a valid software license for a yFiles for Java version that this
11 * demo is shipped with are allowed to use the demo source code as basis
12 * for their own yFiles for Java powered applications. Use of such programs is
13 * governed by the rights and conditions as set out in the yFiles for Java
14 * license agreement.
15 *
16 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 ***************************************************************************/
28 package demo.view.networkmonitoring;
29
30 import demo.view.DemoBase;
31 import y.anim.AnimationObject;
32 import y.anim.AnimationPlayer;
33 import y.base.DataMap;
34 import y.util.DefaultMutableValue2D;
35 import y.util.Maps;
36 import y.view.BackgroundRenderer;
37 import y.view.DefaultGraph2DRenderer;
38 import y.view.EditMode;
39 import y.view.NavigationMode;
40 import y.view.ViewAnimationFactory;
41 import y.view.YRenderingHints;
42
43 import javax.swing.AbstractAction;
44 import javax.swing.Action;
45 import javax.swing.JToolBar;
46 import javax.swing.Timer;
47 import java.awt.Color;
48 import java.awt.Dimension;
49 import java.awt.EventQueue;
50 import java.awt.GradientPaint;
51 import java.awt.Graphics2D;
52 import java.awt.Paint;
53 import java.awt.Rectangle;
54 import java.awt.event.ActionEvent;
55 import java.awt.event.ActionListener;
56 import java.beans.PropertyChangeEvent;
57 import java.beans.PropertyChangeListener;
58 import java.util.Locale;
59
60 /**
61 * This demo shows a simple network monitoring tool. You can watch the traffic flow through the network
62 * and even influence the network.
63 * The network consists of PCs, Laptops, Tablets, Switches, Servers, Databases and W-LANS. The color of the edges
64 * change from green to yellow to red depending on its traffic load. The traffic load of nodes is shown on their
65 * info label. Active edges are marked through an animation.
66 *
67 * Things to try
68 * <ul>
69 * <li>Open/Hide Info Label: Every node has an info label. It can be shown and hidden by clicking on the node. It shows
70 * the name, IP address and traffic load. You can also close it by clicking on the x in the top right corner.
71 * Remember that info labels are only visible at a detailed zoom level.</li>
72 * <li>Disable nodes: The info label also contains a power button in the bottom right corner. Clicking on it
73 * (de)activates the node, preventing it from processing data. This way you can influence the data flow and watch
74 * what happens.</li>
75 * <li>Enable Failures: By Clicking on "Enable Failures" you allow failures to happen randomly. Nodes and edges get
76 * broken and can't process data anymore. Broken elements are marked with a stop sign. If a failure happens on a node
77 * or edge outside the current viewport, then the viewport will be moved to focus the broken element.
78 * You can repair elements by clicking on the stop sign. To repair a node, you can also
79 * open the info label and then click on the green arc arrow at the bottom right corner.</li>
80 * </ul>
81 */
82 public class NetworkMonitoringDemo extends DemoBase {
83 static final double MAX_ZOOM = 3;
84 static final double MIN_ZOOM = 0.15;
85 static final double PAINT_DETAIL_THRESHOLD = 0.25;
86 static final double LABEL_HIDE_ZOOM_LEVEL = 0.55;
87
88 private NetworkModel model;
89 private DataMap view2model;
90
91 public NetworkMonitoringDemo() {
92 this(null);
93 }
94
95 public NetworkMonitoringDemo(final String helpFilePath) {
96 addHelpPane(helpFilePath);
97 // start with a bigger view than usual
98 view.setPreferredSize(new Dimension(1200, 900));
99
100 final NetworkView networkView = new NetworkView(model, view, view2model);
101 model.addObserver(networkView);
102
103 addBackgroundRenderer();
104 ((DefaultGraph2DRenderer) view.getGraph2DRenderer()).setDrawEdgesFirst(true);
105 addZoomThreshold();
106
107 // initially zoom in to avoid sloppy view in the beginning
108 final Timer timer = new Timer(500, new ActionListener() {
109 public void actionPerformed(ActionEvent e) {
110 final ViewAnimationFactory factory = new ViewAnimationFactory(view);
111 final Rectangle graphBounds = view.getGraph2D().getBoundingBox();
112 final DefaultMutableValue2D newCenter =
113 DefaultMutableValue2D.create(graphBounds.getWidth() * 0.4, graphBounds.getHeight() * 0.4);
114 final AnimationObject focus = factory.focusView(0.5, newCenter, 1000);
115 final AnimationPlayer player = factory.createConfiguredPlayer();
116 player.animate(focus);
117 }
118 });
119 timer.setRepeats(false);
120 timer.start();
121 }
122
123 /**
124 * Overwritten to make sure that the model and the model-view-mapping are initialized before
125 * {@link NetworkInteractionMode} is created and added to the view.
126 */
127 protected void initialize() {
128 view2model = Maps.createHashedDataMap();
129 model = new NetworkModelImpl(getResource("resource/network.graphml"));
130 }
131
132 /**
133 * Adds a {@link BackgroundRenderer} that paints a gradient background to the view.
134 */
135 private void addBackgroundRenderer() {
136 view.setBackgroundRenderer(new BackgroundRenderer() {
137 public void paint(Graphics2D gfx, int x, int y, int w, int h) {
138 final Rectangle visibleRect = view.getVisibleRect();
139 //Store old paint
140 final Paint oldPaint = gfx.getPaint();
141 //Draw a rectangle in the visible area, using the GradientPainter.
142 GradientPaint gradientPaint = new GradientPaint(visibleRect.x, visibleRect.y, Color.WHITE,
143 visibleRect.x + visibleRect.width, visibleRect.y + visibleRect.height, new Color(195, 211, 238));
144 gfx.setPaint(gradientPaint);
145 gfx.fillRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height);
146 //Reset old paint
147 gfx.setPaint(oldPaint);
148 }
149 });
150 }
151
152 /**
153 * Adds thresholds to paint different details of the graph depending on the zoom level.
154 */
155 private void addZoomThreshold() {
156 view.setPaintDetailThreshold(PAINT_DETAIL_THRESHOLD);
157 view.getCanvasComponent().addPropertyChangeListener(new PropertyChangeListener() {
158 public void propertyChange(PropertyChangeEvent evt) {
159 if (evt.getPropertyName().equals("Zoom")) {
160 final double zoom = ((Double) evt.getNewValue()).doubleValue();
161 if (zoom <= LABEL_HIDE_ZOOM_LEVEL) {
162 view.getRenderingHints().put(
163 YRenderingHints.KEY_NODE_LABEL_PAINTING,
164 YRenderingHints.VALUE_NODE_LABEL_PAINTING_OFF);
165 } else {
166 view.getRenderingHints().put(
167 YRenderingHints.KEY_NODE_LABEL_PAINTING,
168 YRenderingHints.VALUE_NODE_LABEL_PAINTING_ON);
169 }
170 if (zoom < MIN_ZOOM) {
171 view.setZoom(MIN_ZOOM);
172 } else if (zoom > MAX_ZOOM) {
173 view.setZoom(MAX_ZOOM);
174 }
175 }
176 }
177 });
178 }
179
180 /**
181 * Overwritten because this demo is not editable.
182 */
183 protected EditMode createEditMode() {
184 return null;
185 }
186
187 /**
188 * Overwritten to register {@link NavigationMode} and a custom view mode that provides possible interactions for this
189 * demo.
190 */
191 protected void registerViewModes() {
192 view.addViewMode(new NavigationMode());
193 view.addViewMode(new NetworkInteractionMode(model, view2model));
194 }
195
196 /**
197 * Launches this demo.
198 */
199 public static void main(String[] args) {
200 EventQueue.invokeLater(new Runnable() {
201 public void run() {
202 Locale.setDefault(Locale.ENGLISH);
203 initLnF();
204 (new NetworkMonitoringDemo("resource/networkhelp.html")).start("Network Monitoring Demo");
205 }
206 });
207 }
208
209 /**
210 * Overwritten to disable deletion of graph elements because this demo is not editable.
211 */
212 protected boolean isDeletionEnabled() {
213 return false;
214 }
215
216 /**
217 * Overwritten to disable undo and redo because this demo is not editable.
218 */
219 protected boolean isUndoRedoEnabled() {
220 return false;
221 }
222
223 /**
224 * Overwritten to disable clipboard because this demo is not editable.
225 */
226 protected boolean isClipboardEnabled() {
227 return false;
228 }
229
230 /**
231 * Overwritten to disable loading a graph because this demo is not editable and should only use the initial graph.
232 */
233 protected Action createLoadAction() {
234 return null;
235 }
236
237 /**
238 * Overwritten to disable saving a graph because this demo is not editable and the initial graph does not change.
239 */
240 protected Action createSaveAction() {
241 return null;
242 }
243
244 /**
245 * Overwritten to customize the toolbar for this demo. A button is added to enable/disable failures in the network.
246 */
247 protected JToolBar createToolBar() {
248 final JToolBar toolBar = super.createToolBar();
249 toolBar.add(new AbstractAction("Enable Failures") {
250 public void actionPerformed(ActionEvent e) {
251 if (model.isNetworkErrorsEnabled()) {
252 putValue(Action.NAME,"Enable Failures");
253 model.setNetworkErrorsEnabled(false);
254 } else {
255 putValue(Action.NAME,"Disable Failures");
256 model.setNetworkErrorsEnabled(true);
257 }
258 }
259 });
260 return toolBar;
261 }
262 }
263