/* * JFLAP - Formal Languages and Automata Package * * * Susan H. Rodger * Computer Science Department * Duke University * August 27, 2009 * Copyright (c) 2002-2009 * All rights reserved. * JFLAP is open source software. Please see the LICENSE for terms. * */ package automata.graph; import java.awt.Dimension; import java.util.Random; import automata.Automaton; import automata.graph.layout.*; /** * This class allows the user to fetch a new LayoutAlgorithm, either a random one or a * specific one. It also allows the user to fetch a particular AutomatonGraph that * corresponds to a given LayoutAlgorithm. * * @author Chris Morgan */ public class LayoutAlgorithmFactory { /** * Value that represents the number of LayoutAlgorithms of which this factory currently has * knowledge. Used to generate a random LayoutAlgorithm, so if changed, one should make * sure all integers from 0 to NUM_ALGORITHMS-1 are numerical identifiers for * LayoutAlgorithms. */ private static final int NUM_ALGORITHMS = 7; /** * Numerical identifier for choosing a random LayoutAlgorithm instance. */ public static final int RANDOM_CHOICE = -1; /** * Numerical identifier for a CircleLayoutAlgorithm instance. */ public static final int CIRCLE = 0; /** * Numerical identifier for a GEMLayoutAlgorithm instance. */ public static final int GEM = 1; /** * Numerical identifier for a RandomLayoutAlgorithm instance. */ public static final int RANDOM = 2; /** * Numerical identifier for a SpiralLayoutAlgorithm instance. */ public static final int SPIRAL = 3; /** * Numerical identifier for a TreeLayoutAlgorithm instance with a hierarchical tree. */ public static final int TREE_HIERARCHY = 4; /** * Numerical identifier for a TreeLayoutAlgorithm instance with a degree tree. */ public static final int TREE_DEGREE = 5; /** * Numerical identifier for a TwoCircleLayoutAlgorithm instance. */ public static final int TWO_CIRCLE = 6; /** * Returns a random LayoutAlgorithm among those defined. Should not be mistaken for an * algorithm always creating a RandomLayoutAlgorithm instance. * * @return A random LayoutAlgorithm among those defined. */ public static LayoutAlgorithm getRandomLayoutAlgorithm() { Random random = new Random(); return getLayoutAlgorithm(Math.abs(random.nextInt() % NUM_ALGORITHMS)); } /** * Returns a random LayoutAlgorithm among those defined. Should not be mistaken for an * algorithm always creating a RandomLayoutAlgorithm instance. * * @param pSize value for size. * @param vDim value for vertexDim. * @param vBuffer value for vertexBuffer. * @return A random LayoutAlgorithm among those defined. */ public static LayoutAlgorithm getRandomLayoutAlgorithm(Dimension pSize, Dimension vDim, double vBuffer) { Random random = new Random(); return getLayoutAlgorithm(Math.abs(random.nextInt() % NUM_ALGORITHMS), pSize, vDim, vBuffer); } /** * Returns a LayoutAlgorithm corresponding to the numerical identifier given. * * @param algorithm a numerical identifier for the specific layout algorithm that should be generated. * @return A layout algorithm corresponding to the algorithm value. */ public static LayoutAlgorithm getLayoutAlgorithm(int algorithm) { switch (algorithm) { case RANDOM_CHOICE: return getRandomLayoutAlgorithm(); case CIRCLE: return new CircleLayoutAlgorithm(); case GEM: return new GEMLayoutAlgorithm(); case RANDOM: return new RandomLayoutAlgorithm(); case SPIRAL: return new SpiralLayoutAlgorithm(); case TREE_DEGREE: return new TreeLayoutAlgorithm(false); case TREE_HIERARCHY: return new TreeLayoutAlgorithm(true); case TWO_CIRCLE: return new TwoCircleLayoutAlgorithm(); case VertexMover.NEGATIVE_SLOPE_DIAGONAL: return new VertexMover(VertexMover.NEGATIVE_SLOPE_DIAGONAL); case VertexMover.POSITIVE_SLOPE_DIAGONAL: return new VertexMover(VertexMover.POSITIVE_SLOPE_DIAGONAL); case VertexMover.ROTATE: return new VertexMover(VertexMover.ROTATE); case VertexMover.HORIZONTAL_CENTER: return new VertexMover(VertexMover.HORIZONTAL_CENTER); case VertexMover.VERTICAL_CENTER: return new VertexMover(VertexMover.VERTICAL_CENTER); case VertexMover.FILL: return new VertexMover(VertexMover.FILL); } return null; } /** * Returns a LayoutAlgorithm corresponding to the numerical identifier given. * * @param algorithm a numerical identifier for the specific layout algorithm that should be generated. * @param pSize value for size. * @param vDim value for vertexDim. * @param vBuffer value for vertexBuffer. * @return A layout algorithm corresponding to the algorithm value. */ public static LayoutAlgorithm getLayoutAlgorithm(int algorithm, Dimension pSize, Dimension vDim, double vBuffer) { switch (algorithm) { case RANDOM_CHOICE: return getRandomLayoutAlgorithm(pSize, vDim, vBuffer); case CIRCLE: return new CircleLayoutAlgorithm(pSize, vDim, vBuffer); case GEM: return new GEMLayoutAlgorithm(pSize, vDim, vBuffer); case RANDOM: return new RandomLayoutAlgorithm(pSize, vDim, vBuffer); case SPIRAL: return new SpiralLayoutAlgorithm(pSize, vDim, vBuffer); case TREE_DEGREE: return new TreeLayoutAlgorithm(pSize, vDim, vBuffer, false); case TREE_HIERARCHY: return new TreeLayoutAlgorithm(pSize, vDim, vBuffer, true); case TWO_CIRCLE: return new TwoCircleLayoutAlgorithm(pSize, vDim, vBuffer); case VertexMover.NEGATIVE_SLOPE_DIAGONAL: return new VertexMover(pSize, vDim, vBuffer, VertexMover.NEGATIVE_SLOPE_DIAGONAL); case VertexMover.POSITIVE_SLOPE_DIAGONAL: return new VertexMover(pSize, vDim, vBuffer, VertexMover.POSITIVE_SLOPE_DIAGONAL); case VertexMover.ROTATE: return new VertexMover(pSize, vDim, vBuffer, VertexMover.ROTATE); case VertexMover.HORIZONTAL_CENTER: return new VertexMover(pSize, vDim, vBuffer, VertexMover.HORIZONTAL_CENTER); case VertexMover.VERTICAL_CENTER: return new VertexMover(pSize, vDim, vBuffer, VertexMover.VERTICAL_CENTER); case VertexMover.FILL: return new VertexMover(pSize, vDim, vBuffer, VertexMover.FILL); } return null; } /** * Returns the correct AutomatonGraph that corresponds with this layout algorithm. * * @param algorithm a numerical identifier for the specific layout algorithm which will use * the graph. * @param automaton the automaton that will be used to generate the graph. * @return the correct AutomatonGraph. */ public static AutomatonGraph getAutomatonGraph(int algorithm, Automaton automaton) { if (algorithm == TREE_HIERARCHY) return new AutomatonDirectedGraph(automaton); else return new AutomatonGraph(automaton); } }