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