/* * 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 gui.viewer; import automata.event.AutomataStateEvent; import automata.Automaton; import automata.State; import automata.Transition; import gui.viewer.StateDrawer; import java.util.Set; import java.util.HashSet; import java.util.Iterator; import java.awt.Color; import java.awt.Graphics; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * An extension of the AutomatonDrawer that allows the selection * (i.e. highlighting) of states. * * @author Thomas Finley */ public class SelectionDrawer extends AutomatonDrawer { /** * Instantiates a new selection drawer with no states selected. * * @param automaton * the automaton to select */ public SelectionDrawer(Automaton automaton) { super(automaton); } /** * Listens for changes in the states of the automaton. In the event that one * has it checks the selected states. * * @param event * the state event */ protected void stateChange(AutomataStateEvent event) { if (event.isDelete()) selected.remove(event.getState()); super.stateChange(event); } /** * If a state is selected, draw it somewhat darker than the others. If it is * not, then simply use the regular means for drawing a state. * * @param g * the graphics object to draw on * @param state * the state to draw */ public void drawState(Graphics g, State state) { if (selected.contains(state)) { getStateDrawer().drawState(g, getAutomaton(), state, state.getPoint(), SELECTED_COLOR); if (doesDrawStateLabels()) getStateDrawer().drawStateLabel(g, state, state.getPoint(), StateDrawer.STATE_COLOR); } else super.drawState(g, state); } /** * Draws the transitions normally, then draws the highlight for the selected * transitions. * * @param g * the graphics object to draw upon */ protected void drawTransitions(Graphics g) { java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; super.drawTransitions(g); Iterator it = selectedTransitions.iterator(); while (it.hasNext()) { Transition t = (Transition) it.next(); try { arrowForTransition(t).drawHighlight(g2); } catch (NullPointerException e) { // Then this transition isn't in here. } } } /** * Adds a state to the selected states. * * @param state * the state to add */ public void addSelected(State state) { // Automaton replacer = null; // if(state.getParentBlock()!=null){ // replacer = // (Automaton)state.getAutomaton().getBlockMap().get(state.getParentBlock().getInternalName()); // } // if (state.getAutomaton() != getAutomaton() && replacer != // getAutomaton()) // throw new IllegalArgumentException // ("State to select not in correct automaton!"); if (!selected.contains(state)) { selected.add(state); distributeChangeEvent(); } } /** * Removes the state from the selected states. * * @param state * the state to remove */ public void removeSelected(State state) { if (selected.contains(state)) { selected.remove(state); distributeChangeEvent(); } } /** * Returns the number of selected states. * * @return the number of selected states */ public int numberSelected() { return selected.size(); } /** * Returns an array of the selected states. * * @return an array of the selected states */ public State[] getSelected() { return (State[]) selected.toArray(new State[0]); } /** * Determines if a particular state is selected. * * @param state * the state to check for "selectedness" * @return true if the state is selected, false * if it is not */ public boolean isSelected(State state) { return selected.contains(state); } /** * Clears all selected states, so that there are no selected states. */ public void clearSelected() { if (selected.size() + selectedTransitions.size() > 0) { selected.clear(); selectedTransitions.clear(); distributeChangeEvent(); } } /** * Retrieves the set of selected states. * * @return the set of selected states */ protected Set selected() { return selected; } /** * Returns the set of selected transitions. * * @return the set of selected transitions */ protected Set selectedTransitions() { return selectedTransitions; } /** * Adds a transition to the selected transitions. * * @param transition * the transition to add */ public void addSelected(Transition transition) { if (transition.getFromState().getAutomaton() != getAutomaton()) throw new IllegalArgumentException( "Transition to select not in correct automaton!"); if (!selectedTransitions.contains(transition)) { selectedTransitions.add(transition); distributeChangeEvent(); } } /** * Removes the transition from the selected transitions. * * @param transition * the transition to set as unselected */ public void removeSelected(Transition transition) { if (selectedTransitions.contains(transition)) { selectedTransitions.remove(transition); distributeChangeEvent(); } } /** * Returns the number of selected transitions. * * @return the number of selected transitions */ public int numberSelectedTransitions() { return selectedTransitions.size(); } /** * Returns an array of the selected transitions. * * @return an array of the selected transitions */ public Transition[] getSelectedTransitions() { return (Transition[]) selectedTransitions.toArray(new Transition[0]); } /** * Determines if a particular transition is selected. * * @param transition * the transition to check for "selectedness" * @return true if the transition is selected, false * if it is not */ public boolean isSelected(Transition transition) { return selectedTransitions.contains(transition); } /** * Clears all selected transitions, so that there are no selected * transitions. */ public void clearSelectedTransitions() { selectedTransitions.clear(); } /** * Adds a change listener to this object that listens to changes in what is * selected in this selection drawer. * * @param listener * the listener to add */ public void addChangeListener(ChangeListener listener) { listeners.add(listener); } /** * Removes a change listener from this object. * * @param listener * the listener to remove */ public void removeChangeListener(ChangeListener listener) { listeners.remove(listener); } /** * Distributes a ChangeEvent to all listeners when the * selection has changed. */ protected void distributeChangeEvent() { ChangeEvent e = new ChangeEvent(this); Iterator it = listeners.iterator(); while (it.hasNext()) ((ChangeListener) it.next()).stateChanged(e); } /** The set of selected states, and the set of selected transitions. */ private Set selected = new HashSet(), selectedTransitions = new HashSet(); /** The color to draw selected states in. */ protected static final Color SELECTED_COLOR = StateDrawer.STATE_COLOR .darker().darker(); /** This set of listeners. */ private Set listeners = new HashSet(); }