1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.7. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2009 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.layout.labeling;
15  
16  import demo.view.DemoBase;
17  import y.base.Edge;
18  import y.base.EdgeCursor;
19  import y.base.Node;
20  import y.base.NodeCursor;
21  import y.layout.labeling.GreedyMISLabeling;
22  import y.option.MappedListCellRenderer;
23  import y.option.OptionHandler;
24  import y.view.DefaultBackgroundRenderer;
25  import y.view.EdgeLabel;
26  import y.view.EdgeRealizer;
27  import y.view.EditMode;
28  import y.view.Graph2D;
29  import y.view.NodeLabel;
30  import y.view.NodeRealizer;
31  import y.view.PopupMode;
32  import y.view.ShapeNodeRealizer;
33  import y.view.YLabel;
34  
35  import javax.swing.AbstractAction;
36  import javax.swing.JPopupMenu;
37  import javax.swing.JToolBar;
38  import java.awt.Color;
39  import java.awt.Dimension;
40  import java.awt.EventQueue;
41  import java.awt.event.ActionEvent;
42  import java.net.URL;
43  import java.util.Map;
44  
45  /**
46   * Demonstrates basic labeling features.
47   * <br/>
48   * It is shown:
49   * <ul>
50   * <li>how to create and manipulate labels</li>
51   * <li>how to assign a label model to a label</li>
52   * <li>how a labeling position can be changed interactively.</li>
53   * </ul>
54   * <br/>
55   * Usage: Labels can be moved to another valid position according to the current label
56   * model by using drag and drop. To change the label text for a node select the node
57   * and use the context menu. Moreover, you can add a label to a selected edge with
58   * the context menu. Use the toolbar button for changing the label model for nodes
59   * and/or edges.
60   *
61   */
62  public class LabelingDemo extends DemoBase {
63    private byte edgeLabelModel = EdgeLabel.SIX_POS;
64    private byte nodeLabelModel = NodeLabel.SANDWICH;
65  
66    public LabelingDemo() {
67      DefaultBackgroundRenderer renderer = new DefaultBackgroundRenderer( view );
68  
69      URL bgImage = getClass().getResource( "resource/usamap.gif" );
70      renderer.setImageResource( bgImage );
71      renderer.setMode( DefaultBackgroundRenderer.DYNAMIC );
72      renderer.setColor( Color.white );
73      view.setBackgroundRenderer( renderer );
74      view.setPreferredSize( new Dimension( 650, 400 ) );
75      view.setWorldRect( 0, 0, 650, 400 );
76  
77      // use thicker edges 
78      // EdgeRealizer er = view.getGraph2D().getDefaultEdgeRealizer();
79      // er.setLineType(LineType.LINE_2);
80  
81      ShapeNodeRealizer defaultNode =
82          new ShapeNodeRealizer( ShapeNodeRealizer.ELLIPSE );
83      defaultNode.setSize( 7, 7 );
84      defaultNode.setFillColor( Color.black );
85      defaultNode.getLabel().setModel( nodeLabelModel );
86      view.getGraph2D().setDefaultNodeRealizer( defaultNode );
87      createExample();
88    }
89  
90    protected void registerViewModes() {
91      //add a popup view mode that listens to the right mouse click
92      //and displays context sensitive menus
93      EditMode mode = new EditMode();
94      mode.setPopupMode( new DemoPopupMode() );
95      view.addViewMode( mode );
96    }
97  
98    protected JToolBar createToolBar() {
99      JToolBar bar = super.createToolBar();
100     bar.addSeparator();
101     bar.add( new ChangeLabelModel() );
102     return bar;
103   }
104 
105   class DemoPopupMode extends PopupMode {
106     /**
107      * Popup menu for a hit node
108      */
109     public JPopupMenu getNodePopup( Node v ) {
110       JPopupMenu pm = new JPopupMenu();
111       NodeRealizer r = this.view.getGraph2D().getRealizer( v );
112       YLabel label = r.getLabel();
113       pm.add( new EditLabel( label ) );
114       return pm;
115     }
116 
117     /**
118      * Popup menu for a hit node
119      */
120     public JPopupMenu getEdgePopup( Edge e ) {
121       JPopupMenu pm = new JPopupMenu();
122       pm.add( new AddEdgeLabel( e ) );
123       return pm;
124     }
125 
126     public JPopupMenu getEdgeLabelPopup( EdgeLabel el ) {
127       JPopupMenu pm = new JPopupMenu();
128       pm.add( new EditLabel( el ) );
129       return pm;
130     }
131   }
132 
133 
134   /**
135    * Action that opens a text editor for the label of a node
136    */
137   class EditLabel extends AbstractAction {
138     YLabel label;
139 
140     EditLabel( YLabel l ) {
141       super( "Edit Label" );
142       label = l;
143     }
144 
145     public void actionPerformed( ActionEvent e ) {
146       view.openLabelEditor( label,
147           label.getLocation().getX(),
148           label.getLocation().getY() );
149     }
150   }
151 
152   public class AddEdgeLabel extends AbstractAction {
153     Edge edge;
154 
155     public AddEdgeLabel( Edge e ) {
156       super( "Add Label" );
157       edge = e;
158     }
159 
160     public void actionPerformed( ActionEvent e ) {
161       if ( edge != null ) {
162         Graph2D g = view.getGraph2D();
163         EdgeRealizer er = g.getRealizer( edge );
164         EdgeLabel label = new EdgeLabel( "Route" );
165         er.addLabel( label );
166         g.updateViews();
167         //label.setModel(edgeLabelModel); // a valid option!
168       }
169     }
170   }
171 
172   /**
173    * Change label model model and apply new labeling
174    */
175   public class ChangeLabelModel extends AbstractAction {
176     OptionHandler op;
177 
178     ChangeLabelModel() {
179       super( "Change Label Model" );
180     }
181 
182     public void actionPerformed( ActionEvent e ) {
183       if ( op == null ) {
184         op = new OptionHandler( "Label Model" );
185         Map m1 = NodeLabel.modelToStringMap();
186         Map m2 = EdgeLabel.modelToStringMap();
187         op.addEnum( "Node Label Model",
188             m1.keySet().toArray(), new Byte( nodeLabelModel ),
189             new MappedListCellRenderer( m1 ) );
190         op.addEnum( "Edge Label Model",
191             m2.keySet().toArray(), new Byte( edgeLabelModel ),
192             new MappedListCellRenderer( m2 ) );
193       }
194 
195       if ( op.showEditor() ) {
196         byte model1 = ( ( ( Byte ) op.get( "Node Label Model" ) ).byteValue() );
197         for ( NodeCursor nc = view.getGraph2D().nodes(); nc.ok(); nc.next() ) {
198           view.getGraph2D().getRealizer( nc.node() ).getLabel().setModel( model1 );
199         }
200         nodeLabelModel = model1;
201         byte model2 = ( ( ( Byte ) op.get( "Edge Label Model" ) ).byteValue() );
202         for ( EdgeCursor ec = view.getGraph2D().edges(); ec.ok(); ec.next() ) {
203           EdgeRealizer er = view.getGraph2D().getRealizer( ec.edge() );
204           for ( int i = 0; i < er.labelCount(); i++ ) {
205             er.getLabel( i ).setModel( model2 );
206           }
207         }
208         edgeLabelModel = model2;
209       }
210       //now do actual labeling
211       // Here you may choose another labeling algorithm, i.e. SALabling
212       GreedyMISLabeling labeling = new GreedyMISLabeling();
213 
214       // use:
215       // labeling.setPlaceNodeLabels(true);
216       // labeling.setPlaceEdgeLabels(false);
217       // to label only nodes.
218       labeling.label( view.getGraph2D() );
219       view.updateView();
220     }
221   }
222 
223 
224   public void createExample() {
225     Graph2D graph = view.getGraph2D();
226     graph.clear();
227     Node n1 = graph.createNode();
228     graph.setCenter( n1, 100, 90 );
229     graph.setLabelText( n1, "City 1" );
230     Node n2 = graph.createNode();
231     graph.setCenter( n2, 150, 200 );
232     graph.setLabelText( n2, "City 2" );
233     Node n3 = graph.createNode();
234     graph.setCenter( n3, 250, 260 );
235     graph.setLabelText( n3, "City 3" );
236     Node n4 = graph.createNode();
237     graph.setCenter( n4, 300, 45 );
238     graph.setLabelText( n4, "City 4" );
239     Node n5 = graph.createNode();
240     graph.setCenter( n5, 500, 300 );
241     graph.setLabelText( n5, "City 5" );
242     Node n6 = graph.createNode();
243     graph.setCenter( n6, 50, 150 );
244     graph.setLabelText( n6, "City 6" );
245     Node n7 = graph.createNode();
246     graph.setCenter( n7, 45, 135 );
247     graph.setLabelText( n7, "City 7" );
248     Node n8 = graph.createNode();
249     graph.setCenter( n8, 55, 165 );
250     graph.setLabelText( n8, "City 8" );
251     Node n9 = graph.createNode();
252     graph.setCenter( n9, 620, 50 );
253     graph.setLabelText( n9, "City 9" );
254     Node n10 = graph.createNode();
255     graph.setCenter( n10, 450, 150 );
256     graph.setLabelText( n10, "City 10" );
257     Node n11 = graph.createNode();
258     graph.setCenter( n11, 270, 180 );
259     graph.setLabelText( n11, "City 11" );
260     Node n12 = graph.createNode();
261     graph.setCenter( n12, 580, 100 );
262     graph.setLabelText( n12, "City 12" );
263     //
264     Edge e1 = graph.createEdge( n6, n7 );
265     Edge e2 = graph.createEdge( n7, n8 );
266     Edge e3 = graph.createEdge( n1, n2 );
267     graph.getRealizer( e3 ).addLabel( new EdgeLabel( "Route 1" ) );
268     Edge e4 = graph.createEdge( n2, n3 );
269     graph.getRealizer( e4 ).addLabel( new EdgeLabel( "Route 2" ) );
270     Edge e5 = graph.createEdge( n1, n6 );
271     Edge e6 = graph.createEdge( n2, n8 );
272     Edge e7 = graph.createEdge( n3, n5 );
273     Edge e8 = graph.createEdge( n9, n10 );
274     Edge e9 = graph.createEdge( n11, n10 );
275     Edge e10 = graph.createEdge( n11, n3 );
276     graph.getRealizer( e10 ).addLabel( new EdgeLabel( "Route 3" ) );
277     graph.getRealizer( e10 ).addLabel( new EdgeLabel( "Out of order !" ) );
278     Edge e11 = graph.createEdge( n1, n4 );
279     Edge e12 = graph.createEdge( n11, n4 );
280     Edge e13 = graph.createEdge( n10, n4 );
281     Edge e14 = graph.createEdge( n10, n5 );
282     Edge e15 = graph.createEdge( n12, n5 );
283     Edge e16 = graph.createEdge( n9, n12 );
284   }
285 
286 
287   public static void main(String[] args) {
288     EventQueue.invokeLater(new Runnable() {
289       public void run() {
290         initLnF();
291         (new LabelingDemo()).start("Labeling Demo");
292       }
293     });
294   }
295 }
296 
297 
298       
299