drcl.inet.sensorsim.drl.demo.DRLDemo.java Source code

Java tutorial

Introduction

Here is the source code for drcl.inet.sensorsim.drl.demo.DRLDemo.java

Source

/*
 * 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 drcl.inet.sensorsim.drl.demo;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.functors.ChainedTransformer;

import drcl.inet.sensorsim.drl.EnergyStats.NodeStat;
import drcl.inet.sensorsim.drl.diffext.DRLDiffApp;

import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.algorithms.layout.StaticLayout;
import edu.uci.ics.jung.algorithms.layout.util.Relaxer;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.Layer;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.AbstractModalGraphMouse;
import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ScalingControl;
import edu.uci.ics.jung.visualization.decorators.AbstractVertexShapeTransformer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.GradientVertexRenderer;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import edu.uci.ics.jung.visualization.renderers.BasicVertexLabelRenderer.InsidePositioner;

/**
 * Shows a graph overlaid on a world map image.
 * Scaling of the graph also scales the image background.
 * @author Tom Nelson
 * 
 */
@SuppressWarnings("serial")
public class DRLDemo extends JApplet implements IDRLDemo {

    /**
     * the graph
     */
    Graph<Integer, Number> graph;

    /**
     * the visual component and renderer for the graph
     */
    VisualizationViewer<Integer, Number> vv;

    Map<Integer, double[]> map = new HashMap<Integer, double[]>();

    Map<Integer, String> nodeTypes = new HashMap<Integer, String>();

    NodeStat[] nodeStats = new NodeStat[20];

    private Layout<Integer, Number> layout;

    List<List<Long>> activeStreams = new ArrayList<List<Long>>();

    /**
     * create an instance of a simple graph with controls to
     * demo the zoom features.
     * 
     */
    public DRLDemo() {
        // create a frome to hold the graph
        final JFrame frame = new JFrame();
        Container content = frame.getContentPane();
        content.add(this);
        initDemo();
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private void initDemo() {
        setLayout(new BorderLayout());

        /*map.put("0",new double[]{550.0,350.0});
        map.put("1",new double[]{450.0,250.0});
        map.put("2",new double[]{450.0,450.0});
        map.put("3",new double[]{350.0,350.0});
        map.put("4",new double[]{360.0,340.0});
        map.put("5",new double[]{300.0,300.0});
        map.put("6",new double[]{250.0,450.0});
        map.put("7",new double[]{150.0,350.0});
        map.put("8",new double[]{270.0,325.0});
        map.put("9",new double[]{251.0,270.0});*/

        // create a simple graph for the demo
        graph = new DirectedSparseMultigraph<Integer, Number>();

        Dimension layoutSize = new Dimension(800, 800);

        layout = new StaticLayout<Integer, Number>(graph,
                new ChainedTransformer(new Transformer[] { new NodeTransformer(), new LatLonPixelTransformer() }));

        layout.setSize(layoutSize);
        vv = new VisualizationViewer<Integer, Number>(layout, new Dimension(400, 200));

        vv.getRenderer()
                .setVertexRenderer(new GradientVertexRenderer<Integer, Number>(Color.white, Color.red, false));
        vv.getRenderContext().setVertexShapeTransformer(new VertexShapeSizeAspect(graph));
        // add my listeners for ToolTips
        vv.setVertexToolTipTransformer(new Transformer<Integer, String>() {
            public String transform(Integer v) {
                return nodeTypes.get(v) + "-" + v + "[" + DRLDiffApp.doubleArrToString(map.get(v)) + "]"
                        + ",Energy=" + nodeStats[v].getCurrEnergy();
            }
        });
        vv.setEdgeToolTipTransformer(new Transformer<Number, String>() {
            public String transform(Number edge) {
                return "E" + graph.getEndpoints(edge).toString();
            }
        });

        vv.getRenderContext().setVertexLabelTransformer(new Transformer<Integer, String>() {
            public String transform(Integer v) {
                return nodeTypes.get(v) + "-" + v;
            }
        });
        vv.getRenderer().getVertexLabelRenderer().setPositioner(new InsidePositioner());
        vv.getRenderer().getVertexLabelRenderer().setPosition(Renderer.VertexLabel.Position.E);

        final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
        add(panel);
        final AbstractModalGraphMouse graphMouse = new DefaultModalGraphMouse();
        vv.setGraphMouse(graphMouse);

        vv.addKeyListener(graphMouse.getModeKeyListener());
        // vv.setToolTipText("<html><center>Type 'p' for Pick mode<p>Type 't' for Transform mode");

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

        JButton reset = new JButton("reset");
        reset.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).setToIdentity();
                vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW).setToIdentity();
            }
        });

        JPanel controls = new JPanel();
        controls.add(plus);
        controls.add(minus);
        controls.add(reset);
        add(controls, BorderLayout.SOUTH);
    }

    /**
     * create edges for this demo graph
     * @param v an array of Vertices to connect
     */
    void createEdges() {

        /*for(int i=0; i<map.keySet().size()*1.3; i++) {
           graph.addEdge(new Double(Math.random()), randomCity(), randomCity(), EdgeType.DIRECTED);
        }*/
    }

    double getEnergy(Integer nid) {
        NodeStat stat = (nodeStats.length >= nid) ? nodeStats[nid] : null;
        if (stat != null) {
            return stat.getCurrEnergy();
        }
        return 20;
    }

    class NodeTransformer implements Transformer<Integer, double[]> {

        public NodeTransformer() {
        }

        /**
         * transform airport code to latlon string
         */
        public double[] transform(Integer city) {
            return map.get(city);
        }
    }

    static class LatLonPixelTransformer implements Transformer<double[], Point2D> {

        public LatLonPixelTransformer() {
        }

        /**
         * transform a lat
         */
        public Point2D transform(double[] latlon) {
            double latitude = latlon[0];
            double longitude = latlon[1];
            return new Point2D.Double(longitude, latitude);
        }

    }

    private final class VertexShapeSizeAspect extends AbstractVertexShapeTransformer implements Transformer {
        protected Graph<Integer, Number> graph;
        //        protected AffineTransform scaleTransform = new AffineTransform();

        public VertexShapeSizeAspect(Graph<Integer, Number> graphIn) {
            this.graph = graphIn;
            setSizeTransformer(new Transformer() {

                public Integer transform(Object o) {
                    if (o instanceof Integer) {
                        return Math.min((int) getEnergy((Integer) o) / 2, 25);
                    } else
                        return 10;

                }
            });
            /* setAspectRatioTransformer(new Transformer<V,Float>() {
                
             public Float transform(V v) {
              if (stretch) {
                  return (float)(graph.inDegree(v) + 1) / 
                     (graph.outDegree(v) + 1);
              } else {
                  return 1.0f;
              }
             }});*/
        }

        public Shape transform(Object v) {
            Integer id = (Integer) v;
            String type = nodeTypes.get(id);
            if (type.equals(TYPE_SINK))
                return factory.getRegularStar(v, 6);
            else if (type.equals(TYPE_SENSOR))
                return factory.getEllipse(v);
            else if (type.equals(TYPE_TARGET))
                return factory.getRegularPolygon(v, 5);
            else
                return factory.getRoundRectangle(v);
        }
    }

    /**
     * a driver for this demo
     */
    public static void main(String[] args) {

    }

    public void addNode(int id, double[] latlong, double energy, String type) {
        layout.lock(id, true);
        //add a vertex
        /* Relaxer relaxer = vv.getModel().getRelaxer();
         relaxer.pause();*/
        map.put(id, latlong);
        graph.addVertex(id);
        NodeStat stat = new NodeStat(id, 0);
        stat.setCurrEnergy(energy);
        nodeStats[id] = stat;
        nodeTypes.put(id, type);
        System.err.println("added node " + id);

        layout.initialize();
        //relaxer.resume();
        layout.lock(id, false);

    }

    public void updateNodePosition(Integer nid, double[] loc) {
        double[] currLoc = map.get(nid);
        double dist = Math
                .sqrt(Math.pow(Math.abs(loc[0] - currLoc[0]), 2) + Math.pow(Math.abs(loc[1] - currLoc[1]), 2));
        if (dist < 5)
            return;
        map.put(nid, loc);
        layout.lock(nid, true);
        layout.setLocation(nid, new Point2D.Double(loc[1], loc[0]));
        /*graph.removeVertex(nid);
        */
        layout.initialize();
        layout.lock(nid, false);
        vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).setToIdentity();
        vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW).setToIdentity();

        /*layout.lock(0, true);
        graph.addVertex(nid);
        layout.initialize();
        layout.lock(0, false);
        vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).setToIdentity();
        vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW).setToIdentity();*/
    }

    public void markActiveStream(List<List<Long>> streams) {
        boolean diffFound = (streams.size() != activeStreams.size());
        if (!diffFound) {
            for (List<Long> stream : streams) {
                if (!activeStreams.contains(stream)) {
                    diffFound = true;
                    break;
                }
            }
        }
        if (!diffFound) {
            for (List<Long> stream : activeStreams) {
                if (!streams.contains(stream)) {
                    diffFound = true;
                    break;
                }
            }
        }

        if (!diffFound)
            return;
        activeStreams.clear();
        Number[] edges = graph.getEdges().toArray(new Number[0]);
        layout.lock(0, true);
        for (Number e : edges) {
            graph.removeEdge(e);
        }
        for (List<Long> s : streams) {
            activeStreams.add(s);
            for (int i = 0; i < s.size() - 1; i++) {
                Double id = new Double(s.get(i).toString() + s.get(i + 1).toString());
                if (!graph.containsEdge(id))
                    graph.addEdge(id, Integer.parseInt(s.get(i).toString()),
                            Integer.parseInt(s.get(i + 1).toString()));
            }
        }
        layout.initialize();
        layout.lock(0, false);
        vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).setToIdentity();
        vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW).setToIdentity();
    }

    public void markCurrentEdge(int fromNode, int toNode) {
        // TODO Auto-generated method stub

    }

    public void updateNodes(NodeStat[] stats) {
        this.nodeStats = stats;
    }
}