001package jmri.jmrit.operations.rollingstock.cars.tools; 002 003import java.awt.Dimension; 004import java.awt.GridBagLayout; 005 006import javax.swing.*; 007 008import jmri.InstanceManager; 009import jmri.jmrit.operations.OperationsFrame; 010import jmri.jmrit.operations.OperationsXml; 011import jmri.jmrit.operations.locations.LocationManager; 012import jmri.jmrit.operations.locations.schedules.ScheduleManager; 013import jmri.jmrit.operations.rollingstock.cars.*; 014import jmri.jmrit.operations.setup.Control; 015import jmri.jmrit.operations.setup.Setup; 016import jmri.jmrit.operations.trains.TrainManager; 017import jmri.util.swing.JmriJOptionPane; 018 019/** 020 * Frame for adding and editing the car load attribute for operations. 021 * 022 * @author Daniel Boudreau Copyright (C) 2009, 2010, 2011, 2023 023 */ 024public class CarLoadEditFrame extends OperationsFrame implements java.beans.PropertyChangeListener { 025 026 CarLoads carLoads = InstanceManager.getDefault(CarLoads.class); 027 CarTypes carTypes = InstanceManager.getDefault(CarTypes.class); 028 029 // labels 030 JLabel textSep = new JLabel(); 031 JLabel quanity = new JLabel("0"); 032 033 // major buttons 034 JButton addButton = new JButton(Bundle.getMessage("Add")); 035 JButton deleteButton = new JButton(Bundle.getMessage("ButtonDelete")); 036 JButton replaceButton = new JButton(Bundle.getMessage("Replace")); 037 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 038 039 // combo boxes 040 JComboBox<String> typeComboBox = carTypes.getComboBox(); 041 JComboBox<String> loadComboBox; 042 JComboBox<String> priorityComboBox = carLoads.getPriorityComboBox(); 043 JComboBox<String> hazardousComboBox = carLoads.getHazardousComboBox(); 044 JComboBox<String> loadTypeComboBox = carLoads.getLoadTypesComboBox(); 045 046 // check boxes 047 JCheckBox allTypesCheckBox = new JCheckBox(Bundle.getMessage("All")); 048 049 // text boxes 050 JTextField addTextBox = new JTextField(10); 051 JTextField pickupCommentTextField = new JTextField(35); 052 JTextField dropCommentTextField = new JTextField(35); 053 054 public CarLoadEditFrame() { 055 super(Bundle.getMessage("TitleCarEditLoad")); 056 } 057 058 String _type; // car type name 059 boolean menuActive = false; 060 061 public void initComponents(String type, String selectedItem) { 062 063 getContentPane().removeAll(); 064 065 _type = type; 066 typeComboBox.setSelectedItem(_type); 067 068 loadComboBox = carLoads.getComboBox(_type); 069 carLoads.addPropertyChangeListener(this); 070 loadComboBox.setSelectedItem(selectedItem); 071 updateLoadType(); 072 updatePriority(); 073 updateHazardous(); 074 075 // general GUI config 076 quanity.setVisible(showQuanity); 077 078 // car type panel 079 JPanel pType = new JPanel(); 080 pType.setLayout(new GridBagLayout()); 081 pType.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Type"))); 082 addItem(pType, typeComboBox, 0, 0); 083 addItem(pType, allTypesCheckBox, 1, 0); 084 085 allTypesCheckBox.setToolTipText(Bundle.getMessage("TipCarLoadAll")); 086 087 // load panel 088 JPanel pLoad = new JPanel(); 089 pLoad.setLayout(new GridBagLayout()); 090 pLoad.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Load"))); 091 092 // row 2 093 addItem(pLoad, addTextBox, 2, 2); 094 addItem(pLoad, addButton, 3, 2); 095 096 // row 3 097 addItem(pLoad, quanity, 1, 3); 098 addItem(pLoad, loadComboBox, 2, 3); 099 addItem(pLoad, deleteButton, 3, 3); 100 101 // row 4 102 addItem(pLoad, replaceButton, 3, 4); 103 104 deleteButton.setToolTipText(Bundle.getMessage("TipDeleteAttributeName", 105 Bundle.getMessage("Load"))); 106 addButton.setToolTipText(Bundle.getMessage("TipAddAttributeName", 107 Bundle.getMessage("Load"))); 108 replaceButton.setToolTipText(Bundle.getMessage("TipReplaceAttributeName", 109 Bundle.getMessage("Load"))); 110 111 // row 6 112 JPanel pLoadType = new JPanel(); 113 pLoadType.setLayout(new BoxLayout(pLoadType, BoxLayout.Y_AXIS)); 114 pLoadType.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutLoadType"))); 115 addItem(pLoadType, loadTypeComboBox, 0, 0); 116 117 // row 8 118 JPanel pPriority = new JPanel(); 119 pPriority.setLayout(new BoxLayout(pPriority, BoxLayout.Y_AXIS)); 120 pPriority.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutPriority"))); 121 addItem(pPriority, priorityComboBox, 0, 0); 122 123 // row 9 124 JPanel pHazardous = new JPanel(); 125 pHazardous.setLayout(new BoxLayout(pHazardous, BoxLayout.Y_AXIS)); 126 pHazardous.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Hazardous"))); 127 addItem(pHazardous, hazardousComboBox, 0, 0); 128 129 // row 10 130 // optional panel 131 JPanel pOptionalPickup = new JPanel(); 132 pOptionalPickup.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutOptionalPickup"))); 133 addItem(pOptionalPickup, pickupCommentTextField, 0, 0); 134 135 // row 12 136 JPanel pOptionalDrop = new JPanel(); 137 pOptionalDrop.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutOptionalDrop"))); 138 addItem(pOptionalDrop, dropCommentTextField, 0, 0); 139 140 // row 14 141 JPanel pControl = new JPanel(); 142 pControl.setLayout(new BoxLayout(pControl, BoxLayout.Y_AXIS)); 143 addItem(pControl, saveButton, 0, 0); 144 145 // add panels 146 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 147 getContentPane().add(pType); 148 getContentPane().add(pLoad); 149 getContentPane().add(pLoadType); 150 getContentPane().add(pPriority); 151 getContentPane().add(pHazardous); 152 getContentPane().add(pOptionalPickup); 153 getContentPane().add(pOptionalDrop); 154 getContentPane().add(pControl); 155 156 addButtonAction(addButton); 157 addButtonAction(deleteButton); 158 addButtonAction(replaceButton); 159 addButtonAction(saveButton); 160 161 addComboBoxAction(typeComboBox); 162 addComboBoxAction(loadComboBox); 163 164 addCheckBoxAction(allTypesCheckBox); 165 166 updateCarCommentFields(); 167 168 enableButtons(); 169 170 // build menu 171 JMenuBar menuBar = new JMenuBar(); 172 JMenu toolMenu = new JMenu(Bundle.getMessage("MenuTools")); 173 toolMenu.add(new CarLoadAttributeAction(this)); 174 toolMenu.add(new PrintCarLoadsAction(true)); 175 toolMenu.add(new PrintCarLoadsAction(false)); 176 menuBar.add(toolMenu); 177 setJMenuBar(menuBar); 178 // add help menu to window 179 addHelpMenu("package.jmri.jmrit.operations.Operations_EditCarLoads", true); // NOI18N 180 181 initMinimumSize(new Dimension(Control.panelWidth400, Control.panelHeight500)); 182 } 183 184 // add, delete, replace, and save buttons 185 @Override 186 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 187 String loadName = addTextBox.getText().trim(); 188 if (ae.getSource() == addButton || ae.getSource() == replaceButton) { 189 if (loadName.equals(NONE)) { 190 return; 191 } 192 if (loadName.length() > Control.max_len_string_attibute) { 193 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("carAttribute", 194 Control.max_len_string_attibute), Bundle.getMessage("canNotUseLoadName"), 195 JmriJOptionPane.ERROR_MESSAGE); 196 return; 197 } 198 // can't have the " & " as part of the load name 199 if (loadName.contains(CarLoad.SPLIT_CHAR)) { 200 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("carNameNoAndChar", 201 CarLoad.SPLIT_CHAR), Bundle.getMessage("canNotUseLoadName"), 202 JmriJOptionPane.ERROR_MESSAGE); 203 return; 204 } 205 } 206 if (ae.getSource() == addButton) { 207 addLoadName(loadName); 208 } 209 if (ae.getSource() == deleteButton) { 210 deleteLoadName(); 211 } 212 if (ae.getSource() == replaceButton) { 213 replaceLoadName(loadName); 214 } 215 if (ae.getSource() == saveButton) { 216 saveLoadName(); 217 OperationsXml.save(); // save all files that have been modified; 218 if (Setup.isCloseWindowOnSaveEnabled()) { 219 dispose(); 220 } 221 } 222 } 223 224 @Override 225 protected void comboBoxActionPerformed(java.awt.event.ActionEvent ae) { 226 log.debug("Combo box action"); 227 if (ae.getSource() == typeComboBox) { 228 _type = (String) typeComboBox.getSelectedItem(); 229 updateLoadComboBox(); 230 enableButtons(); 231 } 232 updateCarQuanity(); 233 updateLoadType(); 234 updatePriority(); 235 updateHazardous(); 236 updateCarCommentFields(); 237 } 238 239 @Override 240 protected void checkBoxActionPerformed(java.awt.event.ActionEvent ae) { 241 typeComboBox.setEnabled(!allTypesCheckBox.isSelected()); 242 } 243 244 private void addLoadName(String loadName) { 245 if (allTypesCheckBox.isSelected()) { 246 for (String type : carTypes.getNames()) { 247 carLoads.addName(type, loadName); 248 } 249 } else { 250 carLoads.addName(_type, loadName); 251 } 252 } 253 254 private void deleteLoadName() { 255 String deleteLoad = (String) loadComboBox.getSelectedItem(); 256 if (deleteLoad.equals(carLoads.getDefaultEmptyName()) || deleteLoad.equals(carLoads.getDefaultLoadName())) { 257 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("carLoadDefault"), Bundle 258 .getMessage("canNotDelete", Bundle.getMessage("Load")), 259 JmriJOptionPane.ERROR_MESSAGE); 260 return; 261 } 262 if (allTypesCheckBox.isSelected()) { 263 for (String type : carTypes.getNames()) { 264 replaceLoad(type, deleteLoad, null); 265 carLoads.deleteName(type, deleteLoad); 266 } 267 } else { 268 replaceLoad(_type, deleteLoad, null); 269 carLoads.deleteName(_type, deleteLoad); 270 } 271 } 272 273 private void replaceLoadName(String loadName) { 274 String oldLoadName = (String) loadComboBox.getSelectedItem(); 275 if (oldLoadName.equals(carLoads.getDefaultEmptyName())) { 276 if (JmriJOptionPane.showConfirmDialog(this, 277 Bundle.getMessage("replaceDefaultEmpty", 278 oldLoadName, loadName), 279 Bundle.getMessage("replaceAll"), 280 JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 281 return; 282 } 283 // don't allow the default names for load and empty to be the 284 // same 285 if (loadName.equals(carLoads.getDefaultEmptyName()) || loadName.equals(carLoads.getDefaultLoadName())) { 286 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("carDefault"), Bundle 287 .getMessage("canNotReplace", Bundle.getMessage("Load")), 288 JmriJOptionPane.ERROR_MESSAGE); 289 return; 290 } 291 carLoads.setDefaultEmptyName(loadName); 292 replaceAllLoads(oldLoadName, loadName); 293 return; 294 } 295 if (oldLoadName.equals(carLoads.getDefaultLoadName())) { 296 if (JmriJOptionPane.showConfirmDialog(this, 297 Bundle.getMessage("replaceDefaultLoad", 298 oldLoadName, loadName), 299 Bundle.getMessage("replaceAll"), 300 JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 301 return; 302 } 303 // don't allow the default names for load and empty to be the 304 // same 305 if (loadName.equals(carLoads.getDefaultEmptyName()) || loadName.equals(carLoads.getDefaultLoadName())) { 306 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("carDefault"), Bundle 307 .getMessage("canNotReplace", Bundle.getMessage("Load")), 308 JmriJOptionPane.ERROR_MESSAGE); 309 return; 310 } 311 carLoads.setDefaultLoadName(loadName); 312 replaceAllLoads(oldLoadName, loadName); 313 return; 314 } 315 if (JmriJOptionPane.showConfirmDialog(this, 316 Bundle.getMessage("replaceMsg", 317 oldLoadName, loadName), 318 Bundle.getMessage("replaceAll"), 319 JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 320 return; 321 } 322 if (oldLoadName.equals(loadName)) { 323 return; // do nothing 324 } 325 // ComboBoxes get deselected during the addName operation 326 String loadType = carLoads.getLoadType(_type, oldLoadName); 327 String loadPriority = carLoads.getPriority(_type, oldLoadName); 328 boolean isHazardous = carLoads.isHazardous(_type, oldLoadName); 329 String pickupComment = carLoads.getPickupComment(_type, oldLoadName); 330 String dropComment = carLoads.getDropComment(_type, oldLoadName); 331 332 if (allTypesCheckBox.isSelected()) { 333 for (String type : carTypes.getNames()) { 334 carLoads.addName(type, loadName); 335 carLoads.setLoadType(type, loadName, loadType); 336 carLoads.setPriority(type, loadName, loadPriority); 337 carLoads.setHazardous(type, loadName, isHazardous); 338 carLoads.setPickupComment(type, loadName, pickupComment); 339 carLoads.setDropComment(type, loadName, dropComment); 340 replaceLoad(type, oldLoadName, loadName); 341 carLoads.deleteName(type, oldLoadName); 342 } 343 } else { 344 carLoads.addName(_type, loadName); 345 carLoads.setLoadType(_type, loadName, loadType); 346 carLoads.setPriority(_type, loadName, loadPriority); 347 carLoads.setHazardous(_type, loadName, isHazardous); 348 carLoads.setPickupComment(_type, loadName, pickupComment); 349 carLoads.setDropComment(_type, loadName, dropComment); 350 replaceLoad(_type, oldLoadName, loadName); 351 carLoads.deleteName(_type, oldLoadName); 352 } 353 } 354 355 private void saveLoadName() { 356 if (allTypesCheckBox.isSelected()) { 357 for (String type : carTypes.getNames()) { 358 saveLoadName(type); 359 } 360 } else { 361 saveLoadName(_type); 362 } 363 } 364 365 private void saveLoadName(String type) { 366 carLoads.setLoadType(type, (String) loadComboBox.getSelectedItem(), (String) loadTypeComboBox 367 .getSelectedItem()); 368 carLoads.setPriority(type, (String) loadComboBox.getSelectedItem(), 369 (String) priorityComboBox.getSelectedItem()); 370 carLoads.setHazardous(type, (String) loadComboBox.getSelectedItem(), 371 hazardousComboBox.getSelectedItem().equals(Bundle.getMessage("ButtonYes"))); 372 carLoads.setPickupComment(type, (String) loadComboBox.getSelectedItem(), pickupCommentTextField.getText()); 373 carLoads.setDropComment(type, (String) loadComboBox.getSelectedItem(), dropCommentTextField.getText()); 374 } 375 376 // replace load name for all car types 377 private void replaceAllLoads(String oldLoad, String newLoad) { 378 for (String type : carTypes.getNames()) { 379 carLoads.addName(type, newLoad); 380 replaceLoad(type, oldLoad, newLoad); 381 carLoads.deleteName(type, oldLoad); 382 } 383 } 384 385 private void replaceLoad(String type, String oldLoad, String newLoad) { 386 // adjust all cars 387 InstanceManager.getDefault(CarManager.class).replaceLoad(type, oldLoad, newLoad); 388 // now adjust schedules 389 InstanceManager.getDefault(ScheduleManager.class).replaceLoad(type, oldLoad, newLoad); 390 // now adjust trains 391 InstanceManager.getDefault(TrainManager.class).replaceLoad(type, oldLoad, newLoad); 392 // now adjust tracks 393 InstanceManager.getDefault(LocationManager.class).replaceLoad(type, oldLoad, newLoad); 394 } 395 396 boolean showQuanity = false; 397 398 public void toggleShowQuanity() { 399 if (showQuanity) { 400 showQuanity = false; 401 } else { 402 showQuanity = true; 403 } 404 quanity.setVisible(showQuanity); 405 updateCarQuanity(); 406 } 407 408 private void updateCarQuanity() { 409 if (!showQuanity) { 410 return; 411 } 412 int number = 0; 413 String item = (String) loadComboBox.getSelectedItem(); 414 for (Car car : InstanceManager.getDefault(CarManager.class).getList()) { 415 if (car.getLoadName().equals(item)) { 416 number++; 417 } 418 } 419 quanity.setText(Integer.toString(number)); 420 } 421 422 private void updateLoadComboBox() { 423 carLoads.updateComboBox(_type, loadComboBox); 424 loadComboBox.setSelectedItem(addTextBox.getText().trim()); 425 } 426 427 private void updateLoadType() { 428 String loadName = (String) loadComboBox.getSelectedItem(); 429 loadTypeComboBox.setSelectedItem(carLoads.getLoadType(_type, loadName)); 430 if (loadName != null && 431 (loadName.equals(InstanceManager.getDefault(CarLoads.class).getDefaultEmptyName()) || 432 loadName.equals(InstanceManager.getDefault(CarLoads.class) 433 .getDefaultLoadName()))) { 434 loadTypeComboBox.setEnabled(false); 435 } else { 436 loadTypeComboBox.setEnabled(true); 437 } 438 } 439 440 private void updatePriority() { 441 priorityComboBox.setSelectedItem(carLoads.getPriority(_type, (String) loadComboBox.getSelectedItem())); 442 } 443 444 private void updateHazardous() { 445 hazardousComboBox.setSelectedItem(carLoads.isHazardous(_type, (String) loadComboBox.getSelectedItem()) 446 ? Bundle.getMessage("ButtonYes") : Bundle.getMessage("ButtonNo")); 447 } 448 449 private void updateCarCommentFields() { 450 pickupCommentTextField.setText(carLoads.getPickupComment(_type, (String) loadComboBox.getSelectedItem())); 451 dropCommentTextField.setText(carLoads.getDropComment(_type, (String) loadComboBox.getSelectedItem())); 452 } 453 454 private void enableButtons() { 455 addButton.setEnabled(_type != null); 456 deleteButton.setEnabled(_type != null); 457 replaceButton.setEnabled(_type != null); 458 saveButton.setEnabled(_type != null); 459 } 460 461 @Override 462 public void dispose() { 463 carLoads.removePropertyChangeListener(this); 464 super.dispose(); 465 } 466 467 @Override 468 public void propertyChange(java.beans.PropertyChangeEvent e) { 469 if (Control.SHOW_PROPERTY) { 470 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e 471 .getNewValue()); 472 } 473 if (e.getPropertyName().equals(CarLoads.LOAD_CHANGED_PROPERTY)) { 474 updateLoadComboBox(); 475 } 476 } 477 478 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CarLoadEditFrame.class); 479}