001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.command;
017    
018    import java.awt.event.ActionEvent;
019    import java.beans.PropertyChangeEvent;
020    import java.beans.PropertyChangeListener;
021    
022    import javax.swing.AbstractAction;
023    import javax.swing.Action;
024    
025    import org.springframework.richclient.command.config.CommandFaceDescriptor;
026    import org.springframework.richclient.util.Assert;
027    
028    /**
029     * An adapter between a Spring Rich Client {@link ActionCommand} and the Swing 
030     * {@link Action} interface. 
031     * 
032     * <p>
033     * This adheres to the standard GoF {@code Adapter} pattern whereby this class acts as 
034     * a wrapper around an underlying {@link ActionCommand} to give it the appearance of 
035     * being an {@link Action}. 
036     * </p>
037     * 
038     * <p>
039     * The {@link PropertyChangeListener} interface is also implemented so that 
040     * instances can be notified of property change events being fired by their underlying command.
041     * </p>
042     */
043    public class SwingActionAdapter extends AbstractAction implements PropertyChangeListener {
044        
045        private ActionCommand command;
046    
047        /**
048         * Creates a new {@code SwingActionAdapter} with the given underlying action command. The 
049         * newly created instance will add itself as a property change listener of the command.
050         *
051         * @param command The underlying action command.
052         * 
053         * @throws IllegalArgumentException if {@code command} is null.
054         */
055        public SwingActionAdapter(ActionCommand command) {
056            super();
057            
058            Assert.required(command, "command");
059            this.command = command;
060            command.addPropertyChangeListener(this);
061            command.addEnabledListener(this);
062            update();
063            
064        }
065    
066        /**
067         * Delegates the handling of the given event to the underlying command.
068         * @param event The action event to be handled.
069         */
070        public void actionPerformed(ActionEvent event) {
071            command.actionPerformedHandler.actionPerformed(event);
072        }
073    
074        /**
075         * {@inheritDoc}
076         */
077        public void propertyChange(PropertyChangeEvent event) {
078            update();
079        }
080    
081        /**
082         * Updates this instance according to the properties provided by the 
083         * underlying command. 
084         */
085        protected void update() {
086            putValue(Action.ACTION_COMMAND_KEY, command.getActionCommand());
087            CommandFaceDescriptor face = command.getFaceDescriptor();
088            if (face != null) {
089                face.configure(this);
090            }
091            setEnabled(command.isEnabled());
092        }
093    
094    }