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.io.graphml;
29  
30  
31  import y.base.DataMap;
32  import y.base.Edge;
33  import y.base.EdgeMap;
34  import y.base.Node;
35  import y.base.NodeMap;
36  import y.io.GraphMLIOHandler;
37  import y.io.graphml.KeyScope;
38  import y.io.graphml.KeyType;
39  import y.option.OptionHandler;
40  import y.view.EditMode;
41  import y.view.PopupMode;
42  import y.view.TooltipMode;
43  
44  import javax.swing.AbstractAction;
45  import javax.swing.JPopupMenu;
46  import java.awt.EventQueue;
47  import java.awt.event.ActionEvent;
48  import java.util.Locale;
49  
50  /**
51   * This demo shows how to configure GraphMLIOHandler to be able to handle
52   * extra node and edge data of simple type.
53   * Additional data for a node or an edge can be edited by right-clicking on the
54   * corresponding element.
55   * The element tool tip will show the currently set data values for each element.
56   *
57   * @see <a href="http://docs.yworks.com/yfiles/doc/api/index.html#/dguide/graphml#graphml_extension" target="_blank">Section Reading and Writing Additional Data</a> in the yFiles for Java Developer's Guide
58   */
59  public class SimpleAttributesDemo extends GraphMLDemo {
60  
61    /** stores a boolean value for each node **/
62    private NodeMap node2BoolMap;
63  
64    /** stores an int value for each edge **/
65    private EdgeMap edge2IntMap;
66  
67  
68    protected void loadInitialGraph() {
69      loadGraph("resources/custom/simple-attributes.graphml");
70    }
71  
72    protected TooltipMode createTooltipMode() {
73      TooltipMode tooltipMode = new TooltipMode() {
74        /**
75         * Overwrites {@link TooltipMode#getNodeTip(y.base.Node)} to set a customized tooltip text.
76         * @param node the node for which the tooltip is set
77         * @return the tooltip string that is used by the <code>TooltipMode</code>
78         */
79        protected String getNodeTip(Node node) {
80          return "Node:BooleanValue=" + node2BoolMap.getBool(node);
81        }
82  
83        /**
84         * Overwrites {@link TooltipMode#getEdgeTip(y.base.Edge)} to set a customized tooltip text.
85         * @param edge the edge for which the tooltip is set
86         * @return the tooltip string that is used by the <code>TooltipMode</code>
87         */
88        protected String getEdgeTip(Edge edge) {
89          return "Edge:IntValue=" + edge2IntMap.getInt(edge);
90        }
91      };
92      return tooltipMode;
93    }
94  
95    /**
96     * Configures GraphMLIOHandler to read and write additional node and edge data
97     * of a simple type.
98     */
99    protected GraphMLIOHandler createGraphMLIOHandler() {
100       //Create maps that store the attributes
101     if (node2BoolMap == null) {
102       node2BoolMap = view.getGraph2D().createNodeMap();
103     }
104     if (edge2IntMap == null) {
105       edge2IntMap = view.getGraph2D().createEdgeMap();
106     }
107 
108     GraphMLIOHandler ioHandler = super.createGraphMLIOHandler();
109 
110     //  <key id="d1" for="node" attr.name="BooleanValue" attr.type="boolean"/>
111     ioHandler.getGraphMLHandler().addInputDataAcceptor("BooleanValue", node2BoolMap, KeyScope.NODE, KeyType.BOOLEAN);
112     ioHandler.getGraphMLHandler().addOutputDataProvider("BooleanValue", node2BoolMap, KeyScope.NODE, KeyType.BOOLEAN);
113 
114     //  <key id="d3" for="edge" attr.name="IntValue" attr.type="int"/>
115     ioHandler.getGraphMLHandler().addInputDataAcceptor("IntValue", edge2IntMap, KeyScope.EDGE, KeyType.INT);
116     ioHandler.getGraphMLHandler().addOutputDataProvider("IntValue", edge2IntMap, KeyScope.EDGE, KeyType.INT);
117     return ioHandler;
118   }
119 
120 
121   protected String[] getExampleResources() {
122     return null;
123   }
124 
125   /**
126    * Create an edit mode that displays a context-sensitive popup-menu when
127    * right-clicking on a node or an edge.
128    */
129   protected EditMode createEditMode() {
130     EditMode mode = super.createEditMode();
131 
132     mode.setPopupMode(new PopupMode() {
133       public JPopupMenu getNodePopup(Node v) {
134         JPopupMenu pm = new JPopupMenu();
135         pm.add(new EditAttributeAction("Edit Node Attribute...", v, node2BoolMap, KeyType.BOOLEAN));
136         return pm;
137       }
138 
139       public JPopupMenu getEdgePopup(Edge e) {
140         JPopupMenu pm = new JPopupMenu();
141         pm.add(new EditAttributeAction("Edit Edge Attribute...", e, edge2IntMap, KeyType.INT));
142         return pm;
143       }
144     });
145 
146     return mode;
147   }
148 
149 
150   /**
151    * Editor action for the additional node and edge attributes.
152    */
153   class EditAttributeAction extends AbstractAction {
154     private Object object;
155     private DataMap dataMap;
156     private KeyType dataType;
157 
158     private OptionHandler op;
159 
160     EditAttributeAction(String name, Object object, DataMap dataMap, KeyType dataType) {
161       super(name);
162       this.object = object;
163       this.dataMap = dataMap;
164       this.dataType = dataType;
165       op = new OptionHandler(name);
166       if (dataType == KeyType.BOOLEAN) {
167         op.addBool("Boolean Value", dataMap.getBool(object));
168       } else if (dataType == KeyType.INT) {
169         op.addInt("Integer Value", dataMap.getInt(object));
170       }
171     }
172 
173     public void actionPerformed(ActionEvent actionEvent) {
174       if (op.showEditor()) {
175         if (dataType == KeyType.BOOLEAN) {
176           dataMap.setBool(object, op.getBool("Boolean Value"));
177         } else if (dataType == KeyType.INT) {
178           dataMap.setInt(object, op.getInt("Integer Value"));          
179         }        
180         graphMLPane.updateGraphMLText(view.getGraph2D());
181       }
182     }
183   }
184 
185   /**
186    * Launches this demo.
187    */
188   public static void main(String[] args) {
189     EventQueue.invokeLater(new Runnable() {
190       public void run() {
191         Locale.setDefault(Locale.ENGLISH);
192         initLnF();
193         (new SimpleAttributesDemo()).start();
194       }
195     });
196   }
197 }
198