Java tutorial
package satalitelist; /* * 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. * */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; 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 javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.BoundedRangeModel; import javax.swing.Box; import javax.swing.ButtonGroup; import javax.swing.DefaultBoundedRangeModel; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.apache.commons.collections15.Transformer; import edu.uci.ics.jung.algorithms.layout.FRLayout2; import edu.uci.ics.jung.algorithms.layout.Layout; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.graph.SparseMultigraph; import edu.uci.ics.jung.graph.util.EdgeType; import edu.uci.ics.jung.visualization.GraphZoomScrollPane; 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.decorators.ConstantDirectionalEdgeValueTransformer; 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.renderers.EdgeLabelRenderer; import edu.uci.ics.jung.visualization.renderers.Renderer; import edu.uci.ics.jung.visualization.renderers.VertexLabelRenderer; import graph.INode; import graph.Node; import java.awt.BasicStroke; import java.awt.Stroke; import java.util.ArrayList; import java.util.HashMap; import javax.swing.JLabel; import moves.Move; import moves.MoveType; /** * Demonstrates jung support for drawing edge labels that * can be positioned at any point along the edge, and can * be rotated to be parallel with the edge. * * @author Tom Nelson * */ public class EdgeLabelDemo extends JApplet { ArrayList<Move> ml = new ArrayList<Move>(); { //6 4 // ml.add(new Move(0, 4, 0, 2, MoveType.M01_BREAK_CYCLE)); // ml.add(new Move(2, 6, 4, 6, MoveType.M31_CONNECT_TIP_WITH_YCLE_REMOVE_ROOT_CYCLE_NEXT_ADJACENT_EDGE)); // // 3 // ml.add(new Move(-1, 4, MoveType.CONNECT_TIP_WITH_STEM_REMOVE_EDGE_BEFORE_CONNECTED_NODE)); } ArrayList<INode> cities = new ArrayList<INode>();; StemAndCycleList list; /** * */ private static final long serialVersionUID = -6077157664507049647L; /** * the graph */ String stemTitle = "Stem: "; String cycleTitle = "CycleRoot: "; String otherEndTitle = "Other stem end: "; JLabel stemLabel = new JLabel(stemTitle); JLabel cycleLabel = new JLabel(cycleTitle); JLabel otherEndLabel = new JLabel(otherEndTitle); /** * the visual component and renderer for the graph */ Graph<Integer, MyEdge> graph; VisualizationViewer<Integer, MyEdge> vv; VertexLabelRenderer vertexLabelRenderer; EdgeLabelRenderer edgeLabelRenderer; ScalingControl scaler = new CrossoverScalingControl(); public enum EdgeKind { NORMAL, VIRTUAL, INVISIBLE }; public class MyEdge { int price; private EdgeKind kind = EdgeKind.NORMAL; public MyEdge(int price) { this(price, EdgeKind.NORMAL); } public MyEdge(int price, EdgeKind kind) { this.price = price; this.kind = kind; } @Override public String toString() { return String.valueOf(price); } } /** * create an instance of a simple graph with controls to * demo the label positioning features * */ @SuppressWarnings("serial") public EdgeLabelDemo(StemAndCycleList al) { cities = (ArrayList<INode>) al.list; list = al; al.score = al.getCycleScore(); // create a simple graph for the demo graph = new SparseMultigraph<Integer, MyEdge>(); //Integer[] v = createVertices(7); fillSevenCitiesWithPrices(); for (INode n : cities) { graph.addVertex(Integer.parseInt(n.toString())); } createVertices(); //createEdges(v); Layout<Integer, MyEdge> layout = new FRLayout2<Integer, MyEdge>(graph); vv = new VisualizationViewer<Integer, MyEdge>(layout, new Dimension(1000, 800)); vv.setBackground(Color.white); vertexLabelRenderer = vv.getRenderContext().getVertexLabelRenderer(); edgeLabelRenderer = vv.getRenderContext().getEdgeLabelRenderer(); vv.getRenderContext().setEdgeLabelTransformer(new Transformer<MyEdge, String>() { public String transform(MyEdge i) { return i.toString(); } }); vv.getRenderContext().setEdgeDrawPaintTransformer( new PickableEdgePaintTransformer<MyEdge>(vv.getPickedEdgeState(), Color.black, Color.cyan)); vv.getRenderContext().setVertexFillPaintTransformer( new PickableVertexPaintTransformer<Integer>(vv.getPickedVertexState(), Color.red, Color.yellow)); // add my listener for ToolTips vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<Integer>()); vv.getRenderContext().setEdgeStrokeTransformer(new Transformer<MyEdge, Stroke>() { public Stroke transform(MyEdge i) { switch (i.kind) { case NORMAL: return new BasicStroke(2, 1, 1, 0, new float[] { 10, 0 }, 0); case VIRTUAL: return new BasicStroke(2, 1, 1, 0, new float[] { 5 }, 0); case INVISIBLE: return new BasicStroke(1, 1, 1, 0, new float[] { 1, 10 }, 0); } throw new RuntimeException("No such a type"); } }); vv.getRenderer().getVertexLabelRenderer().setPosition(Renderer.VertexLabel.Position.CNTR); // create a frome to hold the graph final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv); Container content = getContentPane(); content.add(panel); final DefaultModalGraphMouse<Integer, Number> graphMouse = new DefaultModalGraphMouse<Integer, Number>(); vv.setGraphMouse(graphMouse); 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()); } }); ButtonGroup radio = new ButtonGroup(); JRadioButton lineButton = new JRadioButton("Line"); lineButton.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<Integer, MyEdge>()); vv.repaint(); } } }); JRadioButton quadButton = new JRadioButton("QuadCurve"); quadButton.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.QuadCurve<Integer, MyEdge>()); vv.repaint(); } } }); JRadioButton cubicButton = new JRadioButton("CubicCurve"); cubicButton.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.CubicCurve<Integer, MyEdge>()); vv.repaint(); } } }); radio.add(quadButton); radio.add(cubicButton); radio.add(lineButton); graphMouse.setMode(ModalGraphMouse.Mode.TRANSFORMING); Box controls = Box.createHorizontalBox(); JPanel zoomPanel = new JPanel(new GridLayout(0, 1)); zoomPanel.setBorder(BorderFactory.createTitledBorder("Scale")); zoomPanel.add(plus); zoomPanel.add(minus); JPanel edgePanel = new JPanel(new GridLayout(0, 1)); edgePanel.setBorder(BorderFactory.createTitledBorder("EdgeType Type")); edgePanel.add(lineButton); edgePanel.add(quadButton); edgePanel.add(cubicButton); JPanel rotatePanel = new JPanel(); rotatePanel.setBorder(BorderFactory.createTitledBorder("Alignment")); rotatePanel.add(cycleLabel); rotatePanel.add(stemLabel); rotatePanel.add(otherEndLabel); JPanel labelPanel = new JPanel(new BorderLayout()); labelPanel.add(rotatePanel, BorderLayout.WEST); JPanel modePanel = new JPanel(new GridLayout(2, 1)); modePanel.setBorder(BorderFactory.createTitledBorder("Mouse Mode")); modePanel.add(graphMouse.getModeComboBox()); JPanel movePanel = new JPanel(new GridLayout(2, 1)); modePanel.setBorder(BorderFactory.createTitledBorder("Make move")); JButton button = new JButton("Make move"); button.addActionListener(new StemAndCycleAl()); modePanel.add(button); controls.add(zoomPanel); controls.add(edgePanel); controls.add(labelPanel); controls.add(modePanel); controls.add(movePanel); content.add(controls, BorderLayout.SOUTH); lineButton.setSelected(true); } int move = 0; public class StemAndCycleAl implements ActionListener { public void actionPerformed(ActionEvent e) { ArrayList<MyEdge> i = new ArrayList<MyEdge>(); for (MyEdge i2 : graph.getEdges()) { i.add(i2); } for (MyEdge a : i) { graph.removeEdge(a); } //list.apply(ml.get(move)); list.makeMove(); //move++; createVertices(); vv.repaint(); } } /** * subclassed to hold two BoundedRangeModel instances that * are used by JSliders to move the edge label positions * @author Tom Nelson * * */ class MutableDirectionalEdgeValue extends ConstantDirectionalEdgeValueTransformer<Integer, Number> { BoundedRangeModel undirectedModel = new DefaultBoundedRangeModel(5, 0, 0, 10); BoundedRangeModel directedModel = new DefaultBoundedRangeModel(7, 0, 0, 10); public MutableDirectionalEdgeValue(double undirected, double directed) { super(undirected, directed); undirectedModel.setValue((int) (undirected * 10)); directedModel.setValue((int) (directed * 10)); undirectedModel.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { setUndirectedValue(new Double(undirectedModel.getValue() / 10f)); vv.repaint(); } }); directedModel.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { setDirectedValue(new Double(directedModel.getValue() / 10f)); vv.repaint(); } }); } /** * @return Returns the directedModel. */ public BoundedRangeModel getDirectedModel() { return directedModel; } /** * @return Returns the undirectedModel. */ public BoundedRangeModel getUndirectedModel() { return undirectedModel; } } /** * create some vertices * @param count how many to create * @return the Vertices in an array */ // private void createVertices(int count) { private void createVertices() { if (list.tip == StemAndCycleList.NULL_INDEX) { int i = StemAndCycleList.FIRST_INDEX; do { INode v1 = list.get(i); INode v2 = list.get(list.next(i)); Integer v1p = Integer.parseInt(v1.toString()); Integer v2p = Integer.parseInt(v2.toString()); int price = list.getPrice(i); graph.addEdge(new MyEdge(price), v1p, v2p, EdgeType.DIRECTED); i = list.next(i); } while (i != StemAndCycleList.FIRST_INDEX); } else { for (int i = 0; i < list.satalites.length; i++) { INode v1 = list.get(i); INode v2 = list.get(list.next(i)); Integer v1p = Integer.parseInt(v1.toString()); Integer v2p = Integer.parseInt(v2.toString()); int price = list.getPrice(i); graph.addEdge(new MyEdge(price), v1p, v2p, EdgeType.DIRECTED); } } stemLabel.setText(stemTitle + (list.tip + 1)); otherEndLabel.setText(otherEndTitle + (list.otherStemEnd + 1)); cycleLabel.setText(cycleTitle + (list.root + 1)); } /** * create edges for this demo graph * @param v an array of Vertices to connect */ void createEdges(Integer[] v) { // graph.addEdge(new MyEdge(Math.random()), v[0], v[1]); // graph.addEdge(new MyEdge(Math.random()), v[1], v[2]); } private void fillSevenCitiesWithPrices() { Node one = new Node("1"); Node two = new Node("2"); Node three = new Node("3"); Node four = new Node("4"); Node five = new Node("5"); Node six = new Node("6"); Node seven = new Node("7"); int ONE_TWO = 3; int ONE_THREE = 4; int ONE_FOUR = 3; int ONE_FIVE = 2; int ONE_SIX = 1; int ONE_SEVEN = 3; int TWO_THREE = 1; int TWO_FOUR = 1; int TWO_FIVE = 1; int TWO_SIX = 3; int TWO_SEVEN = 1; int THREE_FOUR = 5; int THREE_FIVE = 3; int THREE_SIX = 4; int THREE_SEVEN = 5; int FOUR_FIVE = 4; int FOUR_SIX = 2; int FOUR_SEVEN = 4; int FIVE_SIX = 2; int FIVE_SEVEN = 3; int SIX_SEVEN = 4; HashMap<INode, Integer> prices; prices = new HashMap<INode, Integer>(6); prices.put(two, ONE_TWO); prices.put(three, ONE_THREE); prices.put(four, ONE_FOUR); prices.put(five, ONE_FIVE); prices.put(six, ONE_SIX); prices.put(seven, ONE_SEVEN); one.setPrices(prices); prices = new HashMap<INode, Integer>(6); prices.put(one, ONE_TWO); prices.put(three, TWO_THREE); prices.put(four, TWO_FOUR); prices.put(five, TWO_FIVE); prices.put(six, TWO_SIX); prices.put(seven, TWO_SEVEN); two.setPrices(prices); prices = new HashMap<INode, Integer>(6); prices.put(one, ONE_THREE); prices.put(two, TWO_THREE); prices.put(four, THREE_FOUR); prices.put(five, THREE_FIVE); prices.put(six, THREE_SIX); prices.put(seven, THREE_SEVEN); three.setPrices(prices); prices = new HashMap<INode, Integer>(6); prices.put(one, ONE_FOUR); prices.put(two, TWO_FOUR); prices.put(three, THREE_FOUR); prices.put(five, FOUR_FIVE); prices.put(six, FOUR_SIX); prices.put(seven, FOUR_SEVEN); four.setPrices(prices); prices = new HashMap<INode, Integer>(6); prices.put(one, ONE_FIVE); prices.put(two, TWO_FIVE); prices.put(three, THREE_FIVE); prices.put(four, FOUR_FIVE); prices.put(six, FIVE_SIX); prices.put(seven, FIVE_SEVEN); five.setPrices(prices); prices = new HashMap<INode, Integer>(6); prices.put(one, ONE_SIX); prices.put(two, TWO_SIX); prices.put(three, THREE_SIX); prices.put(four, FOUR_SIX); prices.put(five, FIVE_SIX); prices.put(seven, SIX_SEVEN); six.setPrices(prices); prices = new HashMap<INode, Integer>(6); prices.put(one, ONE_SEVEN); prices.put(two, TWO_SEVEN); prices.put(three, THREE_SEVEN); prices.put(four, FOUR_SEVEN); prices.put(five, FIVE_SEVEN); prices.put(six, SIX_SEVEN); seven.setPrices(prices); cities.add(one); cities.add(two); cities.add(three); cities.add(four); cities.add(five); cities.add(six); cities.add(seven); list = new StemAndCycleList(cities); } /** * a driver for this demo */ // public static void main(String[] args) { // JFrame frame = new JFrame(); // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Container content = frame.getContentPane(); // content.add(new EdgeLabelDemo()); // frame.pack(); // frame.setLocationRelativeTo(null); // frame.setVisible(true); // } }