package org.codehaus.mojo.graphing.pomo;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import javax.swing.BorderFactory;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import edu.uci.ics.jung.graph.ArchetypeVertex;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.decorators.DefaultToolTipFunction;
import edu.uci.ics.jung.graph.decorators.EdgeShape;
import edu.uci.ics.jung.graph.decorators.PickableEdgePaintFunction;
import edu.uci.ics.jung.utils.TestGraphs;
import edu.uci.ics.jung.visualization.DefaultVisualizationModel;
import edu.uci.ics.jung.visualization.FRLayout;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.MultiPickedState;
import edu.uci.ics.jung.visualization.PickedState;
import edu.uci.ics.jung.visualization.PluggableRenderer;
import edu.uci.ics.jung.visualization.ShapePickSupport;
import edu.uci.ics.jung.visualization.VisualizationModel;
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.ScalingControl;
import edu.uci.ics.jung.visualization.subLayout.CircularSubLayout;
import edu.uci.ics.jung.visualization.subLayout.SubLayout;
import edu.uci.ics.jung.visualization.subLayout.SubLayoutDecorator;
/**
* Demonstrates the Cluster, CircularCluster, and ClusteringLayout
* classes. In this demo, vertices are visually clustered as they
* are selected. The cluster is formed in a circle centered at the
* location of the first vertex selected.
*
* @author Tom Nelson - RABA Technologies
*/
public class SubLayoutDemo extends JApplet
{
String instructions =
"<html>Use the mouse to select multiple vertices" +
"<p>either by dragging a region, or by shift-clicking" +
"<p>on multiple vertices." +
"<p>As you select vertices, they become part of a" +
"<p>cluster, centered at the location of the first" +
"<p>selected vertex." +
"<p>You can drag the cluster with the mouse." +
"<p>Use the 'Picking'/'Transforming' combo-box to switch" +
"<p>between picking and transforming mode.</html>";
/**
* the graph
*/
Graph graph;
/**
* the visual component and renderer for the graph
*/
VisualizationViewer vv;
SubLayoutDecorator clusteringLayout;
PickedState ps;
/**
* create an instance of a simple graph with controls to
* demo the zoomand hyperbolic features.
*/
public SubLayoutDemo()
{
// create a simple graph for the demo
graph = TestGraphs.getOneComponentGraph();
PluggableRenderer pr = new PluggableRenderer();
// ClusteringLayout is a decorator class that delegates
// to another layout, but can also sepately manage the
// layout of sub-sets of vertices in circular clusters.
clusteringLayout = new SubLayoutDecorator( new FRLayout( graph ) );
Dimension preferredSize = new Dimension( 400, 400 );
final VisualizationModel visualizationModel =
new DefaultVisualizationModel( clusteringLayout, preferredSize );
vv = new VisualizationViewer( visualizationModel, pr, preferredSize );
vv.setPickSupport( new ShapePickSupport() );
pr.setEdgeShapeFunction( new EdgeShape.QuadCurve() );
vv.setPickedState( new ClusterListener( clusteringLayout ) );
ps = vv.getPickedState();
pr.setEdgePaintFunction( new PickableEdgePaintFunction( ps, Color.black, Color.red ) );
vv.setBackground( Color.white );
// add a listener for ToolTips
vv.setToolTipFunction( new DefaultToolTipFunction() );
/**
* the regular graph mouse for the normal view
*/
final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();
vv.setGraphMouse( graphMouse );
Container content = getContentPane();
GraphZoomScrollPane gzsp = new GraphZoomScrollPane( vv );
content.add( gzsp );
JComboBox modeBox = graphMouse.getModeComboBox();
modeBox.addItemListener( graphMouse.getModeListener() );
graphMouse.setMode( ModalGraphMouse.Mode.PICKING );
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, 0.9f, vv.getCenter() );
}
} );
JButton help = new JButton( "Help" );
help.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
JOptionPane.showMessageDialog( (JComponent) e.getSource(), instructions, "Help", JOptionPane.PLAIN_MESSAGE );
}
} );
JPanel controls = new JPanel();
JPanel zoomControls = new JPanel( new GridLayout( 2, 1 ) );
zoomControls.setBorder( BorderFactory.createTitledBorder( "Zoom" ) );
zoomControls.add( plus );
zoomControls.add( minus );
controls.add( zoomControls );
controls.add( modeBox );
controls.add( help );
content.add( controls, BorderLayout.SOUTH );
}
class ClusterListener extends MultiPickedState
{
SubLayoutDecorator layout;
Point2D center;
/* (non-Javadoc)
* @see edu.uci.ics.jung.visualization.MultiPickedState#pick(edu.uci.ics.jung.graph.ArchetypeVertex, boolean)
*/
public boolean pick( ArchetypeVertex v, boolean picked )
{
boolean result = super.pick( v, picked );
if ( picked )
{
vertexPicked( v );
}
else
{
vertexUnpicked( v );
}
return result;
}
public ClusterListener( SubLayoutDecorator layout )
{
this.layout = layout;
}
public void vertexPicked( ArchetypeVertex v )
{
if ( center == null )
{
center = layout.getLocation( v );
}
layout.removeAllSubLayouts();
SubLayout subLayout = new CircularSubLayout( getPickedVertices(), 20, center );
layout.addSubLayout( subLayout );
}
public void vertexUnpicked( ArchetypeVertex v )
{
layout.removeAllSubLayouts();
if ( getPickedVertices().isEmpty() == false )
{
SubLayout subLayout = new CircularSubLayout( getPickedVertices(), 20, center );
layout.addSubLayout( subLayout );
}
else
{
center = null;
}
}
}
/**
* 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 SubLayoutDemo() );
f.pack();
f.show();
}
}