001package jmri.jmrit.operations.routes.tools; 002 003import java.awt.*; 004import java.awt.event.ComponentListener; 005import java.beans.PropertyChangeEvent; 006import java.beans.PropertyChangeListener; 007import java.util.List; 008 009import javax.swing.*; 010 011import jmri.InstanceManager; 012import jmri.jmrit.display.Editor; 013import jmri.jmrit.display.EditorManager; 014import jmri.jmrit.operations.OperationsFrame; 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 SetTrainIconRouteFrame extends OperationsFrame implements PropertyChangeListener { 028 029 RouteManager routeManager = InstanceManager.getDefault(RouteManager.class); 030 031 // labels 032 JLabel textX = new JLabel(" X "); 033 JLabel textY = new JLabel(" Y "); 034 035 JLabel routeLocationName = new JLabel(); 036 037 // text field 038 // check boxes 039 // major buttons 040 JButton previousButton = new JButton(Bundle.getMessage("Previous")); 041 JButton nextButton = new JButton(Bundle.getMessage("Next")); 042 JButton placeButton = new JButton(Bundle.getMessage("PlaceTestIcon")); 043 JButton applyButton = new JButton(Bundle.getMessage("ButtonApply")); 044 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 045 046 // combo boxes 047 // Spinners 048 JSpinner spinTrainIconX = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 049 JSpinner spinTrainIconY = new JSpinner(new SpinnerNumberModel(0, 0, 10000, 1)); 050 051 Route _route; 052 RouteLocation _rl; 053 int _routeIndex = 0; 054 List<RouteLocation> _routeList; 055 056 // test train icon 057 TrainIcon _tIon; 058 059 public SetTrainIconRouteFrame(Route route) { 060 super(Bundle.getMessage("MenuSetTrainIcon")); 061 062 if (route == null) { 063 return; 064 } 065 _route = route; 066 _route.addPropertyChangeListener(this); 067 068 // general GUI config 069 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 070 071 // set tool tips 072 placeButton.setToolTipText(Bundle.getMessage("TipPlaceButton") + " " + Setup.getPanelName()); 073 applyButton.setToolTipText(Bundle.getMessage("TipApplyButton")); 074 saveButton.setToolTipText(Bundle.getMessage("TipSaveButton")); 075 076 // Set up the panels 077 JPanel pRoute = new JPanel(); 078 pRoute.setBorder(BorderFactory 079 .createTitledBorder(Bundle.getMessage("Route") + " " + _route.getName())); 080 pRoute.setLayout(new GridBagLayout()); 081 addItem(pRoute, previousButton, 0, 0); 082 addItem(pRoute, routeLocationName, 1, 0); 083 addItem(pRoute, nextButton, 2, 0); 084 085 JPanel pSpin = new JPanel(); 086 pSpin.setLayout(new GridBagLayout()); 087 pSpin.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainIcon"))); 088 addItem(pSpin, textX, 0, 0); 089 addItem(pSpin, spinTrainIconX, 1, 0); 090 addItem(pSpin, textY, 2, 0); 091 addItem(pSpin, spinTrainIconY, 3, 0); 092 093 JPanel pControl = new JPanel(); 094 pControl.setLayout(new GridBagLayout()); 095 pControl.setBorder(BorderFactory.createTitledBorder("")); 096 addItem(pControl, placeButton, 0, 0); 097 addItem(pControl, applyButton, 1, 0); 098 addItem(pControl, saveButton, 2, 0); 099 100 getContentPane().add(pRoute); 101 getContentPane().add(pSpin); 102 getContentPane().add(pControl); 103 104 // add help menu to window 105 addHelpMenu("package.jmri.jmrit.operations.Operations_SetTrainIconCoordinates", true); // NOI18N 106 107 // setup buttons 108 addButtonAction(previousButton); 109 addButtonAction(nextButton); 110 addButtonAction(placeButton); 111 addButtonAction(applyButton); 112 addButtonAction(saveButton); 113 114 // start off with save button disabled 115 saveButton.setEnabled(false); 116 117 updateRoute(); 118 119 // setup spinners 120 addSpinnerChangeListerner(spinTrainIconX); 121 addSpinnerChangeListerner(spinTrainIconY); 122 123 initMinimumSize(new Dimension(Control.panelWidth400, Control.panelHeight400)); 124 125 } 126 127 int value = JmriJOptionPane.NO_OPTION; 128 129 @Override 130 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 131 if (ae.getSource() == previousButton) { 132 updateRouteLocation(BACK); 133 } 134 if (ae.getSource() == nextButton) { 135 updateRouteLocation(FORWARD); 136 } 137 if (ae.getSource() == placeButton) { 138 placeTestIcons(); 139 } 140 if (ae.getSource() == applyButton) { 141 if (value != JmriJOptionPane.YES_OPTION) { 142 value = JmriJOptionPane.showConfirmDialog(this, Bundle 143 .getMessage("UpdateTrainIconRoute", _route.getName()), Bundle 144 .getMessage("DoYouWantThisRoute"), 145 JmriJOptionPane.YES_NO_OPTION); 146 } 147 if (value == JmriJOptionPane.YES_OPTION) { 148 saveButton.setEnabled(true); 149 } 150 updateTrainIconCoordinates(); 151 } 152 if (ae.getSource() == saveButton) { 153 InstanceManager.getDefault(RouteManagerXml.class).writeOperationsFile(); 154 if (Setup.isCloseWindowOnSaveEnabled()) { 155 dispose(); 156 } 157 } 158 } 159 160 @Override 161 public void spinnerChangeEvent(javax.swing.event.ChangeEvent ae) { 162 if (ae.getSource() == spinTrainIconX && _tIon != null) { 163 _tIon.setLocation((Integer) spinTrainIconX.getValue(), _tIon.getLocation().y); 164 } 165 if (ae.getSource() == spinTrainIconY && _tIon != null) { 166 _tIon.setLocation(_tIon.getLocation().x, (Integer) spinTrainIconY.getValue()); 167 } 168 } 169 170 private void loadSpinners(RouteLocation rl) { 171 log.debug("Load spinners route location {}", rl.getName()); 172 spinTrainIconX.setValue(rl.getTrainIconX()); 173 spinTrainIconY.setValue(rl.getTrainIconY()); 174 } 175 176 // place test markers on panel 177 private void placeTestIcons() { 178 Editor editor = InstanceManager.getDefault(EditorManager.class).getTargetFrame(Setup.getPanelName()); 179 if (editor == null) { 180 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("LoadPanel", 181 Setup.getPanelName()), Bundle.getMessage("PanelNotFound"), 182 JmriJOptionPane.ERROR_MESSAGE); 183 } else { 184 if (_tIon != null) { 185 _tIon.remove(); 186 } 187 // icon 188 _tIon = editor.addTrainIcon(_rl.getName()); 189 _tIon.getToolTip().setText(_route.getName()); 190 _tIon.getToolTip().setBackgroundColor(Color.white); 191 _tIon.setLocation(_rl.getTrainIconX(), _rl.getTrainIconY()); 192 setTrainIconNameAndColor(); 193 addIconListener(_tIon); 194 } 195 } 196 197 private void setTrainIconNameAndColor() { 198 if (_tIon == null) { 199 return; 200 } 201 _tIon.setText(_rl.getName()); 202 // set color based on train direction at current location 203 if (_rl.getTrainDirection() == RouteLocation.NORTH) { 204 _tIon.setLocoColor(Setup.getTrainIconColorNorth()); 205 } 206 if (_rl.getTrainDirection() == RouteLocation.SOUTH) { 207 _tIon.setLocoColor(Setup.getTrainIconColorSouth()); 208 } 209 if (_rl.getTrainDirection() == RouteLocation.EAST) { 210 _tIon.setLocoColor(Setup.getTrainIconColorEast()); 211 } 212 if (_rl.getTrainDirection() == RouteLocation.WEST) { 213 _tIon.setLocoColor(Setup.getTrainIconColorWest()); 214 } 215 } 216 217 private void updateRoute() { 218 log.debug("Updating route"); 219 _routeList = _route.getLocationsBySequenceList(); 220 updateRouteLocation(NO_CHANGE); 221 } 222 223 private static final int FORWARD = 1; 224 private static final int BACK = -1; 225 private static final int NO_CHANGE = 0; 226 227 private void updateRouteLocation(int direction) { 228 if (direction == FORWARD) { 229 _routeIndex++; 230 } 231 if (direction == BACK) { 232 _routeIndex--; 233 } 234 // Confirm that index is in range 235 if (_routeIndex > _routeList.size() - 1) { 236 _routeIndex = _routeList.size() - 1; 237 } 238 if (_routeIndex < 0) { 239 _routeIndex = 0; 240 } 241 242 if (_rl != null) { 243 _rl.removePropertyChangeListener(this); 244 } 245 if (_routeList.size() > 0) { 246 _rl = _routeList.get(_routeIndex); 247 } 248 if (_rl != null) { 249 _rl.addPropertyChangeListener(this); 250 loadSpinners(_rl); 251 routeLocationName.setText(_rl.getName()); 252 } 253 // disable or enable previous and next buttons 254 previousButton.setEnabled(_routeIndex != 0); 255 nextButton.setEnabled(_routeIndex != _routeList.size() - 1); 256 257 setTrainIconNameAndColor(); 258 } 259 260 private void updateTrainIconCoordinates() { 261 if (_rl != null) { 262 _rl.removePropertyChangeListener(this); 263 _rl.setTrainIconX((Integer) spinTrainIconX.getValue()); 264 _rl.setTrainIconY((Integer) spinTrainIconY.getValue()); 265 _rl.addPropertyChangeListener(this); 266 } 267 } 268 269 private void addIconListener(TrainIcon tI) { 270 tI.addComponentListener(new ComponentListener() { 271 @Override 272 public void componentHidden(java.awt.event.ComponentEvent e) { 273 } 274 275 @Override 276 public void componentShown(java.awt.event.ComponentEvent e) { 277 } 278 279 @Override 280 public void componentMoved(java.awt.event.ComponentEvent e) { 281 trainIconMoved(e); 282 } 283 284 @Override 285 public void componentResized(java.awt.event.ComponentEvent e) { 286 } 287 }); 288 } 289 290 protected void trainIconMoved(java.awt.event.ComponentEvent ae) { 291 if (ae.getSource() == _tIon) { 292 log.debug("train icon X: {} Y: {}", _tIon.getLocation().x, _tIon.getLocation().y); 293 spinTrainIconX.setValue(_tIon.getLocation().x); 294 spinTrainIconY.setValue(_tIon.getLocation().y); 295 } 296 } 297 298 private void removeIcons() { 299 if (_tIon != null) { 300 _tIon.remove(); 301 } 302 } 303 304 @Override 305 public void dispose() { 306 removeIcons(); 307 if (_route != null) { 308 _route.removePropertyChangeListener(this); 309 } 310 if (_rl != null) { 311 _rl.removePropertyChangeListener(this); 312 } 313 super.dispose(); 314 } 315 316 @Override 317 public void propertyChange(PropertyChangeEvent e) { 318 log.debug("Property change ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 319 e.getNewValue()); 320 if (e.getSource().equals(_route)) { 321 updateRoute(); 322 } 323 if (e.getSource().equals(_rl)) { 324 updateRouteLocation(NO_CHANGE); 325 } 326 } 327 328 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SetTrainIconRouteFrame.class); 329}