001    /* ========================================================================
002     * JCommon : a free general purpose class library for the Java(tm) platform
003     * ========================================================================
004     *
005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006     * 
007     * Project Info:  http://www.jfree.org/jcommon/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it 
010     * under the terms of the GNU Lesser General Public License as published by 
011     * the Free Software Foundation; either version 2.1 of the License, or 
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but 
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022     * USA.  
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025     * in the United States and other countries.]
026     * 
027     * -----------------------
028     * DowngradeActionMap.java
029     * -----------------------
030     * (C)opyright 2003, by Thomas Morgner and Contributors.
031     *
032     * Original Author:  Thomas Morgner;
033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
034     *
035     * $Id: DowngradeActionMap.java,v 1.4 2007/11/02 17:50:37 taqua Exp $
036     *
037     * Changes 
038     * -------
039     * 28-Oct-2003 : Initial version
040     * 07-Jun-2004 : Corrected source headers (DG);
041     * 
042     */
043    
044    package org.jfree.ui.action;
045    
046    import java.util.ArrayList;
047    import java.util.HashMap;
048    import javax.swing.Action;
049    
050    /**
051     * An actionmap, which is JDK 1.2.2 compatible.
052     * <p>
053     * This implementation does not implement the ActionMap interface of
054     * JDK 1.3 or higher to maintain the compatibility with JDK 1.2 which
055     * does not know this interface.
056     * <p>
057     * The usage is still the same.
058     *
059     * @author Thomas Morger
060     */
061    public class DowngradeActionMap {
062    
063        /** A map containing the key to action mapping. */
064        private final HashMap actionMap;
065      
066        /** A list containing the actionkeys in their order of addition. */
067        private final ArrayList actionList;
068      
069        /** The parent of this action map. */
070        private DowngradeActionMap parent;
071    
072        /**
073         * Default Constructor. Creates a new empty map.
074         */
075        public DowngradeActionMap() {
076            this.actionMap = new HashMap();
077            this.actionList = new ArrayList();
078        }
079    
080        /**
081         * Sets this <code>ActionMap</code>'s parent.
082         *
083         * @param map  the <code>ActionMap</code> that is the parent of this one
084         */
085        public void setParent(final DowngradeActionMap map) {
086            this.parent = map;
087        }
088    
089        /**
090         * Returns this <code>ActionMap</code>'s parent.
091         *
092         * @return the <code>ActionMap</code> that is the parent of this one,
093         *         or null if this <code>ActionMap</code> has no parent
094         */
095        public DowngradeActionMap getParent() {
096            return this.parent;
097        }
098    
099        /**
100         * Adds a binding for <code>key</code> to <code>action</code>.
101         * If <code>action</code> is null, this removes the current binding
102         * for <code>key</code>.
103         * <p>In most instances, <code>key</code> will be
104         * <code>action.getValue(NAME)</code>.
105         *
106         * @param key the key for the action.
107         * @param action the action to be added.
108         */
109        public void put(final Object key, final Action action) {
110            if (action == null) {
111                remove(key);
112            }
113            else {
114               if (this.actionMap.containsKey(key)) {
115                   remove(key);
116               }
117               this.actionMap.put(key, action);
118               this.actionList.add (key);
119            }
120        }
121    
122        /**
123         * Returns the binding for <code>key</code>, messaging the
124         * parent <code>ActionMap</code> if the binding is not locally defined.
125         *
126         * @param key the key to be queried.
127         * @return the action for this key, or null if there is no such action.
128         */
129        public Action get(final Object key) {
130            final Action retval = (Action) this.actionMap.get(key);
131            if (retval != null) {
132                return retval;
133            }
134            if (this.parent != null) {
135                return this.parent.get(key);
136            }
137            return null;
138        }
139    
140        /**
141         * Removes the binding for <code>key</code> from this <code>ActionMap</code>.
142         *
143         * @param key the key to be removed.
144         */
145        public void remove(final Object key) {
146            this.actionMap.remove(key);
147            this.actionList.remove(key);
148        }
149    
150        /**
151         * Removes all the mappings from this <code>ActionMap</code>.
152         */
153        public void clear() {
154            this.actionMap.clear();
155            this.actionList.clear();
156        }
157    
158        /**
159         * Returns the <code>Action</code> names that are bound in this <code>ActionMap</code>.
160         *
161         * @return the keys which are directly bound to this map.
162         */
163        public Object[] keys() {
164            return this.actionList.toArray();
165        }
166    
167        /**
168         * Returns the number of bindings.
169         *
170         * @return the number of entries in this map.
171         */
172        public int size() {
173            return this.actionMap.size();
174        }
175    
176        /**
177         * Returns an array of the keys defined in this <code>ActionMap</code> and
178         * its parent. This method differs from <code>keys()</code> in that
179         * this method includes the keys defined in the parent.
180         *
181         * @return all keys of this map and all parents.
182         */
183        public Object[] allKeys() {
184            if (this.parent == null) {
185                return keys();
186            }
187            final Object[] parentKeys = this.parent.allKeys();
188            final Object[] key = keys();
189            final Object[] retval = new Object[parentKeys.length + key.length];
190            System.arraycopy(key, 0, retval, 0, key.length);
191            System.arraycopy(retval, 0, retval, key.length, retval.length);
192            return retval;
193        }
194    
195    }