
edu.uci.ics.jung.samples.BalloonLayoutDemo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jung-samples Show documentation
Show all versions of jung-samples Show documentation
Sample programs using JUNG. Nearly all JUNG capabilities are demonstrated here.
Please study the source code for these examples prior to asking how to do something.
The newest version!
/*
* Copyright (c) 2003, The JUNG Authors
* All rights reserved.
*
* This software is open-source under the BSD license; see either "license.txt"
* or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
*
*/
package edu.uci.ics.jung.samples;
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.Paint;
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.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import javax.swing.BorderFactory;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JToggleButton;
import com.google.common.base.Functions;
import com.google.common.base.Supplier;
import edu.uci.ics.jung.algorithms.layout.BalloonLayout;
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.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Forest;
import edu.uci.ics.jung.graph.Tree;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.Layer;
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.ModalGraphMouse;
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.ToStringLabeller;
import edu.uci.ics.jung.visualization.layout.LayoutTransition;
import edu.uci.ics.jung.visualization.transform.LensSupport;
import edu.uci.ics.jung.visualization.transform.MutableTransformer;
import edu.uci.ics.jung.visualization.transform.MutableTransformerDecorator;
import edu.uci.ics.jung.visualization.transform.shape.HyperbolicShapeTransformer;
import edu.uci.ics.jung.visualization.transform.shape.ViewLensSupport;
import edu.uci.ics.jung.visualization.util.Animator;
/**
* Demonstrates the visualization of a Tree using TreeLayout
* and BalloonLayout. An examiner lens performing a hyperbolic
* transformation of the view is also included.
*
* @author Tom Nelson
*
*/
@SuppressWarnings("serial")
public class BalloonLayoutDemo extends JApplet {
/**
* the graph
*/
Forest graph;
Supplier> graphFactory =
new Supplier>() {
public DirectedGraph get() {
return new DirectedSparseMultigraph();
}
};
Supplier> treeFactory =
new Supplier> () {
public Tree get() {
return new DelegateTree(graphFactory);
}
};
Supplier edgeFactory = new Supplier() {
int i=0;
public Integer get() {
return i++;
}};
Supplier vertexFactory = new Supplier() {
int i=0;
public String get() {
return "V"+i++;
}};
/**
* the visual component and renderer for the graph
*/
VisualizationViewer vv;
VisualizationServer.Paintable rings;
String root;
TreeLayout layout;
BalloonLayout radialLayout;
/**
* provides a Hyperbolic lens for the view
*/
LensSupport hyperbolicViewSupport;
public BalloonLayoutDemo() {
// create a simple graph for the demo
graph = new DelegateForest();
createTree();
layout = new TreeLayout(graph);
radialLayout = new BalloonLayout(graph);
radialLayout.setSize(new Dimension(900,900));
vv = new VisualizationViewer(layout, new Dimension(600,600));
vv.setBackground(Color.white);
vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.quadCurve(graph));
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
// add a listener for ToolTips
vv.setVertexToolTipTransformer(new ToStringLabeller());
vv.getRenderContext().setArrowFillPaintTransformer(Functions.constant(Color.lightGray));
rings = new Rings(radialLayout);
Container content = getContentPane();
final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
content.add(panel);
final DefaultModalGraphMouse graphMouse =
new DefaultModalGraphMouse();
vv.setGraphMouse(graphMouse);
vv.addKeyListener(graphMouse.getModeKeyListener());
hyperbolicViewSupport =
new ViewLensSupport(vv, new HyperbolicShapeTransformer(vv,
vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW)),
new ModalLensGraphMouse());
graphMouse.addItemListener(hyperbolicViewSupport.getGraphMouse().getModeListener());
JComboBox> modeBox = graphMouse.getModeComboBox();
modeBox.addItemListener(graphMouse.getModeListener());
graphMouse.setMode(ModalGraphMouse.Mode.TRANSFORMING);
final ScalingControl scaler = new CrossoverScalingControl();
vv.scaleToLayout(scaler);
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());
}
});
JToggleButton radial = new JToggleButton("Balloon");
radial.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED) {
LayoutTransition lt =
new LayoutTransition(vv, layout, radialLayout);
Animator animator = new Animator(lt);
animator.start();
vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).setToIdentity();
vv.addPreRenderPaintable(rings);
} else {
LayoutTransition lt =
new LayoutTransition(vv, radialLayout, layout);
Animator animator = new Animator(lt);
animator.start();
vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).setToIdentity();
vv.removePreRenderPaintable(rings);
}
vv.repaint();
}});
final JRadioButton hyperView = new JRadioButton("Hyperbolic View");
hyperView.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e) {
hyperbolicViewSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
}
});
JPanel scaleGrid = new JPanel(new GridLayout(1,0));
scaleGrid.setBorder(BorderFactory.createTitledBorder("Zoom"));
JPanel controls = new JPanel();
scaleGrid.add(plus);
scaleGrid.add(minus);
controls.add(radial);
controls.add(scaleGrid);
controls.add(modeBox);
controls.add(hyperView);
content.add(controls, BorderLayout.SOUTH);
}
class Rings implements VisualizationServer.Paintable {
BalloonLayout layout;
public Rings(BalloonLayout layout) {
this.layout = layout;
}
public void paint(Graphics g) {
g.setColor(Color.gray);
Graphics2D g2d = (Graphics2D)g;
Ellipse2D ellipse = new Ellipse2D.Double();
for(String v : layout.getGraph().getVertices()) {
Double radius = layout.getRadii().get(v);
if(radius == null) continue;
Point2D p = layout.apply(v);
ellipse.setFrame(-radius, -radius, 2*radius, 2*radius);
AffineTransform at = AffineTransform.getTranslateInstance(p.getX(), p.getY());
Shape shape = at.createTransformedShape(ellipse);
MutableTransformer viewTransformer =
vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW);
if(viewTransformer instanceof MutableTransformerDecorator) {
shape = vv.getRenderContext().getMultiLayerTransformer().transform(shape);
} else {
shape = vv.getRenderContext().getMultiLayerTransformer().transform(Layer.LAYOUT,shape);
}
g2d.draw(shape);
}
}
public boolean useTransform() {
return true;
}
}
/**
*
*/
private void createTree() {
graph.addVertex("A0");
graph.addEdge(edgeFactory.get(), "A0", "B0");
graph.addEdge(edgeFactory.get(), "A0", "B1");
graph.addEdge(edgeFactory.get(), "A0", "B2");
graph.addEdge(edgeFactory.get(), "B0", "C0");
graph.addEdge(edgeFactory.get(), "B0", "C1");
graph.addEdge(edgeFactory.get(), "B0", "C2");
graph.addEdge(edgeFactory.get(), "B0", "C3");
graph.addEdge(edgeFactory.get(), "C2", "H0");
graph.addEdge(edgeFactory.get(), "C2", "H1");
graph.addEdge(edgeFactory.get(), "B1", "D0");
graph.addEdge(edgeFactory.get(), "B1", "D1");
graph.addEdge(edgeFactory.get(), "B1", "D2");
graph.addEdge(edgeFactory.get(), "B2", "E0");
graph.addEdge(edgeFactory.get(), "B2", "E1");
graph.addEdge(edgeFactory.get(), "B2", "E2");
graph.addEdge(edgeFactory.get(), "D0", "F0");
graph.addEdge(edgeFactory.get(), "D0", "F1");
graph.addEdge(edgeFactory.get(), "D0", "F2");
graph.addEdge(edgeFactory.get(), "D1", "G0");
graph.addEdge(edgeFactory.get(), "D1", "G1");
graph.addEdge(edgeFactory.get(), "D1", "G2");
graph.addEdge(edgeFactory.get(), "D1", "G3");
graph.addEdge(edgeFactory.get(), "D1", "G4");
graph.addEdge(edgeFactory.get(), "D1", "G5");
graph.addEdge(edgeFactory.get(), "D1", "G6");
graph.addEdge(edgeFactory.get(), "D1", "G7");
// uncomment this to make it a Forest:
// graph.addVertex("K0");
// graph.addEdge(edgeFactory.get(), "K0", "K1");
// graph.addEdge(edgeFactory.get(), "K0", "K2");
// graph.addEdge(edgeFactory.get(), "K0", "K3");
//
// graph.addVertex("J0");
// graph.addEdge(edgeFactory.get(), "J0", "J1");
// graph.addEdge(edgeFactory.get(), "J0", "J2");
// graph.addEdge(edgeFactory.get(), "J1", "J4");
// graph.addEdge(edgeFactory.get(), "J2", "J3");
//// graph.addEdge(edgeFactory.get(), "J2", "J5");
//// graph.addEdge(edgeFactory.get(), "J4", "J6");
//// graph.addEdge(edgeFactory.get(), "J4", "J7");
//// graph.addEdge(edgeFactory.get(), "J3", "J8");
//// graph.addEdge(edgeFactory.get(), "J6", "B9");
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Container content = frame.getContentPane();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
content.add(new BalloonLayoutDemo());
frame.pack();
frame.setVisible(true);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy