001package jmri.jmrit.operations.routes.gui; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.util.List; 006 007import javax.swing.*; 008import javax.swing.table.TableCellEditor; 009import javax.swing.table.TableColumnModel; 010 011import jmri.InstanceManager; 012import jmri.jmrit.operations.locations.LocationManager; 013import jmri.jmrit.operations.routes.*; 014import jmri.jmrit.operations.setup.Control; 015import jmri.jmrit.operations.setup.Setup; 016import jmri.util.table.ButtonEditor; 017import jmri.util.table.ButtonRenderer; 018 019/** 020 * Table Model for edit of routes used by operations 021 * 022 * @author Daniel Boudreau Copyright (C) 2008, 2015 023 */ 024public class RoutesTableModel extends javax.swing.table.AbstractTableModel implements PropertyChangeListener { 025 026 RouteManager routemanager; // There is only one manager 027 028 // Defines the columns 029 public static final int ID_COLUMN = 0; 030 public static final int NAME_COLUMN = ID_COLUMN + 1; 031 public static final int COMMENT_COLUMN = NAME_COLUMN + 1; 032 public static final int DEPARTS_COLUMN = COMMENT_COLUMN + 1; 033 public static final int TIME_COLUMN = DEPARTS_COLUMN + 1; 034 public static final int MIN_LENGTH_COLUMN = TIME_COLUMN + 1; 035 public static final int MAX_LENGTH_COLUMN = MIN_LENGTH_COLUMN + 1; 036 public static final int STATUS_COLUMN = MAX_LENGTH_COLUMN + 1; 037 public static final int EDIT_COLUMN = STATUS_COLUMN + 1; 038 039 private static final int HIGHESTCOLUMN = EDIT_COLUMN + 1; 040 041 public RoutesTableModel() { 042 super(); 043 Setup.getDefault().addPropertyChangeListener(this); 044 routemanager = InstanceManager.getDefault(RouteManager.class); 045 routemanager.addPropertyChangeListener(this); 046 InstanceManager.getDefault(LocationManager.class).addPropertyChangeListener(this); 047 updateList(); 048 } 049 050 public final int SORTBYNAME = 1; 051 public final int SORTBYID = 2; 052 053 private int _sort = SORTBYNAME; 054 055 public void setSort(int sort) { 056 _sort = sort; 057 updateList(); 058 fireTableDataChanged(); 059 } 060 061 private void updateList() { 062 // first, remove listeners from the individual objects 063 removePropertyChangeRoutes(); 064 065 if (_sort == SORTBYID) { 066 sysList = routemanager.getRoutesByIdList(); 067 } else { 068 sysList = routemanager.getRoutesByNameList(); 069 } 070 // and add them back in 071 for (Route route : sysList) { 072 route.addPropertyChangeListener(this); 073 } 074 } 075 076 List<Route> sysList = null; 077 078 void initTable(RoutesTableFrame frame, JTable table) { 079 // Install the button handlers 080 TableColumnModel tcm = table.getColumnModel(); 081 ButtonRenderer buttonRenderer = new ButtonRenderer(); 082 TableCellEditor buttonEditor = new ButtonEditor(new javax.swing.JButton()); 083 tcm.getColumn(EDIT_COLUMN).setCellRenderer(buttonRenderer); 084 tcm.getColumn(EDIT_COLUMN).setCellEditor(buttonEditor); 085 086 // set column preferred widths 087 table.getColumnModel().getColumn(ID_COLUMN).setPreferredWidth(30); 088 table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(220); 089 table.getColumnModel().getColumn(COMMENT_COLUMN).setPreferredWidth(380); 090 table.getColumnModel().getColumn(STATUS_COLUMN).setPreferredWidth(70); 091 table.getColumnModel().getColumn(DEPARTS_COLUMN).setPreferredWidth(75); 092 table.getColumnModel().getColumn(TIME_COLUMN).setPreferredWidth(60); 093 table.getColumnModel().getColumn(MIN_LENGTH_COLUMN).setPreferredWidth(75); 094 table.getColumnModel().getColumn(MAX_LENGTH_COLUMN).setPreferredWidth(75); 095 table.getColumnModel().getColumn(EDIT_COLUMN).setPreferredWidth(80); 096 097 frame.loadTableDetails(table); 098 } 099 100 @Override 101 public int getRowCount() { 102 return sysList.size(); 103 } 104 105 @Override 106 public int getColumnCount() { 107 return HIGHESTCOLUMN; 108 } 109 110 @Override 111 public String getColumnName(int col) { 112 switch (col) { 113 case ID_COLUMN: 114 return Bundle.getMessage("Id"); 115 case NAME_COLUMN: 116 return Bundle.getMessage("Name"); 117 case COMMENT_COLUMN: 118 return Bundle.getMessage("Comment"); 119 case DEPARTS_COLUMN: 120 return Bundle.getMessage("DepartsDirection"); 121 case TIME_COLUMN: 122 return Bundle.getMessage("Time"); 123 case MIN_LENGTH_COLUMN: 124 return Bundle.getMessage("MinLength"); 125 case MAX_LENGTH_COLUMN: 126 return Bundle.getMessage("MaxLength"); 127 case STATUS_COLUMN: 128 return Bundle.getMessage("Status"); 129 case EDIT_COLUMN: 130 return Bundle.getMessage("ButtonEdit"); // titles above all columns 131 default: 132 return "unknown"; // NOI18N 133 } 134 } 135 136 @Override 137 public Class<?> getColumnClass(int col) { 138 switch (col) { 139 case NAME_COLUMN: 140 case COMMENT_COLUMN: 141 case DEPARTS_COLUMN: 142 case TIME_COLUMN: 143 case STATUS_COLUMN: 144 return String.class; 145 case ID_COLUMN: 146 case MIN_LENGTH_COLUMN: 147 case MAX_LENGTH_COLUMN: 148 return Integer.class; 149 case EDIT_COLUMN: 150 return JButton.class; 151 default: 152 return null; 153 } 154 } 155 156 @Override 157 public boolean isCellEditable(int row, int col) { 158 switch (col) { 159 case EDIT_COLUMN: 160 return true; 161 default: 162 return false; 163 } 164 } 165 166 @Override 167 public Object getValueAt(int row, int col) { 168 if (row >= getRowCount()) { 169 return "ERROR unknown " + row; // NOI18N 170 } 171 Route route = sysList.get(row); 172 if (route == null) { 173 return "ERROR route unknown " + row; // NOI18N 174 } 175 switch (col) { 176 case ID_COLUMN: 177 return Integer.parseInt(route.getId()); 178 case NAME_COLUMN: 179 return route.getName(); 180 case COMMENT_COLUMN: 181 return route.getComment(); 182 case DEPARTS_COLUMN: 183 return route.getDepartureDirection(); 184 case TIME_COLUMN: 185 return getTime(route); 186 case MIN_LENGTH_COLUMN: 187 return route.getRouteMinimumTrainLength(); 188 case MAX_LENGTH_COLUMN: 189 return route.getRouteMaximumTrainLength(); 190 case STATUS_COLUMN: 191 return route.getStatus(); 192 case EDIT_COLUMN: 193 return Bundle.getMessage("ButtonEdit"); 194 default: 195 return "unknown " + col; // NOI18N 196 } 197 } 198 199 @Override 200 public void setValueAt(Object value, int row, int col) { 201 switch (col) { 202 case EDIT_COLUMN: 203 editRoute(row); 204 break; 205 default: 206 break; 207 } 208 } 209 210 private String getTime(Route route) { 211 if (route.getDepartsRouteLocation() != null && 212 !route.getDepartsRouteLocation().getDepartureTimeHourMinutes().equals(RouteLocation.NONE)) { 213 return route.getDepartsRouteLocation().getFormatedDepartureTime(); 214 } 215 // check to see if there's a departure time anywhere in the route 216 for (RouteLocation rl : route.getLocationsBySequenceList()) { 217 if (!rl.getDepartureTimeHourMinutes().equals(RouteLocation.NONE)) { 218 return Bundle.getMessage("ButtonYes"); 219 } 220 } 221 return ""; 222 } 223 224 RouteEditFrame ref = null; 225 protected static final String NEW_LINE = "\n"; // NOI18N 226 227 private void editRoute(int row) { 228 log.debug("Edit route"); 229 if (ref != null) { 230 ref.dispose(); 231 } 232 // use invokeLater so new window appears on top 233 SwingUtilities.invokeLater(() -> { 234 ref = new RouteEditFrame(); 235 ref.initComponents(sysList.get(row)); 236 }); 237 } 238 239 @Override 240 public void propertyChange(PropertyChangeEvent e) { 241 if (Control.SHOW_PROPERTY) { 242 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e 243 .getNewValue()); 244 } 245 if (e.getPropertyName().equals(LocationManager.LISTLENGTH_CHANGED_PROPERTY) || 246 e.getPropertyName().equals(Setup.TRAIN_DIRECTION_PROPERTY_CHANGE)) { 247 fireTableDataChanged(); 248 } else if (e.getPropertyName().equals(RouteManager.LISTLENGTH_CHANGED_PROPERTY)) { 249 updateList(); 250 fireTableDataChanged(); 251 } else if (e.getSource().getClass().equals(Route.class)) { 252 Route route = (Route) e.getSource(); 253 int row = sysList.indexOf(route); 254 if (Control.SHOW_PROPERTY) { 255 log.debug("Update route table row: {} id: {}", row, route.getId()); 256 } 257 if (row >= 0) { 258 fireTableRowsUpdated(row, row); 259 } 260 } 261 } 262 263 private void removePropertyChangeRoutes() { 264 if (sysList != null) { 265 for (Route route : sysList) { 266 route.removePropertyChangeListener(this); 267 } 268 } 269 } 270 271 public void dispose() { 272 if (ref != null) { 273 ref.dispose(); 274 } 275 Setup.getDefault().removePropertyChangeListener(this); 276 routemanager.removePropertyChangeListener(this); 277 InstanceManager.getDefault(LocationManager.class).removePropertyChangeListener(this); 278 removePropertyChangeRoutes(); 279 } 280 281 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(RoutesTableModel.class); 282}