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