001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
004    package graphlab.platform.core;
005    
006    /**
007     * AbstractAction itself is a wrapper for the interface Action.
008     * As you see in the source, it contains only two methods to implement. The first one is the action that must be done by this action, performAction() gets the event(key) that has caused this action to be run. This helps if an action is result of multiple events or when event handling must be coped with in the implementation itself.
009     * <p/>
010     * The abstract class, AbstractAction is the minimal implementation of an Action in a class. It integrates the Action with the GraphLab structure. As a result any recognized AbstractAction in the GraphLab ui is Runnable. The introducing procedure is done via Xml files.
011     * <p/>
012     * There is no default constructor, so every descendant of AbstractAction needs to call the super constructor in its constructor first. It is because the constructor of the AbstractAction assures that the action is registered in a BlackBoard and it is enabled. Method enable() and disable() are designated to control enablity of Action groups.
013     * <p/>
014     * As you can see AbstractAction has implemented The interface Listener. It is easy to see why! Every action is a reaction to event(key change) that is called from a user or program itself. so every AbstractAction is listening to it's relevant event to be fired. Methods listen4Event() and unListenEvent() are designed to handle the relevant events.
015     * <p/>
016     * Basically if you want to do anything in GraphLab, you need to extend AbstractAction. Looking at it's code might help.
017     * <p/>
018     * note: As you may see working with AbstractAction to handle UI events is not so simple, Also there are many classes in !GraphLab that use AbstractAction. But this is not advised to you, It is easier to use Extensions whenever you want to interact with user interface. (basically UIActionExtension, but almost every extensions are welcome!)
019     *
020     * @see graphlab.ui.extension.UIActionExtension
021     * @see graphlab.platform.core.Action
022     * @see graphlab.platform.core.BlackBoard
023     * @author rouzbeh ebrahimi
024     * @author Azin Azadi
025     */
026    public abstract class AbstractAction implements Action, Listener {
027        protected BlackBoard blackboard;
028        private boolean enabled = false;
029        String lastListenedEventKey = null;
030    
031        /**
032         * constructor
033         *
034         * @param bb the blackboard of the action
035         */
036        public AbstractAction(BlackBoard bb) {
037            setBlackBoard(bb);
038            enable();
039        }
040    
041        /**
042         * like Action
043         *
044         * @param key
045         * @param value
046         */
047        public abstract void performAction(String key, Object value);
048    
049        public final void setBlackBoard(BlackBoard t) {
050            blackboard = t;
051        }
052    
053        /**
054         * @param key
055         */
056        public final void keyChanged(String key, Object value) {
057            if (enabled)
058                performAction(key, value);
059        }
060    
061    
062        /**
063         * unlisten the event, see:listen4Event
064         *
065         * @param key the Event for unlisten
066         */
067        protected final void unListenEvent(String key) {
068            blackboard.removeListener(key, this);
069        }
070    
071        public String getLastListenedEventKey() {
072            return lastListenedEventKey;
073        }
074    
075        /**
076         * listens for an event in the black board, (so multiple listening is available)
077         *
078         * @param e the Event for listening
079         */
080        protected final void listen4Event(String key) {
081            blackboard.addListener(key, this);
082            lastListenedEventKey = key;
083        }
084    
085        /**
086         * @return the blackboard of this action
087         */
088        public BlackBoard getBlackBoard() {
089            return blackboard;
090        }
091    
092        /**
093         * disables the action
094         * prevent it from doing anything.
095         * it is used in the configuration
096         */
097        public void disable() {
098            if (enabled) {
099                enabled = false;
100            }
101        }
102    
103        /**
104         * enables the action
105         * see disable
106         */
107        public void enable() {
108            if (!enabled) {
109                enabled = true;
110            }
111        }
112    
113        public final boolean isEnable() {
114            return enabled;
115        }
116    }