001package jmri.jmrit.operations.routes.tools; 002 003import java.awt.*; 004import java.awt.event.ComponentListener; 005 006import javax.swing.*; 007 008import jmri.InstanceManager; 009import jmri.jmrit.display.Editor; 010import jmri.jmrit.display.EditorManager; 011import jmri.jmrit.operations.OperationsFrame; 012import jmri.jmrit.operations.OperationsXml; 013import jmri.jmrit.operations.locations.Location; 014import jmri.jmrit.operations.locations.LocationManager; 015import jmri.jmrit.operations.routes.*; 016import jmri.jmrit.operations.setup.Control; 017import jmri.jmrit.operations.setup.Setup; 018import jmri.jmrit.operations.trains.TrainIcon; 019import jmri.util.swing.JmriJOptionPane; 020 021/** 022 * Frame for setting train icon coordinates for a location. 023 * 024 * @author Bob Jacobsen Copyright (C) 2001 025 * @author Daniel Boudreau Copyright (C) 2010 026 */ 027public class SetTrainIconPositionFrame extends OperationsFrame { 028 029 RouteManager routeManager = InstanceManager.getDefault(RouteManager.class); 030 031 // labels 032 JLabel textEastX = new JLabel(" X "); 033 JLabel textEastY = new JLabel(" Y "); 034 JLabel textWestX = new JLabel(" X "); 035 JLabel textWestY = new JLabel(" Y "); 036 JLabel textNorthX = new JLabel(" X "); 037 JLabel textNorthY = new JLabel(" Y "); 038 JLabel textSouthX = new JLabel(" X "); 039 JLabel textSouthY = new JLabel(" Y "); 040 041 JLabel textRangeX = new JLabel(" X +/-"); 042 JLabel textRangeY = new JLabel(" Y +/-"); 043 044 // major buttons 045 JButton placeButton = new JButton(Bundle.getMessage("PlaceTestIcon")); 046 JButton applyButton = new JButton(Bundle.getMessage("UpdateRoutes")); 047 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 048 049 // combo boxes 050 JComboBox<Location> locationBox = InstanceManager.getDefault(LocationManager.class).getComboBox(); 051 052 // Spinners 053 JSpinner spinTrainIconEastX = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 054 JSpinner spinTrainIconEastY = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 055 JSpinner spinTrainIconWestX = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 056 JSpinner spinTrainIconWestY = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 057 JSpinner spinTrainIconNorthX = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 058 JSpinner spinTrainIconNorthY = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 059 JSpinner spinTrainIconSouthX = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 060 JSpinner spinTrainIconSouthY = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 061 062 // detection range 063 JSpinner spinTrainIconRangeX = new JSpinner(new SpinnerNumberModel(Location.RANGE_DEFAULT, 0, 1000, 1)); 064 JSpinner spinTrainIconRangeY = new JSpinner(new SpinnerNumberModel(Location.RANGE_DEFAULT, 0, 1000, 1)); 065 066 // Four test train icons 067 TrainIcon _tIonEast; 068 TrainIcon _tIonWest; 069 TrainIcon _tIonNorth; 070 TrainIcon _tIonSouth; 071 072 public SetTrainIconPositionFrame() { 073 super(Bundle.getMessage("MenuSetTrainIcon")); 074 075 // general GUI config 076 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 077 078 // set tool tips 079 placeButton.setToolTipText(Bundle.getMessage("TipPlaceButton") + " \"" + Setup.getPanelName() + "\""); // NOI18N 080 applyButton.setToolTipText(Bundle.getMessage("TipApplyAllButton")); 081 saveButton.setToolTipText(Bundle.getMessage("TipSaveButton")); 082 083 // Set up the panels 084 JPanel pLocation = new JPanel(); 085 pLocation.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Location"))); 086 pLocation.add(locationBox); 087 088 JPanel pEast = new JPanel(); 089 pEast.setLayout(new GridBagLayout()); 090 pEast.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("EastTrainIcon"))); 091 addItem(pEast, textEastX, 0, 0); 092 addItem(pEast, spinTrainIconEastX, 1, 0); 093 addItem(pEast, textEastY, 2, 0); 094 addItem(pEast, spinTrainIconEastY, 3, 0); 095 096 JPanel pWest = new JPanel(); 097 pWest.setLayout(new GridBagLayout()); 098 pWest.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("WestTrainIcon"))); 099 addItem(pWest, textWestX, 0, 0); 100 addItem(pWest, spinTrainIconWestX, 1, 0); 101 addItem(pWest, textWestY, 2, 0); 102 addItem(pWest, spinTrainIconWestY, 3, 0); 103 104 JPanel pNorth = new JPanel(); 105 pNorth.setLayout(new GridBagLayout()); 106 pNorth.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("NorthTrainIcon"))); 107 addItem(pNorth, textNorthX, 0, 0); 108 addItem(pNorth, spinTrainIconNorthX, 1, 0); 109 addItem(pNorth, textNorthY, 2, 0); 110 addItem(pNorth, spinTrainIconNorthY, 3, 0); 111 112 JPanel pSouth = new JPanel(); 113 pSouth.setLayout(new GridBagLayout()); 114 pSouth.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("SouthTrainIcon"))); 115 addItem(pSouth, textSouthX, 0, 0); 116 addItem(pSouth, spinTrainIconSouthX, 1, 0); 117 addItem(pSouth, textSouthY, 2, 0); 118 addItem(pSouth, spinTrainIconSouthY, 3, 0); 119 120 JPanel pRange = new JPanel(); 121 pRange.setLayout(new GridBagLayout()); 122 pRange.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("RangeTrainIcon"))); 123 addItem(pRange, textRangeX, 0, 0); 124 addItem(pRange, spinTrainIconRangeX, 1, 0); 125 addItem(pRange, textRangeY, 2, 0); 126 addItem(pRange, spinTrainIconRangeY, 3, 0); 127 128 JPanel pControl = new JPanel(); 129 pControl.setLayout(new GridBagLayout()); 130 pControl.setBorder(BorderFactory.createTitledBorder("")); 131 addItem(pControl, placeButton, 0, 0); 132 addItem(pControl, applyButton, 1, 0); 133 addItem(pControl, saveButton, 2, 0); 134 135 // only show valid directions 136 pEast.setVisible((Setup.getTrainDirection() & Setup.EAST) == Setup.EAST); 137 pWest.setVisible((Setup.getTrainDirection() & Setup.WEST) == Setup.WEST); 138 pNorth.setVisible((Setup.getTrainDirection() & Setup.NORTH) == Setup.NORTH); 139 pSouth.setVisible((Setup.getTrainDirection() & Setup.SOUTH) == Setup.SOUTH); 140 141 getContentPane().add(pLocation); 142 getContentPane().add(pNorth); 143 getContentPane().add(pSouth); 144 getContentPane().add(pEast); 145 getContentPane().add(pWest); 146 getContentPane().add(pRange); 147 getContentPane().add(pControl); 148 149 // add help menu to window 150 addHelpMenu("package.jmri.jmrit.operations.Operations_SetTrainIconCoordinates", true); // NOI18N 151 152 // setup buttons 153 addButtonAction(placeButton); 154 addButtonAction(applyButton); 155 addButtonAction(saveButton); 156 157 // setup combo box 158 addComboBoxAction(locationBox); 159 160 // setup spinners 161 spinnersEnable(false); 162 addSpinnerChangeListerner(spinTrainIconEastX); 163 addSpinnerChangeListerner(spinTrainIconEastY); 164 addSpinnerChangeListerner(spinTrainIconWestX); 165 addSpinnerChangeListerner(spinTrainIconWestY); 166 addSpinnerChangeListerner(spinTrainIconNorthX); 167 addSpinnerChangeListerner(spinTrainIconNorthY); 168 addSpinnerChangeListerner(spinTrainIconSouthX); 169 addSpinnerChangeListerner(spinTrainIconSouthY); 170 171 addSpinnerChangeListerner(spinTrainIconRangeX); 172 addSpinnerChangeListerner(spinTrainIconRangeY); 173 174 initMinimumSize(new Dimension(Control.panelWidth500, Control.panelHeight400)); 175 176 } 177 178 @Override 179 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 180 // check to see if a location has been selected 181 if (locationBox.getSelectedItem() == null) { 182 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("SelectLocationToEdit"), 183 Bundle.getMessage("NoLocationSelected"), JmriJOptionPane.ERROR_MESSAGE); 184 return; 185 } 186 Location location = (Location) locationBox.getSelectedItem(); 187 if (location == null) { 188 return; 189 } 190 if (ae.getSource() == placeButton) { 191 placeTestIcons(); 192 } 193 if (ae.getSource() == applyButton) { 194 // update all routes? 195 int value = JmriJOptionPane.showConfirmDialog(this, Bundle.getMessage("DoYouWantAllRoutes"), 196 Bundle.getMessage("UpdateTrainIcon", location.getName()), 197 JmriJOptionPane.YES_NO_OPTION); 198 if (value == JmriJOptionPane.YES_OPTION) { 199 saveSpinnerValues(location); 200 updateTrainIconCoordinates(location); 201 } 202 } 203 if (ae.getSource() == saveButton) { 204 int value = JmriJOptionPane.showConfirmDialog(this, Bundle.getMessage("UpdateDefaults"), 205 Bundle.getMessage("UpdateTrainIcon", location.getName()), 206 JmriJOptionPane.YES_NO_OPTION); 207 if (value == JmriJOptionPane.YES_OPTION) { 208 saveSpinnerValues(location); 209 } 210 OperationsXml.save(); // save location and route files 211 if (Setup.isCloseWindowOnSaveEnabled()) { 212 dispose(); 213 } 214 } 215 } 216 217 @Override 218 public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) { 219 if (locationBox.getSelectedItem() == null) { 220 resetSpinners(); 221 removeIcons(); 222 } else { 223 loadSpinners((Location) locationBox.getSelectedItem()); 224 } 225 } 226 227 @Override 228 public void spinnerChangeEvent(javax.swing.event.ChangeEvent ae) { 229 if (ae.getSource() == spinTrainIconEastX && _tIonEast != null) { 230 _tIonEast.setLocation((Integer) spinTrainIconEastX.getValue(), _tIonEast.getLocation().y); 231 } 232 if (ae.getSource() == spinTrainIconEastY && _tIonEast != null) { 233 _tIonEast.setLocation(_tIonEast.getLocation().x, (Integer) spinTrainIconEastY.getValue()); 234 } 235 if (ae.getSource() == spinTrainIconWestX && _tIonWest != null) { 236 _tIonWest.setLocation((Integer) spinTrainIconWestX.getValue(), _tIonWest.getLocation().y); 237 } 238 if (ae.getSource() == spinTrainIconWestY && _tIonWest != null) { 239 _tIonWest.setLocation(_tIonWest.getLocation().x, (Integer) spinTrainIconWestY.getValue()); 240 } 241 if (ae.getSource() == spinTrainIconNorthX && _tIonNorth != null) { 242 _tIonNorth.setLocation((Integer) spinTrainIconNorthX.getValue(), _tIonNorth.getLocation().y); 243 } 244 if (ae.getSource() == spinTrainIconNorthY && _tIonNorth != null) { 245 _tIonNorth.setLocation(_tIonNorth.getLocation().x, (Integer) spinTrainIconNorthY.getValue()); 246 } 247 if (ae.getSource() == spinTrainIconSouthX && _tIonSouth != null) { 248 _tIonSouth.setLocation((Integer) spinTrainIconSouthX.getValue(), _tIonSouth.getLocation().y); 249 } 250 if (ae.getSource() == spinTrainIconSouthY && _tIonSouth != null) { 251 _tIonSouth.setLocation(_tIonSouth.getLocation().x, (Integer) spinTrainIconSouthY.getValue()); 252 } 253 } 254 255 private void resetSpinners() { 256 spinnersEnable(false); 257 spinTrainIconEastX.setValue(0); 258 spinTrainIconEastY.setValue(0); 259 spinTrainIconWestX.setValue(0); 260 spinTrainIconWestY.setValue(0); 261 spinTrainIconNorthX.setValue(0); 262 spinTrainIconNorthY.setValue(0); 263 spinTrainIconSouthX.setValue(0); 264 spinTrainIconSouthY.setValue(0); 265 } 266 267 private void loadSpinners(Location location) { 268 log.debug("Load spinners location {}", location.getName()); 269 spinnersEnable(true); 270 spinTrainIconEastX.setValue(location.getTrainIconEast().x); 271 spinTrainIconEastY.setValue(location.getTrainIconEast().y); 272 spinTrainIconWestX.setValue(location.getTrainIconWest().x); 273 spinTrainIconWestY.setValue(location.getTrainIconWest().y); 274 spinTrainIconNorthX.setValue(location.getTrainIconNorth().x); 275 spinTrainIconNorthY.setValue(location.getTrainIconNorth().y); 276 spinTrainIconSouthX.setValue(location.getTrainIconSouth().x); 277 spinTrainIconSouthY.setValue(location.getTrainIconSouth().y); 278 279 spinTrainIconRangeX.setValue(location.getTrainIconRangeX()); 280 spinTrainIconRangeY.setValue(location.getTrainIconRangeY()); 281 } 282 283 private void spinnersEnable(boolean enable) { 284 spinTrainIconEastX.setEnabled(enable); 285 spinTrainIconEastY.setEnabled(enable); 286 spinTrainIconWestX.setEnabled(enable); 287 spinTrainIconWestY.setEnabled(enable); 288 spinTrainIconNorthX.setEnabled(enable); 289 spinTrainIconNorthY.setEnabled(enable); 290 spinTrainIconSouthX.setEnabled(enable); 291 spinTrainIconSouthY.setEnabled(enable); 292 293 spinTrainIconRangeX.setEnabled(enable); 294 spinTrainIconRangeY.setEnabled(enable); 295 } 296 297 private void saveSpinnerValues(Location location) { 298 log.debug("Save train icons coordinates for location {}", location.getName()); 299 location.setTrainIconEast( 300 new Point((Integer) spinTrainIconEastX.getValue(), (Integer) spinTrainIconEastY.getValue())); 301 location.setTrainIconWest( 302 new Point((Integer) spinTrainIconWestX.getValue(), (Integer) spinTrainIconWestY.getValue())); 303 location.setTrainIconNorth( 304 new Point((Integer) spinTrainIconNorthX.getValue(), (Integer) spinTrainIconNorthY.getValue())); 305 location.setTrainIconSouth( 306 new Point((Integer) spinTrainIconSouthX.getValue(), (Integer) spinTrainIconSouthY.getValue())); 307 308 location.setTrainIconRangeX((Integer) spinTrainIconRangeX.getValue()); 309 location.setTrainIconRangeY((Integer) spinTrainIconRangeY.getValue()); 310 } 311 312 // place test markers on panel 313 private void placeTestIcons() { 314 removeIcons(); 315 if (locationBox.getSelectedItem() == null) { 316 return; 317 } 318 Editor editor = InstanceManager.getDefault(EditorManager.class).getTargetFrame(Setup.getPanelName()); 319 if (editor == null) { 320 JmriJOptionPane.showMessageDialog(this, 321 Bundle.getMessage("LoadPanel", Setup.getPanelName()), 322 Bundle.getMessage("PanelNotFound"), JmriJOptionPane.ERROR_MESSAGE); 323 return; 324 } 325 Location location = (Location) locationBox.getSelectedItem(); 326 if (location != null) { 327 // East icon 328 if ((Setup.getTrainDirection() & Setup.EAST) == Setup.EAST) { 329 _tIonEast = editor.addTrainIcon(Bundle.getMessage("East")); 330 _tIonEast.getToolTip().setText(location.getName()); 331 _tIonEast.getToolTip().setBackgroundColor(Color.white); 332 _tIonEast.setLocoColor(Setup.getTrainIconColorEast()); 333 _tIonEast.setLocation((Integer) spinTrainIconEastX.getValue(), (Integer) spinTrainIconEastY.getValue()); 334 addIconListener(_tIonEast); 335 } 336 // West icon 337 if ((Setup.getTrainDirection() & Setup.WEST) == Setup.WEST) { 338 _tIonWest = editor.addTrainIcon(Bundle.getMessage("West")); 339 _tIonWest.getToolTip().setText(location.getName()); 340 _tIonWest.getToolTip().setBackgroundColor(Color.white); 341 _tIonWest.setLocoColor(Setup.getTrainIconColorWest()); 342 _tIonWest.setLocation((Integer) spinTrainIconWestX.getValue(), (Integer) spinTrainIconWestY.getValue()); 343 addIconListener(_tIonWest); 344 } 345 // North icon 346 if ((Setup.getTrainDirection() & Setup.NORTH) == Setup.NORTH) { 347 _tIonNorth = editor.addTrainIcon(Bundle.getMessage("North")); 348 _tIonNorth.getToolTip().setText(location.getName()); 349 _tIonNorth.getToolTip().setBackgroundColor(Color.white); 350 _tIonNorth.setLocoColor(Setup.getTrainIconColorNorth()); 351 _tIonNorth.setLocation((Integer) spinTrainIconNorthX.getValue(), 352 (Integer) spinTrainIconNorthY.getValue()); 353 addIconListener(_tIonNorth); 354 } 355 // South icon 356 if ((Setup.getTrainDirection() & Setup.SOUTH) == Setup.SOUTH) { 357 _tIonSouth = editor.addTrainIcon(Bundle.getMessage("South")); 358 _tIonSouth.getToolTip().setText(location.getName()); 359 _tIonSouth.getToolTip().setBackgroundColor(Color.white); 360 _tIonSouth.setLocoColor(Setup.getTrainIconColorSouth()); 361 _tIonSouth.setLocation((Integer) spinTrainIconSouthX.getValue(), 362 (Integer) spinTrainIconSouthY.getValue()); 363 addIconListener(_tIonSouth); 364 } 365 } 366 } 367 368 public void updateTrainIconCoordinates(Location location) { 369 for (Route route : InstanceManager.getDefault(RouteManager.class).getRoutesByIdList()) { 370 for (RouteLocation rl : route.getLocationsBySequenceList()) { 371 if (rl.getName().equals(location.getName())) { 372 log.debug("Updating train icon for route location {} in route {}", rl.getName(), route.getName()); 373 rl.setTrainIconCoordinates(); 374 } 375 } 376 } 377 } 378 379 private void removeIcons() { 380 if (_tIonEast != null) { 381 _tIonEast.remove(); 382 } 383 if (_tIonWest != null) { 384 _tIonWest.remove(); 385 } 386 if (_tIonNorth != null) { 387 _tIonNorth.remove(); 388 } 389 if (_tIonSouth != null) { 390 _tIonSouth.remove(); 391 } 392 } 393 394 private void addIconListener(TrainIcon tI) { 395 tI.addComponentListener(new ComponentListener() { 396 @Override 397 public void componentHidden(java.awt.event.ComponentEvent e) { 398 } 399 400 @Override 401 public void componentShown(java.awt.event.ComponentEvent e) { 402 } 403 404 @Override 405 public void componentMoved(java.awt.event.ComponentEvent e) { 406 trainIconMoved(e); 407 } 408 409 @Override 410 public void componentResized(java.awt.event.ComponentEvent e) { 411 } 412 }); 413 } 414 415 protected void trainIconMoved(java.awt.event.ComponentEvent ae) { 416 if (ae.getSource() == _tIonEast) { 417 log.debug("East train icon X: {} Y: {}", _tIonEast.getLocation().x, _tIonEast.getLocation().y); 418 spinTrainIconEastX.setValue(_tIonEast.getLocation().x); 419 spinTrainIconEastY.setValue(_tIonEast.getLocation().y); 420 } 421 if (ae.getSource() == _tIonWest) { 422 log.debug("West train icon X: {} Y: {}", _tIonWest.getLocation().x, _tIonWest.getLocation().y); 423 spinTrainIconWestX.setValue(_tIonWest.getLocation().x); 424 spinTrainIconWestY.setValue(_tIonWest.getLocation().y); 425 } 426 if (ae.getSource() == _tIonNorth) { 427 log.debug("North train icon X: {} Y: {}", _tIonNorth.getLocation().x, _tIonNorth.getLocation().y); 428 spinTrainIconNorthX.setValue(_tIonNorth.getLocation().x); 429 spinTrainIconNorthY.setValue(_tIonNorth.getLocation().y); 430 } 431 if (ae.getSource() == _tIonSouth) { 432 log.debug("South train icon X: {} Y: {}", _tIonSouth.getLocation().x, _tIonSouth.getLocation().y); 433 spinTrainIconSouthX.setValue(_tIonSouth.getLocation().x); 434 spinTrainIconSouthY.setValue(_tIonSouth.getLocation().y); 435 } 436 } 437 438 @Override 439 public void dispose() { 440 removeIcons(); 441 super.dispose(); 442 } 443 444 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SetTrainIconPositionFrame.class); 445}