001package jmri.util.swing;
002
003import javax.swing.Icon;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * Action that, when invoked, creates a JmriPanel from its class name
009 * and installs it in a given window.
010 * <p>
011 * Windows are referenced through the {@link WindowInterface}, which can
012 * provide access to a new or existing single-pane window, or a more complex multi-pane
013 * window as seen in the DecoderPro interface.
014 *
015 * @author Bob Jacobsen Copyright (C) 2010
016 */
017public class JmriNamedPaneAction extends JmriAbstractAction {
018
019    /**
020     * Constructor that associates a newly created panel with the given window, showing a name
021     *
022     * @param s         Human-readable panel name for display by the action
023     * @param wi        Window into which to install the new panel. If you want it to be put into a existing
024     *                  one, provide a reference. To create a new window
025     *                  containing just this pane, use "new jmri.util.swing.sdi.JmriJFrameInterface()"
026     * @param paneClass Name of the panel's class, which must be a subclass of JmriPanel. That's not
027     *                  checked at compile time or when the constructor runs, but must be true
028     *                  for the action to be invoked successfully.
029     */
030    public JmriNamedPaneAction(String s, WindowInterface wi, String paneClass) {
031        super(s, wi);
032        this.paneClass = paneClass;
033    }
034
035    /**
036     * Constructor that associates a newly created panel with the given window, showing a name and icon
037     *
038     * @param s         Human-readable panel name for display by the action
039     * @param i         Icon for display by the action
040     * @param wi        Window into which to install the new panel. If you want it to be put into a existing
041     *                  one, provide a reference. To create a new window
042     *                  containing just this pane, use "new jmri.util.swing.sdi.JmriJFrameInterface()"
043     * @param paneClass Name of the panel's class, which must be a subclass of JmriPanel. That's not
044     *                  checked at compile time or when the constructor runs, but must be true
045     *                  for the action to be invoked successfully.
046     */
047    public JmriNamedPaneAction(String s, Icon i, WindowInterface wi, String paneClass) {
048        super(s, i, wi);
049        this.paneClass = paneClass;
050    }
051
052    /**
053     * Original constructor for compatibility with older menus. Assumes SDI GUI.
054     *
055     * @param s         Human-readable panel name for display by the action
056     * @param paneClass Name of the panel's class, which must be a subclass of JmriPanel. That's not
057     *                  checked at compile time or when the constructor runs, but must be true
058     *                  for the action to be invoked successfully.
059     */
060    public JmriNamedPaneAction(String s, String paneClass) {
061        this(s, new jmri.util.swing.sdi.JmriJFrameInterface(), paneClass);
062    }
063
064    protected String paneClass;
065
066    /**
067     * Invoked as part of the action being invoked, e.g. when button pressed
068     * or menu item selected, this runs the panel through the initial part of
069     * its life cycle and installs in the given window interface.
070     * <p>
071     * If different or additional initialization is needed, inherit from this class and
072     * override this method to do it.
073     */
074    @Override
075    public jmri.util.swing.JmriPanel makePanel() {
076        try {
077            JmriPanel p = (JmriPanel) Class.forName(paneClass).getDeclaredConstructor().newInstance();
078            p.setWindowInterface(wi);
079            p.initComponents();
080            p.initContext(context);
081
082            return p;
083        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException | java.lang.reflect.InvocationTargetException ex ) {
084            log.warn("could not load pane class: {}", paneClass, ex);
085            return null;
086        }
087    }
088
089    private final static Logger log = LoggerFactory.getLogger(JmriNamedPaneAction.class);
090}