001package jmri.util.swing.multipane;
002
003import jmri.util.gui.GuiLafPreferencesManager;
004import java.awt.BorderLayout;
005import java.awt.Component;
006import java.awt.FlowLayout;
007import java.awt.Font;
008import javax.swing.Box;
009import javax.swing.BoxLayout;
010import javax.swing.JComponent;
011import javax.swing.JLabel;
012import javax.swing.JMenu;
013import javax.swing.JMenuBar;
014import javax.swing.JPanel;
015import javax.swing.JSeparator;
016import javax.swing.JSplitPane;
017import javax.swing.JToolBar;
018import javax.swing.border.BevelBorder;
019import jmri.InstanceManager;
020import jmri.util.swing.JMenuUtil;
021import jmri.util.swing.JToolBarUtil;
022
023/**
024 * MultiPane JMRI window with a "top" area over a single bottom lower pane,
025 * optional toolbar and menu.
026 *
027 * @author Bob Jacobsen Copyright 2010
028 * @since 2.13.1
029 */
030abstract public class TwoPaneTBWindow extends jmri.util.JmriJFrame {
031
032    /**
033     * Create and initialize a multi-pane GUI window.
034     *
035     * @param name        the name and title of the window
036     * @param menubarFile path to the XML file for the menubar
037     * @param toolbarFile path to the XML file for the toolbar
038     */
039    public TwoPaneTBWindow(String name, String menubarFile, String toolbarFile) {
040        super(name);
041        buildGUI(menubarFile, toolbarFile);
042        pack();
043    }
044
045    JSplitPane upDownSplitPane;
046
047    JPanel top = new JPanel();
048
049    JPanel bottom = new JPanel();
050
051    JPanel statusBar = new JPanel();
052
053    JToolBar toolBar = new JToolBar();
054
055    public JComponent getTop() {
056        return top;
057    }
058
059    public JComponent getBottom() {
060        return bottom;
061    }
062
063    public JComponent getToolBar() {
064        return toolBar;
065    }
066
067    public JComponent getSplitPane() {
068        return upDownSplitPane;
069    }
070
071    protected void buildGUI(String menubarFile, String toolbarFile) {
072        configureFrame();
073        addMainMenuBar(menubarFile);
074        addMainToolBar(toolbarFile);
075        addMainStatusBar();
076    }
077
078    protected void configureFrame() {
079
080        //rightTop.setBorder(BorderFactory.createLineBorder(Color.black));
081        top.setLayout(new BoxLayout(top, BoxLayout.X_AXIS));
082        bottom.setLayout(new BoxLayout(bottom, BoxLayout.X_AXIS));
083
084        upDownSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
085                top,
086                bottom);
087        upDownSplitPane.setOneTouchExpandable(true);
088        upDownSplitPane.setResizeWeight(1.0);  // emphasize top part
089
090        add(upDownSplitPane, BorderLayout.CENTER);
091    }
092
093    public void resetTopToPreferredSizes() {
094        upDownSplitPane.resetToPreferredSizes();
095    }
096
097    protected boolean hideBottomPane = false;
098
099    public void hideBottomPane(boolean hide) {
100        if (hideBottomPane == hide) {
101            return;
102        }
103        hideBottomPane = hide;
104        if (hide) {
105            upDownSplitPane.setDividerLocation(1.0d);
106        } else {
107            resetTopToPreferredSizes();
108        }
109    }
110
111    JMenuBar menuBar = new JMenuBar();
112
113    protected void addMainMenuBar(String menuFile) {
114        if (menuFile == null) {
115            return;
116        }
117
118        JMenu[] menus = JMenuUtil.loadMenu(menuFile, this, this);
119        for (JMenu j : menus) {
120            menuBar.add(j);
121        }
122
123        setJMenuBar(menuBar);
124    }
125
126    public JMenuBar getMenu() {
127        return menuBar;
128    }
129
130    protected void addMainToolBar(String toolBarFile) {
131        if (toolBarFile == null) {
132            return;
133        }
134
135        toolBar = JToolBarUtil.loadToolBar(toolBarFile, this, this);
136
137        // this takes up space at the top until pulled to floating
138        add(toolBar, BorderLayout.NORTH);
139    }
140
141    abstract public void remoteCalls(String args[]);
142
143    protected void addMainStatusBar() {
144        statusBar.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0));
145        statusBar.setBorder(new BevelBorder(BevelBorder.LOWERED));
146
147        statusBox = Box.createHorizontalBox();
148        statusBox.add(Box.createHorizontalGlue());
149        statusBar.add(statusBox);
150        add(statusBar, BorderLayout.SOUTH);
151    }
152
153    public void addToStatusBox(JLabel title, JLabel value) {
154        JPanel statusItemPanel = new JPanel();
155        statusItemPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 0));
156        //Set the font size of the status bar text to be 1points less than the default configured, also set as plain
157        int fontSize = InstanceManager.getDefault(GuiLafPreferencesManager.class).getFontSize() - 1;
158        if (title != null) {
159            if (fontSize <= 4) {
160                fontSize = title.getFont().getSize() - 1;
161            }
162            title.setFont(title.getFont().deriveFont(Font.PLAIN, fontSize));
163            statusItemPanel.add(title);
164        }
165        if (value != null) {
166            if (fontSize <= 4) {
167                fontSize = value.getFont().getSize() - 1;
168            }
169            value.setFont(value.getFont().deriveFont(Font.PLAIN, fontSize));
170            statusItemPanel.add(value);
171        }
172        addToStatusBox(statusItemPanel);
173    }
174
175    Box statusBox;
176    int statusBoxIndex = 0; // index to insert extra stuff
177    static final int statusStrutWidth = 10;
178
179    public void addToStatusBox(Component comp) {
180        if (statusBoxIndex != 0) {
181            statusBox.add(Box.createHorizontalStrut(statusStrutWidth), statusBoxIndex);
182            ++statusBoxIndex;
183            statusBox.add(new JSeparator(javax.swing.SwingConstants.VERTICAL), statusBoxIndex);
184            ++statusBoxIndex;
185        }
186        statusBox.add(comp, statusBoxIndex);
187        ++statusBoxIndex;
188    }
189
190    /**
191     * Only close frame, etc.
192     * super.dispose() disposes of all cached panes.
193     */
194    @Override
195    public void dispose() {
196        super.dispose();
197    }
198
199}