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