001package jmri.util.swing;
002
003import java.awt.event.ActionEvent;
004import javax.swing.Icon;
005import org.slf4j.Logger;
006import org.slf4j.LoggerFactory;
007
008/**
009 * Abstract base for actions that will work with multiple JMRI GUIs.
010 *
011 * An opaque Object can be passed as a context, but null is also possible.
012 *
013 * <b>NOTE</b> Either
014 * {@link jmri.util.swing.JmriAbstractAction#actionPerformed(java.awt.event.ActionEvent)}
015 * or {@link jmri.util.swing.JmriAbstractAction#makePanel()} must be overridden
016 * by extending classes.
017 *
018 * @author Bob Jacobsen Copyright (C) 2010
019 */
020abstract public class JmriAbstractAction extends javax.swing.AbstractAction {
021
022    protected WindowInterface.Hint hint = WindowInterface.Hint.DEFAULT;
023    protected WindowInterface wi;
024    protected Object context = null;
025    private final static Logger log = LoggerFactory.getLogger(JmriAbstractAction.class);
026
027    /**
028     * Enhanced constructor for placing the pane in various GUIs.
029     *
030     * @param name the name for the action; a value of null is ignored
031     * @param wi   the window interface controlling how this action is displayed
032     */
033    public JmriAbstractAction(String name, WindowInterface wi) {
034        super(name);
035        this.wi = wi;
036        if (wi == null) {
037            log.error("Cannot create action with null WindowInterface", new Exception());
038        }
039    }
040
041    public JmriAbstractAction(String s, Icon i, WindowInterface wi) {
042        super(s, i);
043        this.wi = wi;
044    }
045
046    /**
047     * Set the context for this action. The context can be any object that an
048     * overriding class may need to complete an action. It is defined here to
049     * provide a common API for passing these objects in.
050     *
051     * @param context the context object
052     * @since 2.9.4
053     */
054    public void setContext(Object context) {
055        this.context = context;
056    }
057
058    /**
059     * Original constructor for compatibility with older menus. Assumes SDI GUI.
060     *
061     * @param name the name for the action; a value of null is ignored
062     */
063    public JmriAbstractAction(String name) {
064        super(name);
065        this.wi = new jmri.util.swing.sdi.JmriJFrameInterface();
066    }
067
068    public void setWindowInterface(WindowInterface wi) {
069        this.wi = wi;
070    }
071
072    public void setName(String name) {
073        putValue(javax.swing.Action.NAME, name);
074    }
075
076    @Override
077    public String toString() {
078        return (String) getValue(javax.swing.Action.NAME);
079    }
080
081    public JmriAbstractAction setHint(WindowInterface.Hint hint) {
082        this.hint = hint;
083        return this;
084    }
085
086    @Override
087    public void actionPerformed(ActionEvent e) {
088        // we have to make a new panel if we don't have one yet
089        // we don't make a new panel if the window interface is
090        //      single instance (not multiple instance),
091        // or if the existing panel is single instance (not multiple instance)
092        if (cache == null
093                || (wi.multipleInstances() && cache.isMultipleInstances())) {
094            try {
095                cache = makePanel();
096            } catch (Exception ex) {
097                log.error("Exception creating panel", ex);
098                return;
099            }
100            if (cache == null) {
101                log.error("Unable to make panel");
102                return;
103            }
104        }
105
106        wi.show(cache, this, hint);  // no real context, this is new content
107    }
108
109    public void dispose() {
110        if (cache != null) {
111            cache.dispose();
112            cache = null;
113        }
114    }
115    JmriPanel cache = null;
116
117    // A crude method to set a parameter in a given window when loading from the xml file
118    public void setParameter(String parameter, String value) {
119    }
120
121    // A method to allow named parameters to be passed in.
122    // Note that if value is a String, setParameter(String, String) needs to be
123    // implemented (for reasons I do not understand jmri.util.swing.GuiUtilBase
124    // will not call this method with a String parameter for value)
125    public void setParameter(String parameter, Object value) {
126    }
127
128    abstract public JmriPanel makePanel();
129
130}