satalitelist.EdgeLabelDemo.java Source code

Java tutorial

Introduction

Here is the source code for satalitelist.EdgeLabelDemo.java

Source

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);
    //    }
}