001package jmri.jmrit.operations.rollingstock.engines; 002 003import java.awt.GridBagLayout; 004import java.util.List; 005import java.util.ResourceBundle; 006 007import javax.swing.*; 008 009import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 010import jmri.InstanceManager; 011import jmri.jmrit.operations.rollingstock.*; 012import jmri.jmrit.operations.rollingstock.engines.tools.EngineAttributeEditFrame; 013import jmri.jmrit.operations.setup.Control; 014import jmri.util.swing.JmriJOptionPane; 015 016/** 017 * Frame for user edit of engine 018 * 019 * @author Dan Boudreau Copyright (C) 2008, 2011, 2018 020 */ 021public class EngineEditFrame extends RollingStockEditFrame { 022 023 protected static final ResourceBundle rb = ResourceBundle 024 .getBundle("jmri.jmrit.operations.rollingstock.engines.JmritOperationsEnginesBundle"); 025 026 EngineManager engineManager = InstanceManager.getDefault(EngineManager.class); 027 EngineManagerXml managerXml = InstanceManager.getDefault(EngineManagerXml.class); 028 EngineModels engineModels = InstanceManager.getDefault(EngineModels.class); 029 030 JButton editModelButton = new JButton(Bundle.getMessage("ButtonEdit")); 031 032 JCheckBox bUnitCheckBox = new JCheckBox(Bundle.getMessage("BUnit")); 033 034 JTextField hpTextField = new JTextField(8); 035 JTextField teTextField = new JTextField(8); 036 037 private static final String SPEED = "25"; // MPH for tractive effort to HP conversion 038 039 EngineAttributeEditFrame engineAttributeEditFrame; 040 041 public EngineEditFrame() { 042 super(Bundle.getMessage("TitleEngineAdd")); 043 } 044 045 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Checks for null") 046 @Override 047 public void initComponents() { 048 049 groupComboBox = InstanceManager.getDefault(ConsistManager.class).getComboBox(); 050 modelComboBox = engineModels.getComboBox(); 051 052 super.initComponents(); 053 054 addButton.setText(Bundle.getMessage("TitleEngineAdd")); 055 056 // type options for engines 057 addItem(pTypeOptions, bUnitCheckBox, 0, 1); 058 059 // default check box selections 060 bUnitCheckBox.setSelected(false); 061 062 // load tool tips 063 builtTextField.setToolTipText(Bundle.getMessage("TipBuildDate")); 064 editModelButton.setToolTipText(Bundle.getMessage("TipAddDeleteReplace", 065 Bundle.getMessage("Model").toLowerCase())); 066 editGroupButton.setToolTipText(Bundle.getMessage("TipAddDeleteReplace", 067 Bundle.getMessage("Consist").toLowerCase())); 068 bUnitCheckBox.setToolTipText(Bundle.getMessage("TipBoosterUnit")); 069 070 deleteButton.setToolTipText(Bundle.getMessage("TipDeleteButton")); 071 addButton.setToolTipText(Bundle.getMessage("TipAddButton")); 072 saveButton.setToolTipText(Bundle.getMessage("TipSaveButton")); 073 074 // row 3 075 pModel.setLayout(new GridBagLayout()); 076 pModel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Model"))); 077 addItem(pModel, modelComboBox, 1, 0); 078 addItem(pModel, editModelButton, 2, 0); 079 pModel.setVisible(true); 080 081 // row 12 082 pPower.setLayout(new BoxLayout(pPower, BoxLayout.X_AXIS)); 083 JPanel pHp = new JPanel(); 084 pHp.setLayout(new GridBagLayout()); 085 pHp.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Hp"))); 086 addItem(pHp, hpTextField, 0, 0); 087 JPanel pTe = new JPanel(); 088 pTe.setLayout(new GridBagLayout()); 089 pTe.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TractiveEffort"))); 090 addItem(pTe, teTextField, 0, 0); 091 pPower.add(pHp); 092 pPower.add(pTe); 093 pPower.setVisible(true); 094 095 teTextField.setToolTipText(Bundle.getMessage("TipConvertTE-HP", SPEED)); 096 097 pGroup.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Consist"))); 098 099 addEditButtonAction(editModelButton); 100 101 addComboBoxAction(modelComboBox); 102 modelComboBox.setSelectedIndex(0); 103 104 addHelpMenu("package.jmri.jmrit.operations.Operations_LocomotivesAdd", true); // NOI18N 105 } 106 107 @Override 108 protected ResourceBundle getRb() { 109 return rb; 110 } 111 112 @Override 113 protected RollingStockAttribute getTypeManager() { 114 return InstanceManager.getDefault(EngineTypes.class); 115 } 116 117 @Override 118 protected RollingStockAttribute getLengthManager() { 119 return InstanceManager.getDefault(EngineLengths.class); 120 } 121 122 public void load(Engine engine) { 123 setTitle(Bundle.getMessage("TitleEngineEdit")); 124 125 if (!engineModels.containsName(engine.getModel())) { 126 String msg = Bundle.getMessage("modelNameNotExist", 127 engine.getModel()); 128 if (JmriJOptionPane.showConfirmDialog(this, msg, Bundle.getMessage("engineAddModel"), 129 JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) { 130 engineModels.addName(engine.getModel()); 131 } 132 } 133 modelComboBox.setSelectedItem(engine.getModel()); 134 135 super.load(engine); 136 137 pBlocking.setVisible(engine.getConsist() != null); 138 blockingTextField.setEnabled(false); // don't allow user to modify, only see 139 bUnitCheckBox.setSelected(engine.isBunit()); 140 hpTextField.setText(engine.getHp()); 141 groupComboBox.setSelectedItem(engine.getConsistName()); 142 } 143 144 // combo boxes 145 @Override 146 public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) { 147 if (ae.getSource() == modelComboBox) { 148 if (modelComboBox.getSelectedItem() != null) { 149 String model = (String) modelComboBox.getSelectedItem(); 150 // load the default hp and length for the model selected 151 hpTextField.setText(engineModels.getModelHorsepower(model)); 152 weightTonsTextField.setText(engineModels.getModelWeight(model)); 153 if (engineModels.getModelLength(model) != null && !engineModels.getModelLength(model).isEmpty()) { 154 lengthComboBox.setSelectedItem(engineModels.getModelLength(model)); 155 } 156 if (engineModels.getModelType(model) != null && !engineModels.getModelType(model).isEmpty()) { 157 typeComboBox.setSelectedItem(engineModels.getModelType(model)); 158 } 159 } 160 } 161 super.comboBoxActionPerformed(ae); 162 } 163 164 @Override 165 protected boolean check(RollingStock engine) { 166 // check to see if engine with road and number already exists 167 Engine existingEngine = engineManager.getByRoadAndNumber((String) roadComboBox.getSelectedItem(), 168 roadNumberTextField.getText()); 169 if (existingEngine != null) { 170 if (engine == null || !existingEngine.getId().equals(engine.getId())) { 171 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("engineExists"), 172 Bundle.getMessage("engineCanNotUpdate"), JmriJOptionPane.ERROR_MESSAGE); 173 return false; 174 } 175 } 176 return super.check(engine); 177 } 178 179 @Override 180 protected void save(boolean isSave) { 181 super.save(engineManager, isSave); 182 Engine engine = (Engine) _rs; 183 184 checkAndSetLocationAndTrack(engine); 185 186 engine.setBunit(bUnitCheckBox.isSelected()); 187 188 if (groupComboBox.getSelectedItem() != null) { 189 if (groupComboBox.getSelectedItem().equals(EngineManager.NONE)) { 190 engine.setConsist(null); 191 engine.setBlocking(Engine.DEFAULT_BLOCKING_ORDER); 192 } else if (!engine.getConsistName().equals(groupComboBox.getSelectedItem())) { 193 engine.setConsist(InstanceManager.getDefault(ConsistManager.class).getConsistByName((String) groupComboBox.getSelectedItem())); 194 if (engine.getConsist() != null) { 195 engine.setBlocking(engine.getConsist().getSize()); 196 blockingTextField.setText(Integer.toString(engine.getBlocking())); 197 } 198 } 199 } 200 pBlocking.setVisible(engine.getConsist() != null); 201 202 convertTractiveEffortToHp(); 203 // confirm that horsepower is a number 204 if (!hpTextField.getText().trim().isEmpty()) { 205 try { 206 Integer.parseInt(hpTextField.getText()); 207 engine.setHp(hpTextField.getText()); 208 } catch (Exception e) { 209 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("engineHorsepower"), 210 Bundle.getMessage("engineCanNotHp"), JmriJOptionPane.ERROR_MESSAGE); 211 } 212 } 213 214 // is this engine part of a consist? Ask if all engines should have the same location and track 215 if (engine.getConsist() != null) { 216 List<Engine> engines = engine.getConsist().getEngines(); 217 for (Engine cEngine : engines) { 218 if (cEngine != engine) { 219 if (cEngine.getLocation() != engine.getLocation() || cEngine.getTrack() != engine.getTrack()) { 220 int results = JmriJOptionPane.showConfirmDialog(this, Bundle 221 .getMessage("engineInConsistLocation", 222 engine.toString(), engine.getLocationName(), engine.getTrackName()), 223 Bundle.getMessage("enginePartConsist"), 224 JmriJOptionPane.YES_NO_OPTION); 225 if (results == JmriJOptionPane.YES_OPTION) { 226 // change the location for all engines in consist 227 for (Engine cEngine2 : engines) { 228 if (cEngine2 != engine) { 229 setLocationAndTrack(cEngine2); 230 } 231 } 232 } 233 break; // done 234 } 235 } 236 } 237 } 238 } 239 240 @Override 241 protected void delete() { 242 Engine engine = engineManager.getByRoadAndNumber((String) roadComboBox.getSelectedItem(), 243 roadNumberTextField.getText()); 244 if (engine != null) { 245 engineManager.deregister(engine); 246 } 247 } 248 249 // edit buttons only one frame active at a time 250 @Override 251 public void buttonEditActionPerformed(java.awt.event.ActionEvent ae) { 252 if (engineAttributeEditFrame != null) { 253 engineAttributeEditFrame.dispose(); 254 } 255 engineAttributeEditFrame = new EngineAttributeEditFrame(); 256 engineAttributeEditFrame.setLocationRelativeTo(this); 257 engineAttributeEditFrame.addPropertyChangeListener(this); 258 259 if (ae.getSource() == editRoadButton) { 260 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.ROAD, 261 (String) roadComboBox.getSelectedItem()); 262 } 263 if (ae.getSource() == editModelButton) { 264 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.MODEL, 265 (String) modelComboBox.getSelectedItem()); 266 } 267 if (ae.getSource() == editTypeButton) { 268 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.TYPE, 269 (String) typeComboBox.getSelectedItem()); 270 } 271 if (ae.getSource() == editLengthButton) { 272 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.LENGTH, 273 (String) lengthComboBox.getSelectedItem()); 274 } 275 if (ae.getSource() == editOwnerButton) { 276 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.OWNER, 277 (String) ownerComboBox.getSelectedItem()); 278 } 279 if (ae.getSource() == editGroupButton) { 280 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.CONSIST, 281 (String) groupComboBox.getSelectedItem()); 282 } 283 } 284 285 /** 286 * Converts tractive effort to HP using the formula: HP = TE * MPH / 375. MPH 287 * set at 25, see SPEED. 60% conversion efficiency to produce reasonable HP values. 288 */ 289 private void convertTractiveEffortToHp() { 290 String TE = teTextField.getText().trim(); 291 if (!TE.isEmpty()) { 292 TE = TE.replace(",", ""); 293 int te = 0; 294 try { 295 te = Integer.parseInt(TE); 296 } catch (Exception e) { 297 log.error("Not able to convert TE {} to HP", teTextField.getText()); 298 } 299 if (te > 0) { 300 int hp = te * Integer.parseInt(SPEED) / 625; 301 hpTextField.setText(Integer.toString(hp)); 302 } 303 } 304 } 305 306 @Override 307 protected void addPropertyChangeListeners() { 308 InstanceManager.getDefault(ConsistManager.class).addPropertyChangeListener(this); 309 engineModels.addPropertyChangeListener(this); 310 engineManager.addPropertyChangeListener(this); 311 super.addPropertyChangeListeners(); 312 } 313 314 @Override 315 protected void removePropertyChangeListeners() { 316 InstanceManager.getDefault(ConsistManager.class).removePropertyChangeListener(this); 317 engineModels.removePropertyChangeListener(this); 318 engineManager.removePropertyChangeListener(this); 319 if (_rs != null) { 320 _rs.removePropertyChangeListener(this); 321 } 322 super.removePropertyChangeListeners(); 323 } 324 325 @Override 326 public void propertyChange(java.beans.PropertyChangeEvent e) { 327 if (Control.SHOW_PROPERTY) { 328 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 329 e.getNewValue()); 330 } 331 super.propertyChange(e); 332 333 if (e.getPropertyName().equals(EngineLengths.ENGINELENGTHS_CHANGED_PROPERTY)) { 334 InstanceManager.getDefault(EngineLengths.class).updateComboBox(lengthComboBox); 335 if (_rs != null) { 336 lengthComboBox.setSelectedItem(_rs.getLength()); 337 } 338 } 339 if (e.getPropertyName().equals(EngineModels.ENGINEMODELS_CHANGED_PROPERTY)) { 340 engineModels.updateComboBox(modelComboBox); 341 if (_rs != null) { 342 modelComboBox.setSelectedItem(((Engine) _rs).getModel()); 343 } 344 } 345 if (e.getPropertyName().equals(ConsistManager.LISTLENGTH_CHANGED_PROPERTY)) { 346 InstanceManager.getDefault(ConsistManager.class).updateComboBox(groupComboBox); 347 if (_rs != null) { 348 groupComboBox.setSelectedItem(((Engine) _rs).getConsistName()); 349 } 350 } 351 if (e.getPropertyName().equals(EngineAttributeEditFrame.DISPOSE)) { 352 engineAttributeEditFrame = null; 353 } 354 } 355 356 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(EngineEditFrame.class); 357 358}