cz.cuni.mff.ksi.jinfer.autoeditor.BububuEditor.java Source code

Java tutorial

Introduction

Here is the source code for cz.cuni.mff.ksi.jinfer.autoeditor.BububuEditor.java

Source

/*
 *  Copyright (C) 2010 anti
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package cz.cuni.mff.ksi.jinfer.autoeditor;

import cz.cuni.mff.ksi.jinfer.autoeditor.gui.AutoEditorTopComponent;
import cz.cuni.mff.ksi.jinfer.base.automaton.Automaton;
import cz.cuni.mff.ksi.jinfer.base.automaton.State;
import cz.cuni.mff.ksi.jinfer.base.automaton.Step;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.algorithms.layout.StaticLayout;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.PluggableGraphMouse;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.TransformerUtils;
import org.apache.log4j.Logger;
import org.openide.util.Exceptions;
import org.openide.windows.WindowManager;

/**
 * TODO anti Comment!
 *
 * @param <T>
 * @author anti
 */
public class BububuEditor<T> extends AutoEditor<T> {
    private static final Logger LOG = Logger.getLogger(BububuEditor.class);
    private SymbolToString<T> symbolToString;

    public BububuEditor(SymbolToString<T> symbolToString) {
        this.symbolToString = symbolToString;
    }

    public BububuEditor() {
    }

    /**
     * Variable used to pass data to the GUI and gets the result of user
     * interaction.
     */
    private VisualizationViewer<State<T>, Step<T>> visualizationViewer;

    /**
     * Draws automaton and waits until user picks two states and clicks
     * 'continue' button.
     *
     * @param automaton automaton to be drawn
     * @return if user picks exactly two states returns Pair of them otherwise null
     */
    @Override
    public List<State<T>> drawAutomatonToPickStates(final Automaton<T> automaton) {

        final DirectedSparseMultigraph<State<T>, Step<T>> graph = new DirectedSparseMultigraph<State<T>, Step<T>>();
        final Map<State<T>, Set<Step<T>>> automatonDelta = automaton.getDelta();

        // Get vertices = states of automaton
        for (Entry<State<T>, Set<Step<T>>> entry : automatonDelta.entrySet()) {
            graph.addVertex(entry.getKey());
        }

        // Get edges of automaton
        for (Entry<State<T>, Set<Step<T>>> entry : automatonDelta.entrySet()) {
            for (Step<T> step : entry.getValue()) {
                graph.addEdge(step, step.getSource(), step.getDestination());
            }
        }

        Map<State<T>, Point2D> positions = new HashMap<State<T>, Point2D>();

        ProcessBuilder p = new ProcessBuilder(Arrays.asList("/usr/bin/dot", "-Tplain"));
        try {
            Process k = p.start();
            k.getOutputStream().write((new AutomatonToDot<T>()).convertToDot(automaton, symbolToString).getBytes());
            k.getOutputStream().flush();
            BufferedReader b = new BufferedReader(new InputStreamReader(k.getInputStream()));
            k.getOutputStream().close();

            Scanner s = new Scanner(b);
            s.next();
            s.next();
            double width = s.nextDouble();
            double height = s.nextDouble();
            double windowW = 500;
            double windowH = 300;

            while (s.hasNext()) {
                if (s.next().equals("node")) {
                    int nodeName = s.nextInt();
                    double x = s.nextDouble();
                    double y = s.nextDouble();
                    for (State<T> state : automatonDelta.keySet()) {
                        if (state.getName() == nodeName) {
                            positions.put(state,
                                    new Point((int) (windowW * x / width), (int) (windowH * y / height)));
                            break;
                        }
                    }
                }
            }
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
        Transformer<State<T>, Point2D> trans = TransformerUtils.mapTransformer(positions);

        // TODO rio find suitable layout
        final Layout<State<T>, Step<T>> layout = new StaticLayout<State<T>, Step<T>>(graph, trans);

        //layout.setSize(new Dimension(300,300)); // sets the initial size of the space

        visualizationViewer = new VisualizationViewer<State<T>, Step<T>>(layout);
        //visualizationViewer.setPreferredSize(new Dimension(350,350)); //Sets the viewing area size

        visualizationViewer.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<State<T>>());
        visualizationViewer.getRenderContext().setEdgeLabelTransformer(new Transformer<Step<T>, String>() {
            @Override
            public String transform(Step<T> i) {
                return BububuEditor.this.symbolToString.toString(i.getAcceptSymbol());
            }
        });

        final PluggableGraphMouse gm = new PluggableGraphMouse();
        gm.add(new PickingUnlimitedGraphMousePlugin<State<T>, Step<T>>());
        visualizationViewer.setGraphMouse(gm);

        // Call GUI in a special thread. Required by NB.
        synchronized (this) {
            WindowManager.getDefault().invokeWhenUIReady(new Runnable() {

                @Override
                public void run() {
                    // Pass this as argument so the thread will be able to wake us up.
                    AutoEditorTopComponent.findInstance().drawAutomatonBasicVisualizationServer(BububuEditor.this,
                            visualizationViewer, "Please select two states to be merged together.");
                }
            });

            try {
                // Sleep on this.
                this.wait();
            } catch (InterruptedException e) {
                return null;
            }
        }

        /* AutoEditorTopComponent wakes us up. Get the result and return it.
         * VisualizationViewer should give us the information about picked vertices.
         */
        final Set<State<T>> pickedSet = visualizationViewer.getPickedVertexState().getPicked();
        List<State<T>> lst = new ArrayList<State<T>>(pickedSet);
        return lst;
    }
}