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 super.save(engineManager, isSave); 183 Engine engine = (Engine) _rs; 184 185 checkAndSetLocationAndTrack(engine); 186 187 engine.setBunit(bUnitCheckBox.isSelected()); 188 189 if (groupComboBox.getSelectedItem() != null) { 190 if (groupComboBox.getSelectedItem().equals(EngineManager.NONE)) { 191 engine.setConsist(null); 192 engine.setBlocking(Engine.DEFAULT_BLOCKING_ORDER); 193 } else if (!engine.getConsistName().equals(groupComboBox.getSelectedItem())) { 194 engine.setConsist(InstanceManager.getDefault(ConsistManager.class).getConsistByName((String) groupComboBox.getSelectedItem())); 195 if (engine.getConsist() != null) { 196 engine.setBlocking(engine.getConsist().getSize()); 197 blockingTextField.setText(Integer.toString(engine.getBlocking())); 198 } 199 } 200 } 201 pBlocking.setVisible(engine.getConsist() != null); 202 203 convertTractiveEffortToHp(); 204 // confirm that horsepower is a number 205 if (!hpTextField.getText().trim().isEmpty()) { 206 try { 207 Integer.parseInt(hpTextField.getText()); 208 engine.setHp(hpTextField.getText()); 209 } catch (Exception e) { 210 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("engineHorsepower"), 211 Bundle.getMessage("engineCanNotHp"), JmriJOptionPane.ERROR_MESSAGE); 212 } 213 } 214 215 // is this engine part of a consist? Ask if all engines should have the same location and track 216 if (engine.getConsist() != null) { 217 List<Engine> engines = engine.getConsist().getEngines(); 218 for (Engine cEngine : engines) { 219 if (cEngine != engine) { 220 if (cEngine.getLocation() != engine.getLocation() || cEngine.getTrack() != engine.getTrack()) { 221 int results = JmriJOptionPane.showConfirmDialog(this, Bundle 222 .getMessage("engineInConsistLocation", 223 engine.toString(), engine.getLocationName(), engine.getTrackName()), 224 Bundle.getMessage("enginePartConsist"), 225 JmriJOptionPane.YES_NO_OPTION); 226 if (results == JmriJOptionPane.YES_OPTION) { 227 // change the location for all engines in consist 228 for (Engine cEngine2 : engines) { 229 if (cEngine2 != engine) { 230 setLocationAndTrack(cEngine2); 231 } 232 } 233 } 234 break; // done 235 } 236 } 237 } 238 } 239 } 240 241 @Override 242 protected void delete() { 243 Engine engine = engineManager.getByRoadAndNumber((String) roadComboBox.getSelectedItem(), 244 roadNumberTextField.getText()); 245 if (engine != null) { 246 engineManager.deregister(engine); 247 } 248 } 249 250 // edit buttons only one frame active at a time 251 @Override 252 public void buttonEditActionPerformed(java.awt.event.ActionEvent ae) { 253 if (engineAttributeEditFrame != null) { 254 engineAttributeEditFrame.dispose(); 255 } 256 engineAttributeEditFrame = new EngineAttributeEditFrame(); 257 engineAttributeEditFrame.setLocationRelativeTo(this); 258 engineAttributeEditFrame.addPropertyChangeListener(this); 259 260 if (ae.getSource() == editRoadButton) { 261 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.ROAD, 262 (String) roadComboBox.getSelectedItem()); 263 } 264 if (ae.getSource() == editModelButton) { 265 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.MODEL, 266 (String) modelComboBox.getSelectedItem()); 267 } 268 if (ae.getSource() == editTypeButton) { 269 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.TYPE, 270 (String) typeComboBox.getSelectedItem()); 271 } 272 if (ae.getSource() == editLengthButton) { 273 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.LENGTH, 274 (String) lengthComboBox.getSelectedItem()); 275 } 276 if (ae.getSource() == editOwnerButton) { 277 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.OWNER, 278 (String) ownerComboBox.getSelectedItem()); 279 } 280 if (ae.getSource() == editGroupButton) { 281 engineAttributeEditFrame.initComponents(EngineAttributeEditFrame.CONSIST, 282 (String) groupComboBox.getSelectedItem()); 283 } 284 } 285 286 /** 287 * Converts tractive effort to HP using the formula: HP = TE * MPH / 375. MPH 288 * set at 25, see SPEED. 60% conversion efficiency to produce reasonable HP values. 289 */ 290 private void convertTractiveEffortToHp() { 291 String TE = teTextField.getText().trim(); 292 if (!TE.isEmpty()) { 293 TE = TE.replace(",", ""); 294 int te = 0; 295 try { 296 te = Integer.parseInt(TE); 297 } catch (Exception e) { 298 log.error("Not able to convert TE {} to HP", teTextField.getText()); 299 } 300 if (te > 0) { 301 int hp = te * Integer.parseInt(SPEED) / 625; 302 hpTextField.setText(Integer.toString(hp)); 303 } 304 } 305 } 306 307 @Override 308 protected void addPropertyChangeListeners() { 309 InstanceManager.getDefault(ConsistManager.class).addPropertyChangeListener(this); 310 engineModels.addPropertyChangeListener(this); 311 engineManager.addPropertyChangeListener(this); 312 super.addPropertyChangeListeners(); 313 } 314 315 @Override 316 protected void removePropertyChangeListeners() { 317 InstanceManager.getDefault(ConsistManager.class).removePropertyChangeListener(this); 318 engineModels.removePropertyChangeListener(this); 319 engineManager.removePropertyChangeListener(this); 320 if (_rs != null) { 321 _rs.removePropertyChangeListener(this); 322 } 323 super.removePropertyChangeListeners(); 324 } 325 326 @Override 327 public void propertyChange(java.beans.PropertyChangeEvent e) { 328 if (Control.SHOW_PROPERTY) { 329 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 330 e.getNewValue()); 331 } 332 super.propertyChange(e); 333 334 if (e.getPropertyName().equals(EngineLengths.ENGINELENGTHS_CHANGED_PROPERTY)) { 335 InstanceManager.getDefault(EngineLengths.class).updateComboBox(lengthComboBox); 336 if (_rs != null) { 337 lengthComboBox.setSelectedItem(_rs.getLength()); 338 } 339 } 340 if (e.getPropertyName().equals(EngineModels.ENGINEMODELS_CHANGED_PROPERTY)) { 341 engineModels.updateComboBox(modelComboBox); 342 if (_rs != null) { 343 modelComboBox.setSelectedItem(((Engine) _rs).getModel()); 344 } 345 } 346 if (e.getPropertyName().equals(ConsistManager.LISTLENGTH_CHANGED_PROPERTY)) { 347 InstanceManager.getDefault(ConsistManager.class).updateComboBox(groupComboBox); 348 if (_rs != null) { 349 groupComboBox.setSelectedItem(((Engine) _rs).getConsistName()); 350 } 351 } 352 if (e.getPropertyName().equals(EngineAttributeEditFrame.DISPOSE)) { 353 engineAttributeEditFrame = null; 354 } 355 } 356 357 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(EngineEditFrame.class); 358 359}