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}