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