Java tutorial
/* * Copyright (c) 2003, the JUNG Project and the Regents of the University of * California All rights reserved. * * This software is open-source under the BSD license; see either "license.txt" * or http://jung.sourceforge.net/license.txt for a description. * */ package com.google.code.facebook.graph.sna.applet; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.swing.BorderFactory; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenuBar; import javax.swing.JPanel; import javax.swing.JRadioButton; import org.apache.commons.collections15.Factory; import edu.uci.ics.jung.algorithms.layout.PolarPoint; import edu.uci.ics.jung.algorithms.layout.RadialTreeLayout; import edu.uci.ics.jung.algorithms.layout.TreeLayout; import edu.uci.ics.jung.graph.DelegateForest; import edu.uci.ics.jung.graph.DelegateTree; import edu.uci.ics.jung.graph.DirectedGraph; import edu.uci.ics.jung.graph.DirectedSparseGraph; import edu.uci.ics.jung.graph.Forest; import edu.uci.ics.jung.graph.Tree; import edu.uci.ics.jung.visualization.DefaultVisualizationModel; import edu.uci.ics.jung.visualization.GraphZoomScrollPane; import edu.uci.ics.jung.visualization.Layer; import edu.uci.ics.jung.visualization.VisualizationModel; import edu.uci.ics.jung.visualization.VisualizationServer; import edu.uci.ics.jung.visualization.VisualizationViewer; import edu.uci.ics.jung.visualization.control.CrossoverScalingControl; import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; import edu.uci.ics.jung.visualization.control.ModalLensGraphMouse; import edu.uci.ics.jung.visualization.control.ScalingControl; import edu.uci.ics.jung.visualization.decorators.EdgeShape; import edu.uci.ics.jung.visualization.decorators.PickableEdgePaintTransformer; import edu.uci.ics.jung.visualization.decorators.PickableVertexPaintTransformer; import edu.uci.ics.jung.visualization.decorators.ToStringLabeller; import edu.uci.ics.jung.visualization.picking.PickedState; import edu.uci.ics.jung.visualization.transform.LensSupport; import edu.uci.ics.jung.visualization.transform.shape.HyperbolicShapeTransformer; import edu.uci.ics.jung.visualization.transform.shape.ViewLensSupport; /** * Shows a RadialTreeLayout view of a Forest. * A hyperbolic projection lens may also be applied * to the view * * @author Tom Nelson * */ @SuppressWarnings("serial") public class RadialTreeLensDemo extends JApplet { Forest<String, Integer> graph; Factory<DirectedGraph<String, Integer>> graphFactory = new Factory<DirectedGraph<String, Integer>>() { public DirectedGraph<String, Integer> create() { return new DirectedSparseGraph<String, Integer>(); } }; Factory<Tree<String, Integer>> treeFactory = new Factory<Tree<String, Integer>>() { public Tree<String, Integer> create() { return new DelegateTree<String, Integer>(graphFactory); } }; Factory<Integer> edgeFactory = new Factory<Integer>() { int i = 0; public Integer create() { return i++; } }; Factory<String> vertexFactory = new Factory<String>() { int i = 0; public String create() { return "V" + i++; } }; VisualizationServer.Paintable rings; String root; TreeLayout<String, Integer> layout; RadialTreeLayout<String, Integer> radialLayout; /** * the visual component and renderer for the graph */ VisualizationViewer<String, Integer> vv; /** * provides a Hyperbolic lens for the view */ LensSupport hyperbolicViewSupport; ScalingControl scaler; /** * create an instance of a simple graph with controls to * demo the zoomand hyperbolic features. * */ public RadialTreeLensDemo() { // create a simple graph for the demo // create a simple graph for the demo graph = new DelegateForest<String, Integer>(); createTree(); layout = new TreeLayout<String, Integer>(graph); radialLayout = new RadialTreeLayout<String, Integer>(graph); radialLayout.setSize(new Dimension(600, 600)); Dimension preferredSize = new Dimension(600, 600); final VisualizationModel<String, Integer> visualizationModel = new DefaultVisualizationModel<String, Integer>( radialLayout, preferredSize); vv = new VisualizationViewer<String, Integer>(visualizationModel, preferredSize); PickedState<String> ps = vv.getPickedVertexState(); PickedState<Integer> pes = vv.getPickedEdgeState(); vv.getRenderContext().setVertexFillPaintTransformer( new PickableVertexPaintTransformer<String>(ps, Color.red, Color.yellow)); vv.getRenderContext().setEdgeDrawPaintTransformer( new PickableEdgePaintTransformer<Integer>(pes, Color.black, Color.cyan)); vv.setBackground(Color.white); vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<String>()); vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line()); // add a listener for ToolTips vv.setVertexToolTipTransformer(new ToStringLabeller<String>()); Container content = getContentPane(); GraphZoomScrollPane gzsp = new GraphZoomScrollPane(vv); content.add(gzsp); /** * the regular graph mouse for the normal view */ final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse(); vv.setGraphMouse(graphMouse); vv.addKeyListener(graphMouse.getModeKeyListener()); rings = new Rings(); vv.addPreRenderPaintable(rings); hyperbolicViewSupport = new ViewLensSupport<String, Integer>(vv, new HyperbolicShapeTransformer(vv, vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW)), new ModalLensGraphMouse()); final ScalingControl scaler = new CrossoverScalingControl(); JButton plus = new JButton("+"); plus.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1.1f, vv.getCenter()); } }); JButton minus = new JButton("-"); minus.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1 / 1.1f, vv.getCenter()); } }); final JRadioButton hyperView = new JRadioButton("Hyperbolic View"); hyperView.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { hyperbolicViewSupport.activate(e.getStateChange() == ItemEvent.SELECTED); } }); graphMouse.addItemListener(hyperbolicViewSupport.getGraphMouse().getModeListener()); JMenuBar menubar = new JMenuBar(); menubar.add(graphMouse.getModeMenu()); gzsp.setCorner(menubar); JPanel controls = new JPanel(); JPanel zoomControls = new JPanel(new GridLayout(2, 1)); zoomControls.setBorder(BorderFactory.createTitledBorder("Zoom")); JPanel hyperControls = new JPanel(new GridLayout(3, 2)); hyperControls.setBorder(BorderFactory.createTitledBorder("Examiner Lens")); zoomControls.add(plus); zoomControls.add(minus); JPanel modeControls = new JPanel(new BorderLayout()); modeControls.setBorder(BorderFactory.createTitledBorder("Mouse Mode")); modeControls.add(graphMouse.getModeComboBox()); hyperControls.add(hyperView); controls.add(zoomControls); controls.add(hyperControls); controls.add(modeControls); content.add(controls, BorderLayout.SOUTH); } private void createTree() { graph.addVertex("V0"); graph.addEdge(edgeFactory.create(), "V0", "V1"); graph.addEdge(edgeFactory.create(), "V0", "V2"); graph.addEdge(edgeFactory.create(), "V1", "V4"); graph.addEdge(edgeFactory.create(), "V2", "V3"); graph.addEdge(edgeFactory.create(), "V2", "V5"); graph.addEdge(edgeFactory.create(), "V4", "V6"); graph.addEdge(edgeFactory.create(), "V4", "V7"); graph.addEdge(edgeFactory.create(), "V3", "V8"); graph.addEdge(edgeFactory.create(), "V6", "V9"); graph.addEdge(edgeFactory.create(), "V4", "V10"); graph.addVertex("A0"); graph.addEdge(edgeFactory.create(), "A0", "A1"); graph.addEdge(edgeFactory.create(), "A0", "A2"); graph.addEdge(edgeFactory.create(), "A0", "A3"); graph.addVertex("B0"); graph.addEdge(edgeFactory.create(), "B0", "B1"); graph.addEdge(edgeFactory.create(), "B0", "B2"); graph.addEdge(edgeFactory.create(), "B1", "B4"); graph.addEdge(edgeFactory.create(), "B2", "B3"); graph.addEdge(edgeFactory.create(), "B2", "B5"); graph.addEdge(edgeFactory.create(), "B4", "B6"); graph.addEdge(edgeFactory.create(), "B4", "B7"); graph.addEdge(edgeFactory.create(), "B3", "B8"); graph.addEdge(edgeFactory.create(), "B6", "B9"); } class Rings implements VisualizationServer.Paintable { Collection<Double> depths; public Rings() { depths = getDepths(); } private Collection<Double> getDepths() { Set<Double> depths = new HashSet<Double>(); Map<String, PolarPoint> polarLocations = radialLayout.getPolarLocations(); for (String v : graph.getVertices()) { PolarPoint pp = polarLocations.get(v); depths.add(pp.getRadius()); } return depths; } public void paint(Graphics g) { g.setColor(Color.gray); Graphics2D g2d = (Graphics2D) g; Point2D center = radialLayout.getCenter(); Ellipse2D ellipse = new Ellipse2D.Double(); for (double d : depths) { ellipse.setFrameFromDiagonal(center.getX() - d, center.getY() - d, center.getX() + d, center.getY() + d); Shape shape = vv.getRenderContext().getMultiLayerTransformer().transform(ellipse); // vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).transform(ellipse); g2d.draw(shape); } } public boolean useTransform() { return true; } } /** * a driver for this demo */ public static void main(String[] args) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(new RadialTreeLensDemo()); f.pack(); f.setVisible(true); } }