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