001package jmri.jmrit.operations.locations.tools; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.util.ArrayList; 006import java.util.List; 007import javax.swing.JButton; 008import javax.swing.JComboBox; 009import javax.swing.JTable; 010import javax.swing.table.AbstractTableModel; 011import javax.swing.table.TableCellEditor; 012import jmri.jmrit.operations.locations.Location; 013import jmri.jmrit.operations.locations.Track; 014import jmri.jmrit.operations.setup.Control; 015import jmri.util.swing.XTableColumnModel; 016import jmri.util.table.ButtonEditor; 017import jmri.util.table.ButtonRenderer; 018import org.slf4j.Logger; 019import org.slf4j.LoggerFactory; 020 021/** 022 * Table Model for edit of tracks used by operations 023 * 024 * @author Daniel Boudreau Copyright (C) 2015 025 */ 026public class LocationTrackBlockingOrderTableModel extends AbstractTableModel implements PropertyChangeListener { 027 028 protected Location _location; 029 protected List<Track> _tracksList = new ArrayList<Track>(); 030 protected JTable _table; 031 032 // Defines the columns 033 protected static final int ID_COLUMN = 0; 034 protected static final int NAME_COLUMN = 1; 035 protected static final int TYPE_COLUMN = 2; 036 protected static final int ORDER_COLUMN = 3; 037 protected static final int UP_COLUMN = 4; 038 protected static final int DOWN_COLUMN = 5; 039 040 protected static final int HIGHESTCOLUMN = DOWN_COLUMN + 1; 041 042 public LocationTrackBlockingOrderTableModel() { 043 super(); 044 } 045 046 private void updateList() { 047 if (_location == null) { 048 return; 049 } 050 // first, remove listeners from the individual objects 051 removePropertyChangeTracks(); 052 053 _tracksList = _location.getTracksByBlockingOrderList(null); 054 // and add them back in 055 for (Track track : _tracksList) { 056 track.addPropertyChangeListener(this); 057 } 058 fireTableDataChanged(); 059 } 060 061 protected void initTable(JTable table, Location location) { 062 _table = table; 063 _location = location; 064 if (_location != null) { 065 _location.addPropertyChangeListener(this); 066 } 067 initTable(); 068 table.setRowHeight(new JComboBox<>().getPreferredSize().height); 069 // have to shut off autoResizeMode to get horizontal scroll to work (JavaSwing p 541) 070 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 071 updateList(); 072 } 073 074 private void initTable() { 075 // Use XTableColumnModel so we can control which columns are visible 076 XTableColumnModel tcm = new XTableColumnModel(); 077 _table.setColumnModel(tcm); 078 _table.createDefaultColumnsFromModel(); 079 080 ButtonRenderer buttonRenderer = new ButtonRenderer(); 081 TableCellEditor buttonEditor = new ButtonEditor(new javax.swing.JButton()); 082 tcm.getColumn(UP_COLUMN).setCellRenderer(buttonRenderer); 083 tcm.getColumn(UP_COLUMN).setCellEditor(buttonEditor); 084 tcm.getColumn(DOWN_COLUMN).setCellRenderer(buttonRenderer); 085 tcm.getColumn(DOWN_COLUMN).setCellEditor(buttonEditor); 086 087 // set column preferred widths 088 tcm.getColumn(ID_COLUMN).setPreferredWidth(40); 089 tcm.getColumn(NAME_COLUMN).setPreferredWidth(200); 090 tcm.getColumn(TYPE_COLUMN).setPreferredWidth(80); 091 tcm.getColumn(ORDER_COLUMN).setPreferredWidth(60); 092 tcm.getColumn(UP_COLUMN).setPreferredWidth(60); 093 tcm.getColumn(DOWN_COLUMN).setPreferredWidth(70); 094 } 095 096 @Override 097 public int getRowCount() { 098 return _tracksList.size(); 099 } 100 101 @Override 102 public int getColumnCount() { 103 return HIGHESTCOLUMN; 104 } 105 106 @Override 107 public String getColumnName(int col) { 108 switch (col) { 109 case ID_COLUMN: 110 return Bundle.getMessage("Id"); 111 case NAME_COLUMN: 112 return Bundle.getMessage("TrackName"); 113 case TYPE_COLUMN: 114 return Bundle.getMessage("Type"); 115 case ORDER_COLUMN: 116 return Bundle.getMessage("ServiceOrder"); 117 case UP_COLUMN: 118 return Bundle.getMessage("Up"); 119 case DOWN_COLUMN: 120 return Bundle.getMessage("Down"); 121 default: 122 return "unknown"; // NOI18N 123 } 124 } 125 126 @Override 127 public Class<?> getColumnClass(int col) { 128 switch (col) { 129 case ID_COLUMN: 130 return String.class; 131 case NAME_COLUMN: 132 return String.class; 133 case TYPE_COLUMN: 134 return String.class; 135 case ORDER_COLUMN: 136 return Integer.class; 137 case UP_COLUMN: 138 return JButton.class; 139 case DOWN_COLUMN: 140 return JButton.class; 141 default: 142 return null; 143 } 144 } 145 146 @Override 147 public boolean isCellEditable(int row, int col) { 148 switch (col) { 149 case ORDER_COLUMN: 150 case UP_COLUMN: 151 case DOWN_COLUMN: 152 return true; 153 default: 154 return false; 155 } 156 } 157 158 @Override 159 public Object getValueAt(int row, int col) { 160 if (row >= getRowCount()) { 161 return "ERROR row " + row; // NOI18N 162 } 163 Track track = _tracksList.get(row); 164 if (track == null) { 165 return "ERROR track unknown " + row; // NOI18N 166 } 167 switch (col) { 168 case ID_COLUMN: 169 return track.getId(); 170 case NAME_COLUMN: 171 return track.getName(); 172 case TYPE_COLUMN: 173 return track.getTrackTypeName(); 174 case ORDER_COLUMN: 175 return track.getBlockingOrder(); 176 case UP_COLUMN: 177 return Bundle.getMessage("Up"); 178 case DOWN_COLUMN: 179 return Bundle.getMessage("Down"); 180 default: 181 return "unknown " + col; // NOI18N 182 } 183 } 184 185 @Override 186 public void setValueAt(Object value, int row, int col) { 187 if (row >= getRowCount()) { 188 return; 189 } 190 Track track = _tracksList.get(row); 191 if (track == null) { 192 return; // NOI18N 193 } 194 switch (col) { 195 case ORDER_COLUMN: 196 if ((int) value >= 0) 197 track.setBlockingOrder((int) value); 198 break; 199 case UP_COLUMN: 200 _location.changeTrackBlockingOrderEarlier(track); 201 break; 202 case DOWN_COLUMN: 203 _location.changeTrackBlockingOrderLater(track); 204 break; 205 default: 206 break; 207 } 208 } 209 210 // this table listens for changes to a location and its tracks 211 @Override 212 public void propertyChange(PropertyChangeEvent e) { 213 if (Control.SHOW_PROPERTY) 214 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e 215 .getNewValue()); 216 if (e.getPropertyName().equals(Location.TRACK_LISTLENGTH_CHANGED_PROPERTY) || 217 e.getPropertyName().equals(Location.TRACK_BLOCKING_ORDER_CHANGED_PROPERTY)) { 218 updateList(); 219 } 220 if (e.getPropertyName().equals(Track.TRACK_BLOCKING_ORDER_CHANGED_PROPERTY) || 221 e.getPropertyName().equals(Track.NAME_CHANGED_PROPERTY) || 222 e.getPropertyName().equals(Track.TRACK_TYPE_CHANGED_PROPERTY)) { 223 fireTableDataChanged(); 224 } 225 } 226 227 protected void removePropertyChangeTracks() { 228 for (Track track : _tracksList) { 229 track.removePropertyChangeListener(this); 230 } 231 } 232 233 public void dispose() { 234 removePropertyChangeTracks(); 235 if (_location != null) { 236 _location.removePropertyChangeListener(this); 237 } 238 _tracksList.clear(); 239 fireTableDataChanged(); 240 } 241 242 private final static Logger log = LoggerFactory.getLogger(LocationTrackBlockingOrderTableModel.class); 243}