001package jmri.jmrit.display.layoutEditor.blockRoutingTable;
002
003import javax.swing.BoxLayout;
004import javax.swing.JLabel;
005import javax.swing.JPanel;
006import javax.swing.JScrollPane;
007import javax.swing.JSplitPane;
008import javax.swing.JTable;
009import javax.swing.ListSelectionModel;
010import javax.swing.SortOrder;
011import javax.swing.table.TableModel;
012import javax.swing.table.TableRowSorter;
013import jmri.jmrit.display.layoutEditor.LayoutBlock;
014import jmri.swing.RowSorterUtil;
015
016/**
017 * Provide a table of block route entries as a JmriJPanel
018 *
019 * @author Kevin Dickerson Copyright (C) 2011
020 */
021public class LayoutBlockRouteTable extends jmri.util.swing.JmriPanel {
022
023    private LayoutBlockRouteTableModel dataModel;
024    private LayoutBlockNeighbourTableModel neighbourDataModel;
025    private TableRowSorter<LayoutBlockNeighbourTableModel> neighbourSorter;
026    private JTable neighbourDataTable;
027    private JScrollPane neighbourDataScroll;
028    private final TableRowSorter<LayoutBlockRouteTableModel> sorter;
029    private JTable dataTable;
030    private JScrollPane dataScroll;
031
032    private final LayoutBlockThroughPathsTableModel throughPathsDataModel;
033    private final TableRowSorter<LayoutBlockThroughPathsTableModel> throughPathsSorter;
034    private final JTable throughPathsDataTable;
035    private final JScrollPane throughPathsDataScroll;
036
037    public LayoutBlockRouteTable(boolean editable, LayoutBlock block) {
038        super();
039
040        //This could do with being presented in a JSplit Panel
041        dataModel = new LayoutBlockRouteTableModel(editable, block);
042        sorter = new TableRowSorter<>(dataModel);
043        dataTable = new JTable(dataModel);
044        dataTable.setRowSorter(sorter);
045        dataScroll = new JScrollPane(dataTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
046
047        neighbourDataModel = new LayoutBlockNeighbourTableModel(editable, block);
048        neighbourSorter = new TableRowSorter<>(neighbourDataModel);
049        neighbourDataTable = new JTable(neighbourDataModel);
050        neighbourDataTable.setRowSorter(neighbourSorter);
051        neighbourDataScroll = new JScrollPane(neighbourDataTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
052
053        throughPathsDataModel = new LayoutBlockThroughPathsTableModel(editable, block);
054        throughPathsSorter = new TableRowSorter<>(throughPathsDataModel);
055        throughPathsDataTable = new JTable(throughPathsDataModel);
056        throughPathsDataTable.setRowSorter(throughPathsSorter);
057        throughPathsDataScroll = new JScrollPane(throughPathsDataTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
058
059        // set initial sort
060        RowSorterUtil.setSortOrder(sorter, LayoutBlockRouteTableModel.HOPCOUNTCOL, SortOrder.ASCENDING);
061        RowSorterUtil.setSortOrder(this.neighbourSorter, LayoutBlockNeighbourTableModel.NEIGHBOURCOL, SortOrder.ASCENDING);
062        RowSorterUtil.setSortOrder(this.throughPathsSorter, LayoutBlockThroughPathsTableModel.SOURCECOL, SortOrder.ASCENDING);
063
064        // allow reordering of the columns
065        dataTable.getTableHeader().setReorderingAllowed(true);
066        neighbourDataTable.getTableHeader().setReorderingAllowed(true);
067        throughPathsDataTable.getTableHeader().setReorderingAllowed(true);
068
069        // have to shut off autoResizeMode to get horizontal scroll to work (JavaSwing p 541)
070        dataTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
071        neighbourDataTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
072        throughPathsDataTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
073
074        // general GUI config
075        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
076
077        // - - - Configure data table - - -
078        // resize columns as requested
079        for (int i = 0; i < dataTable.getColumnCount(); i++) {
080            int width = dataModel.getPreferredWidth(i);
081            dataTable.getColumnModel().getColumn(i).setPreferredWidth(width);
082        }
083        dataTable.sizeColumnsToFit(-1);
084
085        // set Viewport preferred size from size of table
086        java.awt.Dimension dataTableSize = dataTable.getPreferredSize();
087        // set minimum Viewport size
088        dataTableSize.height = Math.max(dataTableSize.height, 400);
089        dataTableSize.width = Math.max(dataTableSize.width, 400);
090        dataScroll.getViewport().setPreferredSize(dataTableSize);
091
092        // set preferred scrolling options
093//        dataScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
094//        dataScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
095        // set to single selection
096        dataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
097
098        // - - - Configure neighbor table - - -
099        // resize columns as requested
100        for (int i = 0; i < neighbourDataTable.getColumnCount(); i++) {
101            int width = neighbourDataModel.getPreferredWidth(i);
102            neighbourDataTable.getColumnModel().getColumn(i).setPreferredWidth(width);
103        }
104        neighbourDataTable.sizeColumnsToFit(-1);
105
106        // set Viewport preferred size from size of table
107        java.awt.Dimension neighbourDataTableSize = neighbourDataTable.getPreferredSize();
108        // set minimum Viewport size
109        neighbourDataTableSize.height = Math.max(neighbourDataTableSize.height, 400);
110        neighbourDataTableSize.width = Math.max(neighbourDataTableSize.width, 400);
111        neighbourDataScroll.getViewport().setPreferredSize(neighbourDataTableSize);
112
113        // set preferred scrolling options
114        neighbourDataScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
115        neighbourDataScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
116
117        // set to single selection
118        neighbourDataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
119
120        // - - - Configure through paths table - - -
121        // resize columns as requested
122        for (int i = 0; i < throughPathsDataTable.getColumnCount(); i++) {
123            int width = throughPathsDataModel.getPreferredWidth(i);
124            throughPathsDataTable.getColumnModel().getColumn(i).setPreferredWidth(width);
125        }
126        throughPathsDataTable.sizeColumnsToFit(-1);
127
128        // set Viewport preferred size from size of table
129        java.awt.Dimension throughPathsDataTableSize = throughPathsDataTable.getPreferredSize();
130        // set minimum Viewport size
131        throughPathsDataTableSize.height = Math.max(throughPathsDataTableSize.height, 400);
132        throughPathsDataTableSize.width = Math.max(throughPathsDataTableSize.width, 400);
133        throughPathsDataScroll.getViewport().setPreferredSize(throughPathsDataTableSize);
134
135        // set preferred scrolling options
136        throughPathsDataScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
137        throughPathsDataScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
138
139        // set to single selection
140        throughPathsDataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
141
142        JPanel neigh = new JPanel();
143        neigh.setLayout(new BoxLayout(neigh, BoxLayout.Y_AXIS));
144        neigh.add(new JLabel(Bundle.getMessage("Neighbouring")));
145        neigh.add(neighbourDataScroll);
146
147        JPanel through = new JPanel();
148        through.setLayout(new BoxLayout(through, BoxLayout.Y_AXIS));
149        through.add(new JLabel(Bundle.getMessage("ValidPaths")));
150        through.add(throughPathsDataScroll);
151
152        JPanel routePane = new JPanel();
153        routePane.setLayout(new BoxLayout(routePane, BoxLayout.Y_AXIS));
154        routePane.add(new JLabel(Bundle.getMessage("Accessible")));
155        routePane.add(dataScroll);
156
157        JSplitPane splitTopPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
158                neigh, through);
159        splitTopPane.setOneTouchExpandable(true);
160        splitTopPane.setDividerLocation(150);
161        JSplitPane splitBotPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
162                splitTopPane, routePane);
163        splitBotPane.setOneTouchExpandable(true);
164        splitBotPane.setDividerLocation(300);
165        add(splitBotPane);
166
167    }
168
169    public JTable getTable() {
170        return dataTable;
171    }
172
173    public TableModel getModel() {
174        return this.dataModel;
175    }
176
177    public JTable getNeighbourTable() {
178        return neighbourDataTable;
179    }
180
181    public TableModel getNeighbourModel() {
182        return this.neighbourDataModel;
183    }
184
185    @Override
186    public void dispose() {
187        if (dataModel != null) {
188            dataModel.dispose();
189        }
190        dataModel = null;
191        dataTable = null;
192        dataScroll = null;
193        neighbourDataModel = null;
194        neighbourSorter = null;
195        neighbourDataTable = null;
196        neighbourDataScroll = null;
197
198        super.dispose();
199    }
200}