001package jmri.jmrit.roster.swing.rostergroup;
002
003import java.awt.Component;
004import javax.swing.Box;
005import javax.swing.BoxLayout;
006import javax.swing.JMenuBar;
007import javax.swing.JScrollPane;
008import javax.swing.JTable;
009import javax.swing.table.TableRowSorter;
010
011/**
012 * Provide a JFrame to display the Roster Data Based upon BeanTableFrame.
013 * <p>
014 * This frame includes the table itself at the top, plus a "bottom area" for
015 * things like an Add... button and checkboxes that control display options.
016 * <p>
017 * The usual menus are also provided here.
018 * <p>
019 * Specific uses are customized via the RosterGroupTableDataModel implementation
020 * they provide, and by providing a {@link #extras} implementation that can in
021 * turn invoke {@link #addToBottomBox} as needed.
022 *
023 * @author Bob Jacobsen Copyright (C) 2003
024 * @author Kevin Dickerson Copyright (C) 2009
025 */
026public class RosterGroupTableFrame extends jmri.util.JmriJFrame {
027
028    RosterGroupTableModel dataModel;
029    JTable dataTable;
030    JScrollPane dataScroll;
031    Box bottomBox;  // panel at bottom for extra buttons etc
032    int bottomBoxIndex; // index to insert extra stuff
033    static final int bottomStrutWidth = 20;
034    Box topBox;  // panel at bottom for extra buttons etc
035    int topBoxIndex; // index to insert extra stuff
036    static final int topStrutWidth = 20;
037
038    public RosterGroupTableFrame(RosterGroupTableModel model, String helpTarget) {
039
040        super();
041        dataModel = model;
042
043        dataTable = new JTable(dataModel);
044        TableRowSorter<RosterGroupTableModel> sorter = new TableRowSorter<>(dataModel);
045        dataTable.setRowSorter(sorter);
046
047        sorter.setComparator(RosterGroupTableModel.IDCOL, new jmri.util.AlphanumComparator());
048        sorter.toggleSortOrder(RosterGroupTableModel.IDCOL);
049        dataTable = new JTable(dataModel);
050        
051        dataScroll = new JScrollPane(dataTable);
052
053        // configure items for GUI
054        dataModel.configureTable(dataTable);
055
056        // general GUI config
057        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
058
059        // add save menu item
060        JMenuBar menuBar = new JMenuBar();
061
062        setJMenuBar(menuBar);
063
064        addHelpMenu(helpTarget, true);
065
066        // install items in GUI
067        topBox = Box.createHorizontalBox();
068        topBox.add(Box.createHorizontalGlue()); // stays at beginning of box
069        topBoxIndex = 0;
070        getContentPane().add(topBox);
071        getContentPane().add(dataScroll);
072
073        bottomBox = Box.createHorizontalBox();
074        bottomBox.add(Box.createHorizontalGlue()); // stays at end of box
075        bottomBoxIndex = 0;
076
077        getContentPane().add(bottomBox);
078
079        // add extras, if desired by subclass
080        extras();
081
082        // set Viewport preferred size from size of table
083        java.awt.Dimension dataTableSize = dataTable.getPreferredSize();
084        // width is right, but if table is empty, it's not high
085        // enough to reserve much space.
086        dataTableSize.height = Math.max(dataTableSize.height, 400);
087        dataScroll.getViewport().setPreferredSize(dataTableSize);
088
089        // set preferred scrolling options
090        dataScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
091        dataScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
092    }
093
094    /**
095     * Hook to allow sub-types to install more items in GUI.
096     */
097    void extras() {
098    }
099
100    protected Box getBottomBox() {
101        return bottomBox;
102    }
103
104    /**
105     * Add a component to the bottom box. Takes care of organising glue, struts
106     * etc
107     *
108     * @param comp Component to add to the bottom box
109     */
110    protected void addToBottomBox(Component comp) {
111        bottomBox.add(Box.createHorizontalStrut(bottomStrutWidth), bottomBoxIndex);
112        ++bottomBoxIndex;
113        bottomBox.add(comp, bottomBoxIndex);
114        ++bottomBoxIndex;
115    }
116
117    protected Box getTopBox() {
118        return topBox;
119    }
120
121    /**
122     * Add a component to the top box. Takes care of organising glue, struts
123     * etc.
124     * @param comp Component to add to the top box
125     */
126    protected void addToTopBox(Component comp) {
127        topBox.add(Box.createHorizontalStrut(topStrutWidth), topBoxIndex);
128        ++topBoxIndex;
129        topBox.add(comp, topBoxIndex);
130        ++topBoxIndex;
131    }
132
133    @Override
134    public void dispose() {
135        if (dataModel != null) {
136            dataModel.dispose();
137        }
138        dataModel = null;
139        dataTable = null;
140        dataScroll = null;
141        super.dispose();
142    }
143
144}