001package jmri.jmrit.entryexit; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.util.Hashtable; 006import java.util.List; 007import java.util.Map.Entry; 008import jmri.InstanceManager; 009import jmri.NamedBean; 010import jmri.Sensor; 011import jmri.SignalHead; 012import jmri.SignalMast; 013import jmri.jmrit.display.EditorManager; 014import jmri.jmrit.display.SensorIcon; 015import jmri.jmrit.display.layoutEditor.LayoutBlock; 016import jmri.jmrit.display.layoutEditor.LayoutEditor; 017import jmri.jmrit.display.layoutEditor.LayoutSlip; 018import jmri.jmrit.display.layoutEditor.LayoutTurnout; 019import jmri.jmrit.display.layoutEditor.LevelXing; 020import jmri.jmrit.display.layoutEditor.PositionablePoint; 021import org.slf4j.Logger; 022import org.slf4j.LoggerFactory; 023 024public class PointDetails { 025 026 //May want to look at putting a listener on the refLoc to listen to updates to blocks, signals and sensors attached to it 027 LayoutEditor panel = null; 028 LayoutBlock facing; 029 List<LayoutBlock> protectingBlocks; 030 private NamedBean refObj; 031 private Object refLoc; 032 private Sensor sensor; 033 private SignalMast signalmast; 034 private SignalHead signalhead; 035 036 static int nxButtonTimeout = 10; 037 038 Source sourceRoute; 039 transient Hashtable<DestinationPoints, Source> destinations = new Hashtable<>(5); 040 041 public PointDetails(LayoutBlock facing, List<LayoutBlock> protecting) { 042 this.facing = facing; 043 this.protectingBlocks = protecting; 044 } 045 046 public LayoutBlock getFacing() { 047 return facing; 048 } 049 050 public List<LayoutBlock> getProtecting() { 051 return protectingBlocks; 052 } 053 054 //This might be better off a ref to the source pointdetail. 055 boolean routeToSet = false; 056 057 void setRouteTo(boolean boo) { 058 routeToSet = boo; 059 } 060 061 boolean routeFromSet = false; 062 063 void setRouteFrom(boolean boo) { 064 routeFromSet = boo; 065 } 066 067 public void setPanel(LayoutEditor panel) { 068 this.panel = panel; 069 // find the panel that actually contains this sensor, default to the supplied panel 070 for (LayoutEditor layout : InstanceManager.getDefault(EditorManager.class).getAll(LayoutEditor.class)) { 071 for (SensorIcon si : layout.getSensorList()) { 072 if (sensor == si.getNamedBean()) { 073 this.panel = layout; 074 return; 075 } 076 } 077 } 078 } 079 080 void setSensor(Sensor sen) { 081 if (sensor == sen) { 082 return; 083 } 084 if (sensor != null) { 085 sensor.removePropertyChangeListener(nxButtonListener); 086 } 087 sensor = sen; 088 if (sensor != null) { 089 sensor.addPropertyChangeListener(nxButtonListener); 090 } 091 } 092 093 void addSensorList() { 094 sensor.addPropertyChangeListener(nxButtonListener); 095 } 096 097 void removeSensorList() { 098 sensor.removePropertyChangeListener(nxButtonListener); 099 } 100 101 //Sensor getSensor() { return sensor; } 102 protected PropertyChangeListener nxButtonListener = new PropertyChangeListener() { 103 //First off if we were inactive, and now active 104 @Override 105 public void propertyChange(PropertyChangeEvent e) { 106 nxButtonStateChange(e); 107 } 108 }; 109 110 private void nxButtonStateChange(PropertyChangeEvent e) { 111 if (!e.getPropertyName().equals("KnownState")) { // NOI18N 112 return; 113 } 114 int now = ((Integer) e.getNewValue()); 115 int old = ((Integer) e.getOldValue()); 116 117 if ((old == Sensor.UNKNOWN) || (old == Sensor.INCONSISTENT)) { 118 setButtonState(EntryExitPairs.NXBUTTONINACTIVE); 119 return; 120 } 121 122 DestinationPoints destPoint = null; 123 124 for (Entry<DestinationPoints, Source> dp : destinations.entrySet()) { 125 // This point might be a destination in zero or more NX pairs. 126 // If the source point is active, then this is a single point route. 127 destPoint = dp.getKey(); 128 if (destPoint.isEnabled() && dp.getValue().getPoint().getNXState() == EntryExitPairs.NXBUTTONSELECTED) { 129 // This destination point has an active source point 130 setButtonState(EntryExitPairs.NXBUTTONSELECTED); 131 // Call activeBean directly 132 destPoint.activeBean(false); 133 log.debug("[nxButtonStateChange] Single point route selected"); 134 return; 135 } 136 } 137 138 if (sourceRoute != null) { 139 if (now == Sensor.ACTIVE && getNXState() == EntryExitPairs.NXBUTTONINACTIVE) { 140 setButtonState(EntryExitPairs.NXBUTTONSELECTED); 141 for (Entry<PointDetails, DestinationPoints> en : sourceRoute.pointToDest.entrySet()) { 142 //Sensor sen = getSensorFromPoint(en.getKey().getPoint()); 143 //Set a time out on the source sensor, so that if its state hasn't been changed, then we will clear it out. 144 if (en.getValue().isEnabled() && !en.getValue().getUniDirection()) { 145 if (en.getKey().getNXState() == EntryExitPairs.NXBUTTONSELECTED) { 146 // Call activeBean via the Source object when bi-directional 147 sourceRoute.activeBean(en.getValue(), true); 148 } 149 } 150 } 151 } else if (now == Sensor.INACTIVE && getNXState() == EntryExitPairs.NXBUTTONSELECTED) { 152 //sensor inactive, nxbutton state was selected, going to set back to inactive - ie user cancelled button 153 setButtonState(EntryExitPairs.NXBUTTONINACTIVE); 154 } else if (now == Sensor.INACTIVE && getNXState() == EntryExitPairs.NXBUTTONACTIVE) { 155 //Sensor gone inactive, while nxbutton was selected - potential start of user either clear route or setting another 156 setButtonState(EntryExitPairs.NXBUTTONSELECTED); 157 for (Entry<PointDetails, DestinationPoints> en : sourceRoute.pointToDest.entrySet()) { 158 //Sensor sen = getSensorFromPoint(en.getKey().getPoint()); 159 //Set a time out on the source sensor, so that if its state hasn't been changed, then we will clear it out. 160 if (en.getValue().isEnabled() && !en.getValue().getUniDirection()) { 161 if (en.getKey().getNXState() == EntryExitPairs.NXBUTTONSELECTED) { 162 // Call activeBean via the Source object when bi-directional 163 sourceRoute.activeBean(en.getValue(), false); 164 } 165 } 166 } 167 } 168 } else if (destPoint != null) { 169 //Button set as a destination but has no source, it has had a change in state 170 if (now == Sensor.ACTIVE) { 171 //State now is Active will set flashing 172 setButtonState(EntryExitPairs.NXBUTTONSELECTED); 173 } else if (getNXState() == EntryExitPairs.NXBUTTONACTIVE) { 174 //Sensor gone inactive while it was previosly active 175 setButtonState(EntryExitPairs.NXBUTTONSELECTED); 176 } else if (getNXState() == EntryExitPairs.NXBUTTONSELECTED) { 177 //Sensor gone inactive while it was previously selected therefore will cancel 178 setButtonState(EntryExitPairs.NXBUTTONINACTIVE); 179 } 180 } 181 182 log.debug("[nxButtonStateChange] Initial button or possible multiple point route"); 183 jmri.InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class).setMultiPointRoute(this, panel); 184 } 185 186 void setSignalMast(SignalMast mast) { 187 signalmast = mast; 188 } 189 190 void setSource(Source src) { 191 if (sourceRoute == src) { 192 return; 193 } 194 sourceRoute = src; 195 } 196 197 void setDestination(DestinationPoints srcdp, Source src) { 198 if (!destinations.containsKey(srcdp)) { 199 destinations.put(srcdp, src); 200 } 201 } 202 203 void removeDestination(DestinationPoints srcdp) { 204 destinations.remove(srcdp); 205 if (sourceRoute == null && destinations.isEmpty()) { 206 stopFlashSensor(); 207 sensor.removePropertyChangeListener(nxButtonListener); 208 setSensor(null); 209 } 210 } 211 212 void removeSource(Source src) { 213 sourceRoute = null; 214 if (destinations.isEmpty()) { 215 stopFlashSensor(); 216 setSensor(null); 217 } 218 } 219 220 private int nxButtonState = EntryExitPairs.NXBUTTONINACTIVE; 221 222 void setButtonState(int state) { 223 setNXButtonState(state); 224 } 225 226 void setNXState(int state) { 227 if (state == nxButtonState) { 228 return; 229 } 230 if (state == EntryExitPairs.NXBUTTONSELECTED) { 231 nxButtonTimeOut(); 232 flashSensor(); 233 } else { 234 cancelNXButtonTimeOut(); 235 stopFlashSensor(); 236 } 237 nxButtonState = state; 238 } 239 240 public int getNXState() { 241 return nxButtonState; 242 } 243 244 SignalMast getSignalMast() { 245 return signalmast; 246 } 247 248 void setSignalHead(SignalHead head) { 249 signalhead = head; 250 } 251 252 SignalHead getSignalHead() { 253 return signalhead; 254 } 255 256 public LayoutEditor getPanel() { 257 return panel; 258 } 259 260 public void setRefObject(NamedBean refObs) { 261 for (LayoutEditor pnl : InstanceManager.getDefault(EditorManager.class).getAll(LayoutEditor.class)) { 262 if (refLoc == null) { 263 setRefObjectByPanel(refObs, pnl); 264 } 265 } 266 } 267 268 public void setRefObjectByPanel(NamedBean refObs, LayoutEditor pnl) { 269 refObj = refObs; 270 if (pnl != null && refObj != null) { 271 if (refObj instanceof SignalMast || refObj instanceof Sensor) { 272 //String mast = ((SignalMast)refObj).getUserName(); 273 refLoc = pnl.getFinder().findPositionablePointByEastBoundBean(refObj); 274 if (refLoc == null) { 275 refLoc = pnl.getFinder().findPositionablePointByWestBoundBean(refObj); 276 } 277 if (refLoc == null) { 278 refLoc = pnl.getFinder().findLayoutTurnoutByBean(refObj); 279 } 280 if (refLoc == null) { 281 refLoc = pnl.getFinder().findLevelXingByBean(refObj); 282 } 283 if (refLoc == null) { 284 refLoc = pnl.getFinder().findLayoutSlipByBean(refObj); 285 } 286 if (refObj instanceof Sensor) { 287 setSensor((Sensor) refObj); 288 } 289 } else if (refObj instanceof SignalHead) { 290 String signal = ((SignalHead) refObj).getDisplayName(); 291 refLoc = pnl.getFinder().findPositionablePointByEastBoundSignal(signal); 292 if (refLoc == null) { 293 refLoc = pnl.getFinder().findPositionablePointByWestBoundSignal(signal); 294 } 295 } 296 } 297// if (refLoc != null) { 298// if (refLoc instanceof PositionablePoint) { 299// //((PositionablePoint)refLoc).addPropertyChangeListener(this); 300// } else if (refLoc instanceof LayoutTurnout) { //<== this includes LayoutSlips 301// //((LayoutTurnout)refLoc).addPropertyChangeListener(this); 302// } else if (refLoc instanceof LevelXing) { 303// //((LevelXing)refLoc).addPropertyChangeListener(this); 304// } 305// } 306 //With this set ref we can probably add a listener to it, so that we can detect when a change to the point details takes place 307 } 308 309 public NamedBean getRefObject() { 310 return refObj; 311 } 312 313 public Object getRefLocation() { 314 return refLoc; 315 } 316 317 //LayoutEditor getLayoutEditor() { return panel; } 318 public boolean isRouteToPointSet() { 319 return routeToSet; 320 } 321 322 public boolean isRouteFromPointSet() { 323 return routeFromSet; 324 } 325 326 public String getDisplayName() { 327 if (sensor != null) { 328 String description = sensor.getDisplayName(); 329 if (signalmast != null) { 330 description = description + " (" + signalmast.getDisplayName() + ")"; 331 } 332 return description; 333 } 334 335 if (refObj instanceof SignalMast) { 336 return ((SignalMast) refObj).getDisplayName(); 337 } else if (refObj instanceof Sensor) { 338 return ((Sensor) refObj).getDisplayName(); 339 } else if (refObj instanceof SignalHead) { 340 return ((SignalHead) refObj).getDisplayName(); 341 } 342 return "no display name"; // NOI18N 343 } 344 345 transient Thread nxButtonTimeOutThr; 346 347 void nxButtonTimeOut() { 348 if ((nxButtonTimeOutThr != null) && (nxButtonTimeOutThr.isAlive())) { 349 return; 350 } 351 extendedtime = true; 352 class ButtonTimeOut implements Runnable { 353 354 ButtonTimeOut() { 355 } 356 357 @Override 358 public void run() { 359 try { 360 //Stage one default timer for the button if no other button has been pressed 361 Thread.sleep(nxButtonTimeout * 1000L); 362 //Stage two if an extended time out has been requested 363 if (extendedtime) { 364 Thread.sleep(60000); //timeout after a minute waiting for the sml to set. 365 } 366 } catch (InterruptedException ex) { 367 log.debug("[nxButtonTimeOut] Flash timer cancelled"); // NOI18N 368 } 369 setNXButtonState(EntryExitPairs.NXBUTTONINACTIVE); 370 } 371 } 372 ButtonTimeOut t = new ButtonTimeOut(); 373 nxButtonTimeOutThr = jmri.util.ThreadingUtil.newThread(t, "NX Button Timeout " + getSensor().getDisplayName()); // NOI18N 374 375 nxButtonTimeOutThr.start(); 376 } 377 378 void cancelNXButtonTimeOut() { 379 if (nxButtonTimeOutThr != null) { 380 nxButtonTimeOutThr.interrupt(); 381 } 382 383 } 384 385 boolean extendedtime = false; 386 387 public void flashSensor() { 388 for (SensorIcon si : getPanel().getSensorList()) { 389 if (si.getSensor() == getSensor()) { 390 si.flashSensor(2, Sensor.ACTIVE, Sensor.INACTIVE); 391 } 392 } 393 } 394 395 public void stopFlashSensor() { 396 for (SensorIcon si : getPanel().getSensorList()) { 397 if (si.getSensor() == getSensor()) { 398 si.stopFlash(); 399 } 400 } 401 } 402 403 synchronized public void setNXButtonState(int state) { 404 if (getSensor() == null) { 405 return; 406 } 407 if (state == EntryExitPairs.NXBUTTONINACTIVE) { 408 //If a route is set to or from out point then we need to leave/set the sensor to ACTIVE 409 if (isRouteToPointSet()) { 410 state = EntryExitPairs.NXBUTTONACTIVE; 411 } else if (isRouteFromPointSet()) { 412 state = EntryExitPairs.NXBUTTONACTIVE; 413 } 414 } 415 setNXState(state); 416 int sensorState; 417 switch (state) { 418 case EntryExitPairs.NXBUTTONINACTIVE: 419 sensorState = Sensor.INACTIVE; 420 break; 421 case EntryExitPairs.NXBUTTONACTIVE: 422 sensorState = Sensor.ACTIVE; 423 break; 424 case EntryExitPairs.NXBUTTONSELECTED: 425 sensorState = Sensor.ACTIVE; 426 break; 427 default: 428 sensorState = Sensor.UNKNOWN; 429 break; 430 } 431 432 //Might need to clear listeners at the stage and then reapply them after. 433 if (getSensor().getKnownState() != sensorState) { 434 removeSensorList(); 435 try { 436 getSensor().setKnownState(sensorState); 437 } catch (jmri.JmriException ex) { 438 log.error("Could not set Sensor known state.", ex); 439 } 440 addSensorList(); 441 } 442 } 443 444 /** 445 * @since 4.17.6 446 * Making the source object available for scripting in Jython. 447 * @return the sensor. 448 */ 449 public Sensor getSensor() { 450 if (getRefObject() == null) { 451 return null; 452 } 453 if ((getPanel() != null) && (!getPanel().isEditable()) && (sensor != null)) { 454 return sensor; 455 } 456 457 if (getRefObject() instanceof Sensor) { 458 setSensor((Sensor) getRefObject()); 459 return (Sensor) getRefObject(); 460 } 461 Object objLoc = getRefLocation(); 462 Object objRef = getRefObject(); 463 SignalHead head = null; 464 SignalMast mast = null; 465 String username = ""; 466 String systemname = ""; 467 Sensor foundSensor = null; 468 if (objRef instanceof SignalMast) { 469 mast = (SignalMast) objRef; 470 } 471 if (objRef instanceof SignalHead) { 472 head = (SignalHead) objRef; 473 username = head.getUserName(); 474 systemname = head.getSystemName(); 475 } 476 jmri.SensorManager sm = InstanceManager.sensorManagerInstance(); 477 if (objLoc instanceof PositionablePoint) { 478 PositionablePoint p = (PositionablePoint) objLoc; 479 if (mast != null) { 480 if (p.getEastBoundSignalMast() == objRef) { 481 foundSensor = p.getEastBoundSensor(); 482 } else if (p.getWestBoundSignalMast() == objRef) { 483 foundSensor = p.getWestBoundSensor(); 484 } 485 } else if (head != null) { 486 if ((p.getEastBoundSignal().equals(username)) 487 || p.getEastBoundSignal().equals(systemname)) { 488 foundSensor = p.getEastBoundSensor(); 489 } else if ((p.getWestBoundSignal().equals(username)) 490 || p.getWestBoundSignal().equals(systemname)) { 491 foundSensor = p.getWestBoundSensor(); 492 } 493 } 494 } else if (objLoc instanceof LayoutSlip) { 495 LayoutSlip sl = (LayoutSlip) objLoc; 496 if (mast != null) { 497 if (sl.getSignalAMast() == objRef) { 498 foundSensor = sl.getSensorA(); 499 } else if (sl.getSignalBMast() == objRef) { 500 foundSensor = sl.getSensorB(); 501 } else if (sl.getSignalCMast() == objRef) { 502 foundSensor = sl.getSensorC(); 503 } else if (sl.getSignalDMast() == objRef) { 504 foundSensor = sl.getSensorD(); 505 } 506 } 507 if (head != null) { 508 if ((sl.getSignalA1Name().equals(username)) || (sl.getSignalA1Name().equals(systemname))) { 509 foundSensor = sm.getSensor(sl.getSensorAName()); 510 } else if ((sl.getSignalB1Name().equals(username)) || (sl.getSignalB1Name().equals(systemname))) { 511 foundSensor = sm.getSensor(sl.getSensorBName()); 512 } else if ((sl.getSignalC1Name().equals(username)) || (sl.getSignalC1Name().equals(systemname))) { 513 foundSensor = sm.getSensor(sl.getSensorCName()); 514 } else if ((sl.getSignalD1Name().equals(username)) || (sl.getSignalD1Name().equals(systemname))) { 515 foundSensor = sm.getSensor(sl.getSensorDName()); 516 } 517 } 518 } else //note: you have to do this after LayoutSlip 519 // because LayoutSlip extends LayoutTurnout 520 // (So a LayoutSlip would be an instance of LayoutTurnout.) 521 if (objLoc instanceof LayoutTurnout) { //<== this includes LayoutSlips 522 LayoutTurnout t = (LayoutTurnout) objLoc; 523 if (mast != null) { 524 if (t.getSignalAMast() == objRef) { 525 foundSensor = t.getSensorA(); 526 } else if (t.getSignalBMast() == objRef) { 527 foundSensor = t.getSensorB(); 528 } else if (t.getSignalCMast() == objRef) { 529 foundSensor = t.getSensorC(); 530 } else if (t.getSignalDMast() == objRef) { 531 foundSensor = t.getSensorD(); 532 } 533 } 534 if (head != null) { 535 if ((t.getSignalA1Name().equals(username)) || (t.getSignalA1Name().equals(systemname))) { 536 foundSensor = t.getSensorA(); 537 } else if ((t.getSignalA2Name().equals(username)) || (t.getSignalA2Name().equals(systemname))) { 538 foundSensor = t.getSensorA(); 539 } else if ((t.getSignalA3Name().equals(username)) || (t.getSignalA3Name().equals(systemname))) { 540 foundSensor = t.getSensorA(); 541 } else if ((t.getSignalB1Name().equals(username)) || (t.getSignalB1Name().equals(systemname))) { 542 foundSensor = t.getSensorB(); 543 } else if ((t.getSignalB2Name().equals(username)) || (t.getSignalB2Name().equals(systemname))) { 544 foundSensor = t.getSensorB(); 545 } else if ((t.getSignalC1Name().equals(username)) || (t.getSignalC1Name().equals(systemname))) { 546 foundSensor = t.getSensorC(); 547 } else if ((t.getSignalC2Name().equals(username)) || (t.getSignalC2Name().equals(systemname))) { 548 foundSensor = t.getSensorC(); 549 } else if ((t.getSignalD1Name().equals(username)) || (t.getSignalD1Name().equals(systemname))) { 550 foundSensor = t.getSensorD(); 551 } else if ((t.getSignalD2Name().equals(username)) || (t.getSignalD2Name().equals(systemname))) { 552 foundSensor = t.getSensorD(); 553 } 554 } 555 } else if (objLoc instanceof LevelXing) { 556 LevelXing x = (LevelXing) objLoc; 557 if (mast != null) { 558 if (x.getSignalAMast() == objRef) { 559 foundSensor = x.getSensorA(); 560 } else if (x.getSignalBMast() == objRef) { 561 foundSensor = x.getSensorB(); 562 } else if (x.getSignalCMast() == objRef) { 563 foundSensor = x.getSensorC(); 564 } else if (x.getSignalDMast() == objRef) { 565 foundSensor = x.getSensorD(); 566 } 567 } 568 if (head != null) { 569 if ((x.getSignalAName().equals(username)) || (x.getSignalAName().equals(systemname))) { 570 foundSensor = x.getSensorA(); 571 } else if ((x.getSignalBName().equals(username)) || (x.getSignalBName().equals(systemname))) { 572 foundSensor = x.getSensorB(); 573 } else if ((x.getSignalCName().equals(username)) || (x.getSignalCName().equals(systemname))) { 574 foundSensor = x.getSensorC(); 575 } else if ((x.getSignalDName().equals(username)) || (x.getSignalDName().equals(systemname))) { 576 foundSensor = x.getSensorD(); 577 } 578 } 579 } 580 setSensor(foundSensor); 581 return foundSensor; 582 } 583 584 NamedBean getSignal() { 585 if ((getPanel() != null) && (!getPanel().isEditable()) && (getSignalMast() != null)) { 586 return getSignalMast(); 587 } 588 if ((getPanel() != null) && (!getPanel().isEditable()) && (getSignalHead() != null)) { 589 return getSignalHead(); 590 } 591 jmri.SignalHeadManager sh = InstanceManager.getDefault(jmri.SignalHeadManager.class); 592 NamedBean signal = null; 593 594 if (getRefObject() == null) { 595 log.error("Signal not found at point"); // NOI18N 596 return null; 597 } else if (getRefObject() instanceof SignalMast) { 598 signal = getRefObject(); 599 setSignalMast(((SignalMast) getRefObject())); 600 return signal; 601 } else if (getRefObject() instanceof SignalHead) { 602 signal = getRefObject(); 603 setSignalHead(((SignalHead) getRefObject())); 604 return signal; 605 } 606 607 Sensor sen = (Sensor) getRefObject(); 608 log.debug(" Looking at sensor '{}' on panel '{}' at '{}'", 609 sen.getDisplayName(), getPanel().getLayoutName(), getRefLocation()); 610 if (getRefLocation() instanceof PositionablePoint) { 611 PositionablePoint p = (PositionablePoint) getRefLocation(); 612 if (p.getEastBoundSensor() == sen) { 613 if (p.getEastBoundSignalMast() != null) { 614 signal = p.getEastBoundSignalMast(); 615 } else if (!p.getEastBoundSignal().isEmpty()) { 616 signal = sh.getSignalHead(p.getEastBoundSignal()); 617 } 618 } else if (p.getWestBoundSensor() == sen) { 619 if (p.getWestBoundSignalMast() != null) { 620 signal = p.getWestBoundSignalMast(); 621 } else if (!p.getWestBoundSignal().isEmpty()) { 622 signal = sh.getSignalHead(p.getWestBoundSignal()); 623 } 624 } 625 } else if (getRefLocation() instanceof LayoutSlip) { 626 LayoutSlip t = (LayoutSlip) getRefLocation(); 627 if (t.getSensorA() == sen) { 628 if (t.getSignalAMast() != null) { 629 signal = t.getSignalAMast(); 630 } else if (!t.getSignalA1Name().isEmpty()) { 631 signal = sh.getSignalHead(t.getSignalA1Name()); 632 } 633 } else if (t.getSensorB() == sen) { 634 if (t.getSignalBMast() != null) { 635 signal = t.getSignalBMast(); 636 } else if (!t.getSignalB1Name().isEmpty()) { 637 signal = sh.getSignalHead(t.getSignalB1Name()); 638 } 639 } else if (t.getSensorC() == sen) { 640 if (t.getSignalCMast() != null) { 641 signal = t.getSignalCMast(); 642 } else if (!t.getSignalC1Name().isEmpty()) { 643 signal = sh.getSignalHead(t.getSignalC1Name()); 644 } 645 } else if (t.getSensorD() == sen) { 646 if (t.getSignalDMast() != null) { 647 signal = t.getSignalDMast(); 648 } else if (!t.getSignalD1Name().isEmpty()) { 649 signal = sh.getSignalHead(t.getSignalD1Name()); 650 } 651 } 652 } else //note: you have to do this after LayoutSlip 653 // because LayoutSlip extends LayoutTurnout 654 // (So a LayoutSlip would be an instance of LayoutTurnout.) 655 if (getRefLocation() instanceof LayoutTurnout) { //<== this includes LayoutSlips 656 LayoutTurnout t = (LayoutTurnout) getRefLocation(); 657 if (t.getSensorA() == sen) { 658 if (t.getSignalAMast() != null) { 659 signal = t.getSignalAMast(); 660 } else if (!t.getSignalA1Name().isEmpty()) { 661 signal = sh.getSignalHead(t.getSignalA1Name()); 662 } 663 } else if (t.getSensorB() == sen) { 664 if (t.getSignalBMast() != null) { 665 signal = t.getSignalBMast(); 666 } else if (!t.getSignalB1Name().isEmpty()) { 667 signal = sh.getSignalHead(t.getSignalB1Name()); 668 } 669 } else if (t.getSensorC() == sen) { 670 if (t.getSignalCMast() != null) { 671 signal = t.getSignalCMast(); 672 } else if (!t.getSignalC1Name().isEmpty()) { 673 signal = sh.getSignalHead(t.getSignalC1Name()); 674 } 675 } else if (t.getSensorD() == sen) { 676 if (t.getSignalDMast() != null) { 677 signal = t.getSignalDMast(); 678 } else if (!t.getSignalD1Name().isEmpty()) { 679 signal = sh.getSignalHead(t.getSignalD1Name()); 680 } 681 } 682 } else if (getRefLocation() instanceof LevelXing) { 683 LevelXing x = (LevelXing) getRefLocation(); 684 if (x.getSensorA() == sen) { 685 if (x.getSignalAMast() != null) { 686 signal = x.getSignalAMast(); 687 } else if (!x.getSignalAName().isEmpty()) { 688 signal = sh.getSignalHead(x.getSignalAName()); 689 } 690 } else if (x.getSensorB() == sen) { 691 if (x.getSignalBMast() != null) { 692 signal = x.getSignalBMast(); 693 } else if (!x.getSignalBName().isEmpty()) { 694 signal = sh.getSignalHead(x.getSignalBName()); 695 } 696 } else if (x.getSensorC() == sen) { 697 if (x.getSignalCMast() != null) { 698 signal = x.getSignalCMast(); 699 } else if (!x.getSignalCName().isEmpty()) { 700 signal = sh.getSignalHead(x.getSignalCName()); 701 } 702 } else if (x.getSensorD() == sen) { 703 if (x.getSignalDMast() != null) { 704 signal = x.getSignalDMast(); 705 } else if (!x.getSignalDName().isEmpty()) { 706 signal = sh.getSignalHead(x.getSignalDName()); 707 } 708 } 709 } 710 711 if (signal instanceof SignalMast) { 712 setSignalMast(((SignalMast) signal)); 713 } else if (signal instanceof SignalHead) { 714 setSignalHead(((SignalHead) signal)); 715 } 716 return signal; 717 } 718 719 @Override 720 public boolean equals(Object obj) { 721 if (obj == this) { 722 return true; 723 } 724 if (obj == null) { 725 return false; 726 } 727 728 if (!(getClass() == obj.getClass())) { 729 return false; 730 } else { 731 PointDetails tmp = (PointDetails) obj; 732 if (tmp.getFacing() != this.facing) { 733 return false; 734 } 735 if (!tmp.getProtecting().equals(this.protectingBlocks)) { 736 return false; 737 } 738 if (tmp.getPanel() != this.panel) { 739 return false; 740 } 741 } 742 return true; 743 } 744 745 @Override 746 public int hashCode() { 747 int hash = 7; 748 hash = 37 * hash + (this.panel != null ? this.panel.hashCode() : 0); 749 hash = 37 * hash + (this.facing != null ? this.facing.hashCode() : 0); 750 hash = 37 * hash + (this.protectingBlocks != null ? this.protectingBlocks.hashCode() : 0); 751 return hash; 752 } 753 754 java.beans.PropertyChangeSupport pcs = new java.beans.PropertyChangeSupport(this); 755 756 public synchronized void addPropertyChangeListener(java.beans.PropertyChangeListener l) { 757 pcs.addPropertyChangeListener(l); 758 } 759 760 public synchronized void removePropertyChangeListener(java.beans.PropertyChangeListener l) { 761 pcs.removePropertyChangeListener(l); 762 } 763 764 protected void firePropertyChange(String p, Object old, Object n) { 765 pcs.firePropertyChange(p, old, n); 766 } 767 768 private final static Logger log = LoggerFactory.getLogger(PointDetails.class); 769}