001package jmri.util.swing.multipane;
002
003import java.awt.BorderLayout;
004import java.awt.Color;
005import java.awt.Dimension;
006import java.awt.FlowLayout;
007import javax.swing.AbstractAction;
008import javax.swing.BorderFactory;
009import javax.swing.JComponent;
010import javax.swing.JMenu;
011import javax.swing.JMenuBar;
012import javax.swing.JPanel;
013import javax.swing.JScrollPane;
014import javax.swing.JSplitPane;
015import javax.swing.JToolBar;
016import javax.swing.JTree;
017import javax.swing.tree.DefaultMutableTreeNode;
018import javax.swing.tree.TreeNode;
019import javax.swing.tree.TreeSelectionModel;
020import jmri.util.swing.JMenuUtil;
021import jmri.util.swing.JToolBarUtil;
022import jmri.util.swing.JTreeUtil;
023
024/**
025 * Core JMRI multi-pane GUI window.
026 *
027 * @author Bob Jacobsen Copyright 2010
028 * @since 2.9.4
029 */
030public class MultiPaneWindow 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 treeFile path to the XML file for the navigation tree
037     * @param menubarFile path to the XML file for the menubar
038     * @param toolbarFile path to the XML file for the toolbar
039     */
040    public MultiPaneWindow(String name, String treeFile, String menubarFile, String toolbarFile) {
041        super(name);
042        buildGUI(treeFile, menubarFile, toolbarFile);
043        pack();
044    }
045
046    JSplitPane leftRightSplitPane;
047
048    JPanel left = new JPanel();
049
050    JSplitPane rightUpDownSplitPane;
051    JPanel rightTop = new JPanel();
052    JPanel rightBottom = new JPanel();
053
054    public JComponent getLowerRight() {
055        return rightBottom;
056    }
057
058    public JComponent getUpperRight() {
059        return rightTop;
060    }
061
062    PanedInterface rightTopWI;
063
064    protected void buildGUI(String treeFile, String menubarFile, String toolbarFile) {
065        configureFrame();
066        configureNavTreePane(treeFile);
067        addMainMenuBar(menubarFile);
068        addMainToolBar(toolbarFile);
069    }
070
071    protected void configureFrame() {
072
073        rightTop.setBorder(BorderFactory.createLineBorder(Color.black));
074        rightTop.setLayout(new FlowLayout());            // new BoxLayout(rightTop, BoxLayout.Y_AXIS));
075
076        rightBottom.setLayout(new FlowLayout());            // new BoxLayout(rightBottom, BoxLayout.Y_AXIS));
077
078        rightUpDownSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, rightTop, rightBottom);
079        rightUpDownSplitPane.setOneTouchExpandable(true);
080        rightUpDownSplitPane.setResizeWeight(1.0);  // emphasize top part
081
082        leftRightSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
083                new JPanel(), // placeholder
084                rightUpDownSplitPane);
085        leftRightSplitPane.setOneTouchExpandable(true);
086        leftRightSplitPane.setResizeWeight(0.0);  // emphasize right part
087
088        add(leftRightSplitPane, BorderLayout.CENTER);
089    }
090
091    protected void configureNavTreePane(String treeFile) {
092        leftRightSplitPane.setLeftComponent(makeNavTreePane(treeFile));
093    }
094
095    protected JScrollPane makeNavTreePane(String treeFile) {
096        final JTree tree;
097        TreeNode topNode;
098
099        rightTopWI = new PanedInterface(this);
100
101        topNode = makeNavTreeTopNode(treeFile, rightTopWI);
102
103        tree = new JTree(topNode);
104        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
105        tree.setRootVisible(false);  // allow multiple roots
106
107        // install listener
108        tree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
109            @Override
110            public void valueChanged(javax.swing.event.TreeSelectionEvent e) {
111                DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
112                if (node == null) {
113                    return; //Nothing is selected.
114                }
115                if (node.getUserObject() == null) {
116                    return; // Not an interesting node
117                }
118                if (node.getUserObject() instanceof AbstractAction) {
119                    AbstractAction action = (AbstractAction) node.getUserObject();
120                    action.actionPerformed(null);
121                }
122            }
123        });
124        // install in scroll area
125        JScrollPane treeView = new JScrollPane(tree);
126        treeView.setMinimumSize(new Dimension(0, 0));
127        treeView.setPreferredSize(new Dimension(150, 600));
128        return treeView;
129    }
130
131    protected TreeNode makeNavTreeTopNode(String treeFile, PanedInterface rightTopWI) {
132        return JTreeUtil.loadTree(treeFile, rightTopWI, null);  // no context
133    }
134
135    public void resetRightToPreferredSizes() {
136        rightUpDownSplitPane.resetToPreferredSizes();
137    }
138
139    protected void addMainMenuBar(String menuFile) {
140        JMenuBar menuBar = new JMenuBar();
141
142        JMenu[] menus = JMenuUtil.loadMenu(menuFile, rightTopWI, null);
143        for (JMenu j : menus) {
144            menuBar.add(j);
145        }
146
147        setJMenuBar(menuBar);
148    }
149
150    protected void addMainToolBar(String toolBarFile) {
151
152        JToolBar toolBar = JToolBarUtil.loadToolBar(toolBarFile, rightTopWI, null);
153
154        // this takes up space at the top until pulled to floating
155        add(toolBar, BorderLayout.NORTH);
156    }
157
158    /**
159     * Only close frame, etc, dispose() disposes of all cached panes
160     */
161    @Override
162    public void dispose() {
163        rightTopWI.dispose();
164        super.dispose();
165    }
166
167}