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