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