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