1
14 package demo.layout.organic;
15
16 import demo.view.DemoBase;
17 import y.algo.Bfs;
18 import y.anim.AnimationFactory;
19 import y.anim.AnimationObject;
20 import y.anim.AnimationPlayer;
21 import y.base.Node;
22 import y.base.NodeCursor;
23 import y.base.NodeList;
24 import y.base.NodeMap;
25 import y.geom.YPoint;
26 import y.layout.CopiedLayoutGraph;
27 import y.layout.LayoutTool;
28 import y.layout.organic.InteractiveOrganicLayouter;
29 import y.util.DefaultMutableValue2D;
30 import y.util.GraphHider;
31 import y.view.DefaultGraph2DRenderer;
32 import y.view.EditMode;
33 import y.view.Graph2DViewRepaintManager;
34 import y.view.NodeRealizer;
35 import y.view.TooltipMode;
36 import y.view.ViewAnimationFactory;
37
38 import javax.swing.Action;
39 import javax.swing.SwingUtilities;
40 import java.awt.event.ActionEvent;
41 import java.awt.EventQueue;
42 import java.util.Locale;
43
44
60 public class NavigationDemo extends DemoBase {
61 protected static final long PREFERRED_DURATION = 1000;
62
63
66 protected InteractiveOrganicLayouter layouter;
67
70 protected Node centerNode;
71
72 protected GraphHider graphHider;
73
74
77 protected AnimationPlayer animationPlayer;
78 protected ViewAnimationFactory factory;
79 private Thread layoutThread;
80
81 public static void main(String[] args) {
82 EventQueue.invokeLater(new Runnable() {
83 public void run() {
84 Locale.setDefault(Locale.ENGLISH);
85 initLnF();
86 (new NavigationDemo()).start("Navigation Demo");
87 }
88 });
89 }
90
91 public NavigationDemo() {
92
93
94 SwingUtilities.invokeLater(new Runnable() {
95 public void run() {
96 moveFirstNodeToCenter();
97 }
98 });
99
100 }
101
102 protected void initialize() {
103 ((DefaultGraph2DRenderer) view.getGraph2DRenderer()).setDrawEdgesFirst(true);
104 view.setPaintDetailThreshold(0.0);
105 Graph2DViewRepaintManager repaintManager = new Graph2DViewRepaintManager(view);
106 factory = new ViewAnimationFactory(repaintManager);
107 factory.setQuality(ViewAnimationFactory.HIGH_PERFORMANCE);
108 animationPlayer = factory.createConfiguredPlayer();
109 animationPlayer.setFps(25);
110
111 graphHider = new GraphHider(view.getGraph2D());
112 graphHider.setFireGraphEventsEnabled(true);
113
114 loadInitialGraph();
115
116 initLayouter();
117 initUpdater(repaintManager);
118 }
119
120 public void dispose() {
121 if (animationPlayer != null) {
122 animationPlayer.stop();
123 }
124 if (layouter != null) {
125 layouter.stop();
126 }
127 if (layoutThread != null) {
128 layoutThread.interrupt();
129 }
130 }
131
132 protected EditMode createEditMode() {
133 EditMode editMode = new EditMode() {
134 protected void nodeClicked(Node v) {
135 moveToCenter(v, true);
136 }
137 };
138 editMode.allowBendCreation(false);
139 editMode.allowEdgeCreation(false);
140 editMode.allowMoveLabels(false);
141 editMode.allowMovePorts(false);
142 editMode.allowNodeCreation(false);
143 editMode.allowNodeEditing(false);
144 editMode.allowResizeNodes(false);
145 editMode.setMoveSelectionMode(new InteractiveMoveSelectionMode(layouter));
146 return editMode;
147 }
148
149
152 protected TooltipMode createTooltipMode() {
153 return null;
154 }
155
156 protected void moveFirstNodeToCenter() {
157 if (view.getGraph2D().nodeCount() > 0) {
158 moveToCenter(view.getGraph2D().firstNode(), false);
159 }
160 }
161
162
167 protected void initUpdater(final Graph2DViewRepaintManager repaintManager) {
168 final AnimationObject updater = new AnimationObject() {
170 public long preferredDuration() {
171 return Long.MAX_VALUE;
172 }
173
174 public void calcFrame(double time) {
175 if (updatePositions()) {
176 repaintManager.invalidate();
177 }
178 }
179
180 public void initAnimation() {
181 }
182
183 public void disposeAnimation() {
184 }
185 };
186 animationPlayer.animate(updater);
187 }
188
189
192 protected void loadInitialGraph() {
193 loadGraph("resource/peopleNav.graphml");
194 LayoutTool.resetPaths(view.getGraph2D());
195 view.setZoom(0.80);
196 view.updateView();
197 }
198
199
203 protected void initLayouter() {
204 layouter = new InteractiveOrganicLayouter();
205
206 layouter.setMaxTime(2000);
208
209 layoutThread = layouter.startLayout(new CopiedLayoutGraph(view.getGraph2D()));
212 layoutThread.setPriority(Thread.MIN_PRIORITY);
213 }
214
215
224 protected boolean updatePositions() {
225 if (layouter == null || !layouter.isRunning()) {
226 return false;
227 }
228 double maxMovement = layouter.commitPositionsSmoothly(50, 0.15);
229 return maxMovement > 0;
230 }
231
232
238 protected void moveToCenter(final Node newCenterNode, boolean animated) {
239 if (centerNode != null) {
243 layouter.setInertia(centerNode, 0);
245 }
246 centerNode = newCenterNode;
247
248 layouter.setInertia(newCenterNode, 1);
250
251 NodeList hiddenNodes = new NodeList(graphHider.hiddenNodes());
252
253 graphHider.unhideAll();
254
255 NodeList toHide = new NodeList(view.getGraph2D().nodes());
256 NodeMap nodeMap = view.getGraph2D().createNodeMap();
257 NodeList[] layers = Bfs.getLayers(view.getGraph2D(), new NodeList(centerNode), false, nodeMap, 3);
258 view.getGraph2D().disposeNodeMap(nodeMap);
259 for (int i = 0; i < layers.length; i++) {
260 NodeList layer = layers[i];
261 toHide.removeAll(layer);
262 }
263
264 graphHider.hide(toHide);
265
266 double centerX = view.getGraph2D().getCenterX(newCenterNode);
268 double centerY = view.getGraph2D().getCenterY(newCenterNode);
269 for (NodeCursor nc = hiddenNodes.nodes(); nc.ok(); nc.next()) {
270 if (view.getGraph2D().contains(nc.node())) {
271 view.getGraph2D().setCenter(nc.node(), centerX, centerY);
272 layouter.setCenter(nc.node(), centerX, centerY);
273 }
274 }
275
276 layouter.wakeUp();
277
278 double x;
280 double y;
281 YPoint point = layouter.getCenter(newCenterNode);
282 if (point != null) {
283 x = point.getX();
284 y = point.getY();
285 } else {
286 NodeRealizer realizer = view.getGraph2D().getRealizer(newCenterNode);
287 x = realizer.getX();
288 y = realizer.getY();
289 }
290
291 if (animated) {
292 AnimationObject animationObject = factory.moveCamera(DefaultMutableValue2D.create(x, y), PREFERRED_DURATION);
294 AnimationObject easedAnimation = AnimationFactory.createEasedAnimation(animationObject, 0.15, 0.25);
295 animationPlayer.animate(easedAnimation);
296 } else {
297 view.setCenter(x, y);
298 }
299
300 layouter.syncStructure();
302 layouter.wakeUp();
303 }
304
305
308 protected void setPosition(Node node, double x, double y) {
309 if (layouter == null || !layouter.isRunning()) {
310 return;
311 }
312 layouter.setCenter(node, x, y);
313 }
314
315
316 protected Action createLoadAction() {
317 return new DemoBase.LoadAction() {
318 public void actionPerformed(ActionEvent e) {
319 layouter.stop();
320 centerNode = null;
321 super.actionPerformed(e);
322 graphHider = new GraphHider(view.getGraph2D());
323 LayoutTool.resetPaths(view.getGraph2D());
324
325 initLayouter();
326
327 moveFirstNodeToCenter();
328 }
329 };
330 }
331
332 protected boolean isDeletionEnabled() {
333 return false;
334 }
335 }