package org.limewire.mojito.visual; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import org.limewire.mojito.Context; import org.limewire.mojito.routing.Bucket; import org.limewire.mojito.routing.RouteTable; import org.limewire.mojito.visual.components.BinaryEdge; import org.limewire.mojito.visual.components.BinaryEdge.EdgeType; import org.limewire.mojito.visual.graph.BucketGraph; import org.limewire.mojito.visual.graph.NodeGraph; import org.limewire.mojito.visual.graph.RouteTableGraph; import org.limewire.mojito.visual.helper.RouteTableGraphMousePlugin; import org.limewire.mojito.visual.helper.RouteTableToolTipFunction; import org.limewire.mojito.visual.helper.RouteTableVertexPaintFunction; import org.limewire.mojito.visual.helper.RouteTableVertexShapeFunction; import edu.uci.ics.jung.graph.ArchetypeEdge; import edu.uci.ics.jung.graph.ArchetypeVertex; import edu.uci.ics.jung.graph.decorators.EdgeShape; import edu.uci.ics.jung.graph.decorators.EdgeStringer; import edu.uci.ics.jung.graph.decorators.PickableEdgePaintFunction; import edu.uci.ics.jung.graph.decorators.VertexStringer; import edu.uci.ics.jung.visualization.DefaultGraphLabelRenderer; import edu.uci.ics.jung.visualization.GraphZoomScrollPane; import edu.uci.ics.jung.visualization.Layout; import edu.uci.ics.jung.visualization.PluggableRenderer; import edu.uci.ics.jung.visualization.ShapePickSupport; import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.contrib.TreeLayout; import edu.uci.ics.jung.visualization.control.LayoutScalingControl; import edu.uci.ics.jung.visualization.control.PickingGraphMousePlugin; import edu.uci.ics.jung.visualization.control.PluggableGraphMouse; import edu.uci.ics.jung.visualization.control.ScalingGraphMousePlugin; import edu.uci.ics.jung.visualization.control.ViewScalingControl; /** * A visualizer for the Routing table. This is only experimental! * */ public class RouteTableVisualizer implements RouteTableGraphCallback, RouteTableUICallback{ private JPanel graphComponent; private JTextArea txtArea; private VisualizationViewer vv; private RouteTableGraph routeTableGraph; RouteTable routeTable; public static RouteTableVisualizer show(final RouteTable routeTable) { RouteTableVisualizer viz = new RouteTableVisualizer(routeTable); createAndShowFrame(viz, "RouteTable"); return viz; } public static RouteTableVisualizer show(final Context context) { RouteTableVisualizer viz = new RouteTableVisualizer(context); createAndShowFrame(viz, context.getName()); return viz; } private static void createAndShowFrame(final RouteTableVisualizer visualizer, final String name) { SwingUtilities.invokeLater(new Runnable() { public void run() { final JFrame jf = new JFrame(name); jf.getContentPane().add (visualizer.getComponent()); jf.pack(); jf.addWindowListener(new WindowListener() { public void windowActivated(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowClosing(WindowEvent e) { visualizer.stop(); } public void windowDeactivated(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowOpened(WindowEvent e) {} }); jf.setVisible(true); } }); } public RouteTableVisualizer(Context dht) { this(dht.getRouteTable()); } public RouteTableVisualizer(RouteTable routetTable) { routeTable = routetTable; routeTableGraph = new BucketGraph(routeTable, this); init(); } private void init() { //now update the graph with the route table data routeTableGraph.populateGraph(); //create layout Layout layout = new TreeLayout(routeTableGraph.getTree()); //render graph PluggableRenderer pr = new PluggableRenderer(); //vertex pr.setVertexPaintFunction(new RouteTableVertexPaintFunction( pr, Color.black, Color.white, Color.blue, Color.yellow, Color.red)); pr.setVertexShapeFunction(new RouteTableVertexShapeFunction()); VertexStringer vertStringer = new VertexStringer() { public String getLabel(ArchetypeVertex v) { return getLabelForVertex(v); } }; pr.setVertexStringer(vertStringer); //edge EdgeStringer edgeStringer = new EdgeStringer(){ public String getLabel(ArchetypeEdge e) { if(!(e instanceof BinaryEdge)) { return e.toString(); } BinaryEdge be = (BinaryEdge)e; return (be.getType().equals(EdgeType.LEFT)?"0":"1"); } }; pr.setEdgeStringer(edgeStringer); pr.setEdgePaintFunction(new PickableEdgePaintFunction(pr, Color.black, Color.cyan)); pr.setEdgeShapeFunction(new EdgeShape.Line()); pr.setGraphLabelRenderer(new DefaultGraphLabelRenderer(Color.cyan, Color.cyan)); //create JPanel vv = new VisualizationViewer(layout, pr, new Dimension(400,400)); vv.setPickSupport(new ShapePickSupport()); vv.setBackground(Color.white); // add a listener for ToolTips vv.setToolTipFunction(new RouteTableToolTipFunction()); PluggableGraphMouse graphMouse = new PluggableGraphMouse(); graphMouse.add(new PickingGraphMousePlugin()); graphMouse.add(new ScalingGraphMousePlugin( new ViewScalingControl(), MouseEvent.CTRL_MASK)); graphMouse.add(new ScalingGraphMousePlugin( new LayoutScalingControl(), 0)); graphMouse.add(new RouteTableGraphMousePlugin(this)); vv.setGraphMouse(graphMouse); //create south panel txtArea = new JTextArea(); txtArea.setText(routeTableGraph.getGraphInfo()); JScrollPane pane = new JScrollPane(txtArea); //create main compononent JPanel graphPanel = new GraphZoomScrollPane(vv); graphComponent = new JPanel(new BorderLayout()); graphComponent.add(graphPanel, BorderLayout.CENTER); graphComponent.add(pane, BorderLayout.SOUTH); repaint(); } private synchronized void repaint() { vv.setGraphLayout(new TreeLayout(routeTableGraph.getTree())); SwingUtilities.invokeLater(new Runnable() { public void run() { vv.invalidate(); vv.revalidate(); vv.repaint(); txtArea.setText(routeTableGraph.getGraphInfo()); } }); } /** * Displays the graph containing all the Route Table's buckets */ private synchronized void showBucketGraph() { stop(); routeTableGraph = new BucketGraph(routeTable, this); routeTableGraph.populateGraph(); repaint(); } /** * Displays the graph containing all the specified bucket's contacts * */ private synchronized void showNodeGraph(Bucket bucket) { stop(); routeTableGraph = new NodeGraph(routeTable, this, bucket); routeTableGraph.populateGraph(); repaint(); } private synchronized void updateTextArea() { SwingUtilities.invokeLater(new Runnable() { public void run() { txtArea.setText(routeTableGraph.getGraphInfo()); } }); } private String getLabelForVertex(ArchetypeVertex v) { return routeTableGraph.getLabelForVertex(v); } public synchronized void handleGraphLayoutUpdated() { repaint(); } public void handleRouteTableCleared() { showBucketGraph(); } public synchronized void handleGraphInfoUpdated() { updateTextArea(); } public void handleBucketSelected(Bucket bucket) { showNodeGraph(bucket); updateTextArea(); } public void handleNodeGraphRootSelected() { showBucketGraph(); } public Component getComponent() { return graphComponent; } public void stop() { routeTableGraph.deregister(); } }