package jsetool.gui; import java.awt.Dimension; import java.util.ArrayList; import java.util.Iterator; import jsetool.data.ExplorationState; /** * @author Mike Lawson * * @since Oct 24, 2004 * * The ExplorationStateDrawingPane class is a pane on which the results of the * state exploration computation will be displayed. * * */ public class ExplorationStateDrawingPane extends DrawingPane { protected static final double VERTICAL_STANDOFF = 25; protected static final double HORIZONTAL_STANDOFF = 55; protected static final double HORIZONTAL_INSET = 10; protected ExplorationStateLeveler leveler; protected double levelHeight; protected ArrayList splits; public ExplorationStateDrawingPane() { // required for serialization } /** * Constructs a new LeveledDrawingPane from the given ExplorationStateLeveler * * @param leveler */ public ExplorationStateDrawingPane(ExplorationStateLeveler leveler) { super(); this.leveler = leveler; configureDisplay(); setPreferredSize(new Dimension((int) displayWidth, (int) displayHeight)); } /** * Configures the display according to the information found in the leveler. */ protected void configureDisplay() { displayWidth = determineDisplayWidth(); displayHeight = determineDisplayHeight(); levelHeight = determineLevelHeight(); splits = determineSplits(); createGraphicComponents(); } /** * Calculates the "splits" for each level. A split is the center point at * which each Global State will be drawn. * * @return ArrayList */ private ArrayList determineSplits() { ArrayList levels = leveler.getLevels(); ArrayList splits = new ArrayList(); for (Iterator levelIterator = levels.iterator(); levelIterator.hasNext();) { ArrayList level = (ArrayList) levelIterator.next(); double[] splitsForLevel = new double[level.size()]; for (int i = 0; i < splitsForLevel.length; i++) { splitsForLevel[i] = (displayWidth / (level.size() + 1.0)) * (i + 1); } splits.add(splitsForLevel); } return splits; } /** * Determines the height of each level in the display. * * @return double */ private double determineLevelHeight() { return GlobalState.DEFAULT_HEIGHT + 2 * VERTICAL_STANDOFF; } /** * Determines the height of the entire display * * @return double */ private double determineDisplayHeight() { return (leveler.getLevels().size() + 1) * determineLevelHeight(); } /** * Determines the width of the entire display * * @return double */ private double determineDisplayWidth() { return leveler.getMaxStatesPerLevel() * (GlobalState.DEFAULT_WIDTH + HORIZONTAL_STANDOFF) + 2 * HORIZONTAL_INSET; } /** * Creates the graphics components from the information found in the leveler. * */ private void createGraphicComponents() { ArrayList levels = leveler.getLevels(); createLevels(levels); createConnectivityEdges(levels); } /** * Puts GlobalStates into each level. * * @param levels */ private void createLevels(ArrayList levels) { // Place global state objects in the drawings levels. for (int i = 0; i < levels.size(); i++) { createLevel(i, (ArrayList) levels.get(i), (double[]) splits.get(i)); } } /** * Creates the connectivity edges between objects on the display. * * @param levels */ private void createConnectivityEdges(ArrayList levels) { // Now, create connectivity edges between states for (int i = 0; i < levels.size(); i++) { createConnectivityEdgeForLevel((ArrayList) levels.get(i)); } } /** * Creates global state objects for an individual level, placing them evenly * in the display * * @param levelNum * @param level * @param splits */ private void createLevel(int levelNum, ArrayList level, double[] splits) { for (int esNum = 0; esNum < level.size(); esNum++) { createGlobalState(levelNum, (ExplorationState) level.get(esNum), splits[esNum]); } } /** * Creates a global state and adds it to this pane's set of drawing objects. * * @param levelNum * @param es * @param split */ private void createGlobalState(int levelNum, ExplorationState es, double split) { GlobalState gs = new GlobalState(es); es.setAssociatedAttribute(gs); double gsX = split - (GlobalState.DEFAULT_WIDTH / 2); double gsY = VERTICAL_STANDOFF + levelNum * levelHeight; gs.setFrame(gsX, gsY, GlobalState.DEFAULT_WIDTH, GlobalState.DEFAULT_HEIGHT); gs.setEditable(false); addDrawingObject(gs); } /** * Creates all connectivity edges for the given level. * * @param level */ private void createConnectivityEdgeForLevel(ArrayList level) { for (int i = 0; i < level.size(); i++) { ExplorationState es = (ExplorationState) level.get(i); createConnectivityEdgeForState(es); } } /** * For a given state, creates the connectivity edges * * @param es */ private void createConnectivityEdgeForState(ExplorationState es) { // For each next state, create a connectivity edge for the global states // and associate them. GlobalState sourceState = (GlobalState) es.getAssociatedAttribute(); for (Iterator nextStateIterator = es.nextStateIterator(); nextStateIterator.hasNext();) { ExplorationState.NextStateContainer targetExplorationState = (ExplorationState.NextStateContainer) nextStateIterator.next(); String transitionLabel = targetExplorationState.getTransitionLabel(); GlobalState targetState = (GlobalState) targetExplorationState.getExplorationState().getAssociatedAttribute(); buildConnectivityEdge(sourceState, targetState, transitionLabel); } } /** * Builds an individual connectivity edge from the given source to the given * target. * * @param sourceState * @param targetState * @param transitionLabel */ private void buildConnectivityEdge(GlobalState sourceState, GlobalState targetState, String transitionLabel) { ConnectivityEdge ce = new ConnectivityEdge(sourceState, targetState); ce.setEdgeLabel(transitionLabel); ce.setEditable(false); addDrawingObject(ce); } /** * Returns the number of global states in the drawing. * @return */ public int getNumberOfGlobalStates() { int numberOfGlobalStates = 0; for (Iterator iter = getGraphicsComponents().iterator(); iter.hasNext(); ) { if (iter.next() instanceof GlobalState) { numberOfGlobalStates++; } } // for all known drawing objects. return numberOfGlobalStates; } /** * Returns the number of deadlocked states in the drawing. * @return */ public int getNumberOfDeadlockedStates() { int numberOfDeadlocked = 0; for (Iterator iter = getGraphicsComponents().iterator(); iter.hasNext(); ) { Object o = iter.next(); if (o instanceof GlobalState) { ExplorationState es = (ExplorationState)((GlobalState)o).getExplorationState(); if (es.isStateIsDeadlocked()) { numberOfDeadlocked++; } } } // for all known drawing objects. return numberOfDeadlocked; } /** * Returns the number of deadlocked states in the drawing. * @return */ public int getNumberOfUnspecifiedReceptionStates() { int numberOfURS = 0; for (Iterator iter = getGraphicsComponents().iterator(); iter.hasNext(); ) { Object o = iter.next(); if (o instanceof GlobalState) { ExplorationState es = (ExplorationState)((GlobalState)o).getExplorationState(); if (es.isStateIsUnspecifiedReception()) { numberOfURS++; } } } // for all known drawing objects. return numberOfURS; } }