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.3 2005/10/18 13:22:13 mungady 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    
049    import javax.swing.Action;
050    
051    /**
052     * An actionmap, which is JDK 1.2.2 compatible.
053     * <p>
054     * This implementation does not implement the ActionMap interface of
055     * JDK 1.3 or higher to maintain the compatibility with JDK 1.2 which
056     * does not know this interface.
057     * <p>
058     * The usage is still the same.
059     *
060     * @author Thomas Morger
061     */
062    public class DowngradeActionMap {
063    
064        /** A map containing the key to action mapping. */
065        private final HashMap actionMap;
066      
067        /** A list containing the actionkeys in their order of addition. */
068        private final ArrayList actionList;
069      
070        /** The parent of this action map. */
071        private DowngradeActionMap parent;
072    
073        /**
074         * Default Constructor. Creates a new empty map.
075         */
076        public DowngradeActionMap() {
077            this.actionMap = new HashMap();
078            this.actionList = new ArrayList();
079        }
080    
081        /**
082         * Sets this <code>ActionMap</code>'s parent.
083         *
084         * @param map  the <code>ActionMap</code> that is the parent of this one
085         */
086        public void setParent(final DowngradeActionMap map) {
087            this.parent = map;
088        }
089    
090        /**
091         * Returns this <code>ActionMap</code>'s parent.
092         *
093         * @return the <code>ActionMap</code> that is the parent of this one,
094         *         or null if this <code>ActionMap</code> has no parent
095         */
096        public DowngradeActionMap getParent() {
097            return this.parent;
098        }
099    
100        /**
101         * Adds a binding for <code>key</code> to <code>action</code>.
102         * If <code>action</code> is null, this removes the current binding
103         * for <code>key</code>.
104         * <p>In most instances, <code>key</code> will be
105         * <code>action.getValue(NAME)</code>.
106         *
107         * @param key the key for the action.
108         * @param action the action to be added.
109         */
110        public void put(final Object key, final Action action) {
111            if (action == null) {
112                remove(key);
113            }
114            else {
115               if (this.actionMap.containsKey(key)) {
116                   remove(key);
117               }
118               this.actionMap.put(key, action);
119               this.actionList.add (key);
120            }
121        }
122    
123        /**
124         * Returns the binding for <code>key</code>, messaging the
125         * parent <code>ActionMap</code> if the binding is not locally defined.
126         *
127         * @param key the key to be queried.
128         * @return the action for this key, or null if there is no such action.
129         */
130        public Action get(final Object key) {
131            final Action retval = (Action) this.actionMap.get(key);
132            if (retval != null) {
133                return retval;
134            }
135            if (this.parent != null) {
136                return this.parent.get(key);
137            }
138            return null;
139        }
140    
141        /**
142         * Removes the binding for <code>key</code> from this <code>ActionMap</code>.
143         *
144         * @param key the key to be removed.
145         */
146        public void remove(final Object key) {
147            this.actionMap.remove(key);
148            this.actionList.remove(key);
149        }
150    
151        /**
152         * Removes all the mappings from this <code>ActionMap</code>.
153         */
154        public void clear() {
155            this.actionMap.clear();
156            this.actionList.clear();
157        }
158    
159        /**
160         * Returns the <code>Action</code> names that are bound in this <code>ActionMap</code>.
161         *
162         * @return the keys which are directly bound to this map.
163         */
164        public Object[] keys() {
165            return this.actionList.toArray();
166        }
167    
168        /**
169         * Returns the number of bindings.
170         *
171         * @return the number of entries in this map.
172         */
173        public int size() {
174            return this.actionMap.size();
175        }
176    
177        /**
178         * Returns an array of the keys defined in this <code>ActionMap</code> and
179         * its parent. This method differs from <code>keys()</code> in that
180         * this method includes the keys defined in the parent.
181         *
182         * @return all keys of this map and all parents.
183         */
184        public Object[] allKeys() {
185            if (this.parent == null) {
186                return keys();
187            }
188            final Object[] parentKeys = this.parent.allKeys();
189            final Object[] key = keys();
190            final Object[] retval = new Object[parentKeys.length + key.length];
191            System.arraycopy(key, 0, retval, 0, key.length);
192            System.arraycopy(retval, 0, retval, key.length, retval.length);
193            return retval;
194        }
195    
196    }