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.rendering;
29  
30  import demo.view.DemoBase;
31  import y.base.Edge;
32  import y.base.Node;
33  import y.geom.YPoint;
34  import y.view.BridgeCalculator;
35  import y.view.DefaultGraph2DRenderer;
36  import y.view.Graph2D;
37  
38  import javax.swing.JComboBox;
39  import javax.swing.JLabel;
40  import javax.swing.JToolBar;
41  import java.awt.EventQueue;
42  import java.awt.event.ActionEvent;
43  import java.awt.event.ActionListener;
44  import java.util.Locale;
45  
46  /**
47   * This class demonstrates how to utilize {@link BridgeCalculator} to draw bridges/gaps for crossing edges.
48   * It demonstrates how {@link y.view.PolyLineEdgeRealizer} automatically makes use of
49   * the {@link BridgeCalculator} registered with the default {@link y.view.Graph2DRenderer} instance to
50   * incorporate the calculation of bridges.
51   *
52   * @see <a href="http://docs.yworks.com/yfiles/doc/api/index.html#/dguide/mvc_view#renderer" target="_blank">Section View Implementations</a> in the yFiles for Java Developer's Guide
53   */
54  public class BridgeDemo extends DemoBase {
55    BridgeCalculator bridgeCalculator;
56  
57    public BridgeDemo() {
58      // create the BridgeCalculator
59      bridgeCalculator = new BridgeCalculator();
60  
61      // register it with the DefaultGraph2DRenderer
62      ((DefaultGraph2DRenderer) view.getGraph2DRenderer()).setBridgeCalculator(bridgeCalculator);
63  
64      // create a nice graph that shows all possible configurations...
65      final Graph2D graph = view.getGraph2D();
66      Node[] nodes = new Node[16];
67      
68      int count = 0;
69      double hDist = graph.getDefaultNodeRealizer().getWidth() + 10;
70      double vDist = graph.getDefaultNodeRealizer().getHeight() + 10;
71      
72      for (int i = 1; i < 5; i++) {      
73        nodes[count++] = graph.createNode(50 + hDist * i, vDist*5+50);
74        nodes[count++] = graph.createNode(50 + hDist * i, 40);
75        nodes[count++] = graph.createNode(40, 50 + vDist * i);
76        nodes[count++] = graph.createNode(50+hDist*5, 50 + vDist * i);
77      }
78  
79      graph.createEdge(nodes[0], nodes[1]);
80  
81      Edge e = graph.createEdge(nodes[0], nodes[1]);
82      graph.setSourcePointRel(e, new YPoint(5, 0));
83      graph.setTargetPointRel(e, new YPoint(5, 0));
84  
85      graph.createEdge(nodes[5], nodes[4]);
86  
87      graph.createEdge(nodes[2], nodes[3]);
88      e = graph.createEdge(nodes[2], nodes[3]);
89      graph.setSourcePointRel(e, new YPoint(0, 5));
90      graph.setTargetPointRel(e, new YPoint(0, 5));
91  
92      graph.createEdge(nodes[7], nodes[6]);
93  
94      graph.createEdge(nodes[2 + 8], nodes[3 + 8]);
95      graph.createEdge(nodes[7 + 8], nodes[6 + 8]);
96  
97      graph.createEdge(nodes[0 + 8], nodes[1 + 8]);
98      graph.createEdge(nodes[5 + 8], nodes[4 + 8]);
99  
100     getUndoManager().resetQueue();
101   }
102 
103   protected JToolBar createToolBar() {
104     final JComboBox crossingModeCB = new JComboBox(new Object[]{"Horizontal Crosses Vertical", "Vertical Crosses Horizontal", "Induced by Edge Ordering"});
105     crossingModeCB.setMaximumSize(crossingModeCB.getPreferredSize());
106     crossingModeCB.setSelectedIndex(0);
107     crossingModeCB.addActionListener(new ActionListener() {
108       public void actionPerformed(ActionEvent e) {
109         bridgeCalculator.setCrossingMode(getCrossingModeForIndex(crossingModeCB.getSelectedIndex()));
110         view.getGraph2D().updateViews();
111       }
112     });
113     final JComboBox crossingStyleCB = new JComboBox(new Object[]{"Gap", "Arc", "Square", "Two Sides", "Scaled Arc", "Scaled Square", "Scaled Two Sides"});
114     crossingStyleCB.setMaximumSize(crossingStyleCB.getPreferredSize());
115     crossingStyleCB.setSelectedIndex(1);
116     crossingStyleCB.addActionListener(new ActionListener() {
117       public void actionPerformed(ActionEvent e) {
118         bridgeCalculator.setCrossingStyle((short) crossingStyleCB.getSelectedIndex());
119         view.getGraph2D().updateViews();
120       }
121     });
122     final JComboBox orientationStyleCB = new JComboBox(
123         new Object[]{"Up", "Down", "Left", "Right", "Positive", "Negative", "Flow Left", "Flow Right"});
124     orientationStyleCB.setMaximumSize(orientationStyleCB.getPreferredSize());
125     orientationStyleCB.setSelectedIndex(4);
126     orientationStyleCB.addActionListener(new ActionListener() {
127       public void actionPerformed(ActionEvent e) {
128         bridgeCalculator.setOrientationStyle((short) (orientationStyleCB.getSelectedIndex() + 1));
129         view.getGraph2D().updateViews();
130       }
131     });
132 
133     final JToolBar toolBar = super.createToolBar();
134     toolBar.addSeparator();
135     toolBar.add(new JLabel("Bridge Style: "));
136     toolBar.add(crossingStyleCB);
137     toolBar.addSeparator(TOOLBAR_SMALL_SEPARATOR);
138     toolBar.add(orientationStyleCB);
139     toolBar.addSeparator(TOOLBAR_SMALL_SEPARATOR);
140     toolBar.add(crossingModeCB);
141     return toolBar;
142   }
143 
144   protected boolean isUndoRedoEnabled() {
145     return false;
146   }
147 
148   private static short getCrossingModeForIndex(int index) {
149     switch (index) {
150       case 0:
151       default:
152         return BridgeCalculator.CROSSING_MODE_HORIZONTAL_CROSSES_VERTICAL;
153       case 1:
154         return BridgeCalculator.CROSSING_MODE_VERTICAL_CROSSES_HORIZONTAL;
155       case 2:
156         return BridgeCalculator.CROSSING_MODE_ORDER_INDUCED;
157     }
158   }
159 
160   public static void main(String[] args) {
161     EventQueue.invokeLater(new Runnable() {
162       public void run() {
163         Locale.setDefault(Locale.ENGLISH);
164         initLnF();
165         new BridgeDemo().start("Bridge Demo");
166       }
167     });
168   }
169 }
170