1   package demo.yext.graphml;
2   
3   
4   import org.graphdrawing.graphml.attr.AttributeConstants;
5   import y.base.DataMap;
6   import y.base.Edge;
7   import y.base.EdgeMap;
8   import y.base.Graph;
9   import y.base.Node;
10  import y.base.NodeMap;
11  import y.option.OptionHandler;
12  import y.util.Maps;
13  import y.view.EditMode;
14  import y.view.PopupMode;
15  import y.view.ViewMode;
16  import y.view.HitInfo;
17  import yext.graphml.graph2D.GraphMLIOHandler;
18  
19  import javax.swing.AbstractAction;
20  import javax.swing.JMenu;
21  import javax.swing.JPopupMenu;
22  import java.awt.event.ActionEvent;
23  import java.util.HashMap;
24  
25  
26  /**
27   * This demo shows how to configure GraphMLIOHandler to be able to handle
28   * extra node, edge and graph data of simple type.
29   * Additional data for a node and edge can be edited by right-clicking on the corresponding
30   * element. To edit the graph data, right-click on the canvas background.
31   * The element tooltip will show the currently set data values for each element.
32   */
33  public class CustomGraphMLDemo extends GraphMLDemo {
34  
35    /** stores a boolean value for each node **/
36    NodeMap node2BoolMap;
37  
38    /** stores an int value for each edge **/
39    EdgeMap edge2IntMap;
40  
41    /** stores an String value for the graph **/
42    DataMap graph2StringMap;
43  
44    public CustomGraphMLDemo() {
45  
46      //define a view mode that displays the currently set data values
47      ViewMode tooltipMode = new ViewMode() {
48        public void mouseMoved(double x, double y) {
49          HitInfo info = getHitInfo(x,y);
50          if (info.getHitNode() != null) {
51            view.setToolTipText("Node:BooleanValue=" + node2BoolMap.getBool(info.getHitNode()));
52          } else if (info.getHitEdge() != null) {
53            view.setToolTipText("Edge:IntValue=" + edge2IntMap.getInt(info.getHitEdge()));
54          } else {
55            view.setToolTipText("Graph:StringValue=" + graph2StringMap.get(view.getGraph2D()));
56          }
57        }
58      };
59      //add the view mode to the view
60      view.addViewMode(tooltipMode);
61    }
62  
63    /**
64     * Configures GraphMLIOHandler to read and write additional node, edge and graph data
65     * of a simple type.
66     */
67    protected GraphMLIOHandler createGraphMLIOHandler() {
68      GraphMLIOHandler ioHandler = super.createGraphMLIOHandler();
69  
70      Graph graph = view.getGraph2D();
71  
72      node2BoolMap = graph.createNodeMap();
73      ioHandler.addAttribute(node2BoolMap, "BooleanValue", AttributeConstants.TYPE_BOOLEAN);
74  
75      edge2IntMap = graph.createEdgeMap();
76      ioHandler.addAttribute(edge2IntMap, "IntValue", AttributeConstants.TYPE_INT);
77  
78      graph2StringMap = Maps.createDataMap(new HashMap());
79      ioHandler.addGraphAttribute(graph2StringMap, graph2StringMap, "StringValue", AttributeConstants.TYPE_STRING);
80  
81      return ioHandler;
82    }
83  
84  
85    /**
86     * Create an edit mode that displays a context-sensitive popup-menu when right-clicking
87     * on an the canvas.
88     */
89    protected EditMode createEditMode() {
90      EditMode editMode = super.createEditMode();
91  
92      editMode.setPopupMode(new PopupMode() {
93        public JPopupMenu getNodePopup(Node v) {
94          JPopupMenu pm = new JPopupMenu();
95          pm.add(new EditAttributeAction("Edit Node Attribute...", v, node2BoolMap, AttributeConstants.TYPE_BOOLEAN));
96          return pm;
97        }
98  
99        public JPopupMenu getEdgePopup(Edge e) {
100         JPopupMenu pm = new JPopupMenu();
101         pm.add(new EditAttributeAction("Edit Edge Attribute...", e, edge2IntMap, AttributeConstants.TYPE_INT));
102         return pm;
103       }
104 
105       public JPopupMenu getPaperPopup(double x, double y) {
106         JPopupMenu pm = new JPopupMenu();
107         pm.add(new EditAttributeAction("Edit Graph Attribute...", getGraph2D(), graph2StringMap, AttributeConstants.TYPE_STRING));
108         return pm;
109       }
110     });
111 
112     return editMode;
113   }
114 
115 
116   /**
117    * Editor action for the additional node, edge and graph attributes.
118    */
119   static class EditAttributeAction extends AbstractAction {
120     private Object object;
121     private DataMap dataMap;
122     private int dataType;
123 
124     private OptionHandler op;
125 
126     EditAttributeAction(String name, Object object, DataMap dataMap, int dataType) {
127       super(name);
128       this.object = object;
129       this.dataMap = dataMap;
130       this.dataType = dataType;
131       op = new OptionHandler(name);
132       if (dataType == AttributeConstants.TYPE_BOOLEAN) {
133         op.addBool("Boolean Value", dataMap.getBool(object));
134       } else if (dataType == AttributeConstants.TYPE_INT) {
135         op.addInt("Integer Value", dataMap.getInt(object));
136       } else if (dataType == AttributeConstants.TYPE_STRING) {
137         op.addString("String Value", (String) dataMap.get(object));
138       }
139     }
140 
141     public void actionPerformed(ActionEvent actionEvent) {
142       if (op.showEditor()) {
143         if (dataType == AttributeConstants.TYPE_BOOLEAN) {
144           dataMap.setBool(object, op.getBool("Boolean Value"));
145         } else if (dataType == AttributeConstants.TYPE_INT) {
146           dataMap.setInt(object, op.getInt("Integer Value"));
147         } else if (dataType == AttributeConstants.TYPE_STRING) {
148           dataMap.set(object, op.getString("String Value"));
149         }
150       }
151     }
152   }
153 
154   /**
155    * Add sample graphs to the menu.
156    */
157   protected JMenu createSampleGraphMenu() {
158     return createSampleGraphMenu(new String[]{"resources/custom/demo.graphml"});
159   }
160 
161   /**
162    * Launches this demo.
163    */
164   public static void main(String[] args) {
165     initLnF();
166     final CustomGraphMLDemo demo = new CustomGraphMLDemo();
167     demo.start();
168   }
169 }
170