001package jmri.util.swing.sdi;
002
003import java.awt.Frame;
004import java.util.HashMap;
005import java.util.List;
006import javax.swing.JMenu;
007import javax.swing.JMenuBar;
008import jmri.util.JmriJFrame;
009import jmri.util.swing.JmriAbstractAction;
010import jmri.util.swing.JmriPanel;
011
012/**
013 * Display a JmriPanel in a JFrame of its own.
014 *
015 * Dispose() of a multi-instance panel is invoked when the containing window is
016 * fully closed via a listener installed here. Single instance
017 * (non-multi-instance) panels are cached and never disposed.
018 *
019 * @author Bob Jacobsen Copyright 2010
020 * @since 2.9.4
021 */
022public class JmriJFrameInterface implements jmri.util.swing.WindowInterface {
023
024    HashMap<JmriPanel, JmriJFrame> frames = new HashMap<JmriPanel, JmriJFrame>();
025
026    @Override
027    public void show(final JmriPanel child,
028            JmriAbstractAction act,
029            Hint hint) {
030
031        // display cached frame if available
032        JmriJFrame frame = frames.get(child);
033        if (frame != null) {
034            frame.setVisible(true);
035            return;
036        }
037
038        // create frame
039        frame = new jmri.util.JmriJFrame(child.getClass().getName());
040
041        // cache if single instance
042        if (!child.isMultipleInstances()) {
043            frames.put(child, frame);
044        }
045
046        // add gui object, responsible for own layout
047        frame.add(child);
048
049        // add menus if requested
050        List<JMenu> list = child.getMenus();
051        JMenuBar bar = frame.getJMenuBar();
052        if (bar == null) {
053            bar = new JMenuBar();
054        }
055        for (JMenu menu : list) {
056            bar.add(menu);
057        }
058        frame.setJMenuBar(bar);
059
060        // add help menu if requested
061        if (child.getHelpTarget() != null) {
062            frame.addHelpMenu(child.getHelpTarget(), true);
063        }
064
065        // set title if available
066        if (child.getTitle() != null) {
067            frame.setTitle(child.getTitle());
068        }
069
070        // if multi-instance, arrange to run dispose on close
071        if (child.isMultipleInstances()) {
072            frame.addWindowListener(new java.awt.event.WindowAdapter() {
073                jmri.util.swing.JmriPanel c;
074
075                {
076                    c = child;
077                }
078
079                @Override
080                public void windowClosed(java.awt.event.WindowEvent e) {
081                    c.dispose();
082                }
083            });
084        }
085
086        // pack and show
087        frame.pack();
088        frame.setVisible(true);
089    }
090
091    @Override
092    public void show(final jmri.util.swing.JmriPanel child,
093            jmri.util.swing.JmriAbstractAction act) {
094
095        show(child, act, Hint.DEFAULT);
096    }
097
098    /**
099     * Create new windows on each request
100     */
101    @Override
102    public boolean multipleInstances() {
103        return true;
104    }
105
106    @Override
107    public void dispose() {
108    }
109
110    @Override
111    public Frame getFrame() {
112        return null;
113    }
114}