001package jmri.jmrit.beantable; 002 003import javax.annotation.Nonnull; 004import javax.swing.*; 005 006import jmri.*; 007import jmri.jmrit.beantable.routetable.RouteEditFrame; 008import jmri.util.JmriJFrame; 009import jmri.util.swing.JmriJOptionPane; 010 011/** 012 * TableDataModel for the Route Table. 013 * 014 * Split from {@link RouteTableAction} 015 * 016 * @author Dave Duchamp Copyright (C) 2004 017 * @author Bob Jacobsen Copyright (C) 2007 018 * @author Simon Reader Copyright (C) 2008 019 * @author Pete Cressman Copyright (C) 2009 020 * @author Egbert Broerse Copyright (C) 2016 021 * @author Paul Bender Colyright (C) 2020 022 */ 023public class RouteTableDataModel extends BeanTableDataModel<Route> { 024 025 private static final int ENABLECOL = NUMCOLUMN; 026 private static final int LOCKCOL = ENABLECOL + 1; 027 private static final int SETCOL = ENABLECOL + 2; 028 029 @Override 030 public int getColumnCount() { 031 return NUMCOLUMN + 3; 032 } 033 034 @Override 035 public String getColumnName(int col) { 036 switch (col) { 037 case VALUECOL: // no heading on "Edit" 038 case SETCOL: // no heading on "Set" 039 return ""; 040 case ENABLECOL: 041 return Bundle.getMessage("ColumnHeadEnabled"); 042 case LOCKCOL: 043 return Bundle.getMessage("Locked"); 044 default: 045 return super.getColumnName(col); 046 } 047 } 048 049 @Override 050 public Class<?> getColumnClass(int col) { 051 switch (col) { 052 case SETCOL: 053 return JButton.class; 054 case ENABLECOL: 055 case LOCKCOL: 056 return Boolean.class; 057 default: 058 return super.getColumnClass(col); 059 } 060 } 061 062 @Override 063 public int getPreferredWidth(int col) { 064 switch (col) { 065 case SETCOL: 066 case ENABLECOL: 067 case LOCKCOL: 068 return new JTextField(6).getPreferredSize().width; 069 default: 070 return super.getPreferredWidth(col); 071 } 072 } 073 074 @Override 075 public boolean isCellEditable(int row, int col) { 076 switch (col) { 077 case USERNAMECOL: 078 case SETCOL: 079 case ENABLECOL: 080 return true; 081 case LOCKCOL: // Route lock is available if turnouts are lockable 082 return ((Route) getValueAt(row, SYSNAMECOL)).canLock(); 083 default: 084 return super.isCellEditable(row, col); 085 } 086 } 087 088 @Override 089 public Object getValueAt(int row, int col) { 090 switch (col) { 091 case SETCOL: 092 return Bundle.getMessage("ButtonEdit"); 093 case ENABLECOL: 094 return ((Route) getValueAt(row, SYSNAMECOL)).getEnabled(); 095 case LOCKCOL: 096 Route r = (Route) getValueAt(row, SYSNAMECOL); 097 if (r.canLock()) { 098 return r.getLocked(); 099 } else { 100 // this covers the case when route was locked and lockable turnouts were removed from the route 101 r.setLocked(false); 102 return false; 103 } 104 default: 105 return super.getValueAt(row, col); 106 } 107 } 108 109 @Override 110 public void setValueAt(Object value, int row, int col) { 111 switch (col) { 112 case USERNAMECOL: 113 // Directly changing the username should only be possible if the username was previously null or "" 114 // check to see if user name already exists 115 if (value.equals("")) { 116 value = null; 117 } else { 118 Route nB = getByUserName((String) value); 119 if (nB != null) { 120 log.error("User Name is not unique {}", value); 121 String msg; 122 msg = Bundle.getMessage("WarningUserName", ("" + value)); 123 JmriJOptionPane.showMessageDialog(null, msg, Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 124 return; 125 } 126 } 127 Route nBean = getBySystemName(sysNameList.get(row)); 128 nBean.setUserName((String) value); 129 fireTableRowsUpdated(row, row); 130 break; 131 case SETCOL: 132 SwingUtilities.invokeLater(() -> { 133 JmriJFrame editFrame = new RouteEditFrame(((Route) getValueAt(row, SYSNAMECOL)).getSystemName()); 134 editFrame.setVisible(true); 135 }); 136 break; 137 case ENABLECOL: { 138 // alternate 139 Route r = (Route) getValueAt(row, SYSNAMECOL); 140 r.setEnabled(!r.getEnabled()); 141 break; 142 } 143 case LOCKCOL: { 144 // alternate 145 Route r = (Route) getValueAt(row, SYSNAMECOL); 146 r.setLocked(!r.getLocked()); 147 break; 148 } 149 default: 150 super.setValueAt(value, row, col); 151 break; 152 } 153 } 154 155 @Override 156 public void configureTable(JTable table) { 157 table.setDefaultRenderer(Boolean.class, new EnablingCheckboxRenderer()); 158 table.setDefaultRenderer(JComboBox.class, new jmri.jmrit.symbolicprog.ValueRenderer()); 159 table.setDefaultEditor(JComboBox.class, new jmri.jmrit.symbolicprog.ValueEditor()); 160 super.configureTable(table); 161 } 162 163 /** 164 * Delete the bean after all the checking has been done. 165 * <p> 166 * Deactivate the Route, then use the superclass to delete it. 167 */ 168 @Override 169 protected void doDelete(Route bean) { 170 bean.deActivateRoute(); 171 super.doDelete(bean); 172 } 173 174 // want to update when enabled parameter changes 175 @Override 176 protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) { 177 switch (e.getPropertyName()) { 178 case "Enabled": // NOI18N 179 case "Locked": // NOI18N 180 return true; 181 default: 182 return super.matchPropertyName(e); 183 } 184 } 185 186 @Override 187 public RouteManager getManager() { 188 return InstanceManager.getDefault(RouteManager.class); 189 } 190 191 @Override 192 public Route getBySystemName(@Nonnull String name) { 193 return InstanceManager.getDefault(RouteManager.class).getBySystemName(name); 194 } 195 196 @Override 197 public Route getByUserName(@Nonnull String name) { 198 return InstanceManager.getDefault(RouteManager.class).getByUserName(name); 199 } 200 201 @Override 202 protected String getMasterClassName() { 203 // Use the RouteTabelAction class to combine messages in Preferences -> Messages 204 return RouteTableAction.class.getName(); 205 } 206 207 @Override 208 public void clickOn(Route t) { 209 t.setRoute(); 210 } 211 212 @Override 213 public String getValue(String s) { 214 return Bundle.getMessage("Set"); 215 //Title of Set button in Route table 216 } 217 218 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(RouteTableDataModel.class); 219 220}