001package jmri.jmrit.display.layoutEditor; 002 003import java.awt.Color; 004import java.awt.Graphics2D; 005import java.awt.event.ActionEvent; 006import java.awt.geom.*; 007import static java.lang.Float.POSITIVE_INFINITY; 008import static java.lang.Math.PI; 009import java.util.*; 010 011import javax.annotation.Nonnull; 012import javax.swing.*; 013 014import jmri.*; 015import jmri.jmrit.display.layoutEditor.LevelXing.Geometry; 016import jmri.jmrit.display.layoutEditor.blockRoutingTable.LayoutBlockRouteTableAction; 017import jmri.util.MathUtil; 018import jmri.util.swing.JmriMouseEvent; 019 020/** 021 * MVC View component for the LevelXing class 022 * 023 * @author Bob Jacobsen Copyright (c) 2020 024 * 025 */ 026public class LevelXingView extends LayoutTrackView { 027 028 /** 029 * Constructor method. 030 * @param xing the level crossing. 031 * @param layoutEditor for access to tools 032 */ 033 public LevelXingView(@Nonnull LevelXing xing, @Nonnull LayoutEditor layoutEditor) { 034 super(xing, layoutEditor); 035 036 this.xing = xing; 037 editor = new jmri.jmrit.display.layoutEditor.LayoutEditorDialogs.LevelXingEditor(layoutEditor); 038 } 039 040 /** 041 * constructor method 042 * @param xing the level crossing. 043 * @param c display location 044 * @param layoutEditor for access to tools 045 */ 046 public LevelXingView(@Nonnull LevelXing xing, @Nonnull Point2D c, @Nonnull LayoutEditor layoutEditor) { 047 super(xing, c, layoutEditor); 048 049 this.xing = xing; 050 editor = new jmri.jmrit.display.layoutEditor.LayoutEditorDialogs.LevelXingEditor(layoutEditor); 051 } 052 053 private Point2D dispA = new Point2D.Double(-20.0, 0.0); 054 private Point2D dispB = new Point2D.Double(-14.0, 14.0); 055 056 // temporary reference to the Editor that will eventually be part of View 057 private final jmri.jmrit.display.layoutEditor.LayoutEditorDialogs.LevelXingEditor editor; 058 059 final private LevelXing xing; 060 061 // temporary? 062 @Nonnull 063 public LevelXing getLevelXing() { return xing; } 064 065 // this should only be used for debugging 066 @Override 067 public String toString() { 068 return "LevelXing " + getName(); 069 } 070 071 /* 072 * Accessor methods 073 */ 074 @Nonnull 075 public String getBlockNameAC() { 076 return xing.getBlockNameAC(); 077 } 078 079 @Nonnull 080 public String getBlockNameBD() { 081 return xing.getBlockNameBD(); 082 } 083 084 public SignalHead getSignalHead(Geometry loc) { 085 return xing.getSignalHead(loc); 086 } 087 088 public SignalMast getSignalMast(Geometry loc) { 089 return xing.getSignalMast(loc); 090 } 091 092 public Sensor getSensor(Geometry loc) { 093 return xing.getSensor(loc); 094 } 095 096 @Nonnull 097 public String getSignalAName() { 098 return xing.getSignalAName(); 099 } 100 101 public void setSignalAName(String signalHead) { 102 xing.setSignalAName(signalHead); 103 } 104 105 @Nonnull 106 public String getSignalBName() { 107 return xing.getSignalBName(); 108 } 109 110 public void setSignalBName(String signalHead) { 111 xing.setSignalBName(signalHead); 112 } 113 114 @Nonnull 115 public String getSignalCName() { 116 return xing.getSignalCName(); 117 } 118 119 public void setSignalCName(String signalHead) { 120 xing.setSignalCName(signalHead); 121 } 122 123 @Nonnull 124 public String getSignalDName() { 125 return xing.getSignalDName(); 126 } 127 128 public void setSignalDName(String signalHead) { 129 xing.setSignalDName(signalHead); 130 } 131 132 public void removeBeanReference(jmri.NamedBean nb) { 133 xing.removeBeanReference(nb); 134 } 135 136 public String getSignalAMastName() { 137 return xing.getSignalAMastName(); 138 } 139 140 public SignalMast getSignalAMast() { 141 return xing.getSignalAMast(); 142 } 143 144 public void setSignalAMast(String signalMast) { 145 xing.setSignalAMast(signalMast); 146 } 147 148 public String getSignalBMastName() { 149 return xing.getSignalBMastName(); 150 } 151 152 public SignalMast getSignalBMast() { 153 return xing.getSignalBMast(); 154 } 155 156 public void setSignalBMast(String signalMast) { 157 xing.setSignalBMast(signalMast); 158 } 159 160 public String getSignalCMastName() { 161 return xing.getSignalCMastName(); 162 } 163 164 public SignalMast getSignalCMast() { 165 return xing.getSignalCMast(); 166 } 167 168 public void setSignalCMast(String signalMast) { 169 xing.setSignalCMast(signalMast); 170 } 171 172 public String getSignalDMastName() { 173 return xing.getSignalDMastName(); 174 } 175 176 public SignalMast getSignalDMast() { 177 return xing.getSignalDMast(); 178 } 179 180 public void setSignalDMast(String signalMast) { 181 xing.setSignalDMast(signalMast); 182 } 183 184 public String getSensorAName() { 185 return xing.getSensorAName(); 186 } 187 188 public Sensor getSensorA() { 189 return xing.getSensorA(); 190 } 191 192 public void setSensorAName(String sensorName) { 193 xing.setSensorAName(sensorName); 194 } 195 196 public String getSensorBName() { 197 return xing.getSensorBName(); 198 } 199 200 public Sensor getSensorB() { 201 return xing.getSensorB(); 202 } 203 204 public void setSensorBName(String sensorName) { 205 xing.setSensorBName(sensorName); 206 } 207 208 public String getSensorCName() { 209 return xing.getSensorCName(); 210 } 211 212 public Sensor getSensorC() { 213 return xing.getSensorC(); 214 } 215 216 public void setSensorCName(String sensorName) { 217 xing.setSensorCName(sensorName); 218 } 219 220 public String getSensorDName() { 221 return xing.getSensorDName(); 222 } 223 224 public Sensor getSensorD() { 225 return xing.getSensorD(); 226 } 227 228 public void setSensorDName(String sensorName) { 229 xing.setSensorDName(sensorName); 230 } 231 232 /** 233 * {@inheritDoc} 234 */ 235 @Override 236 public LayoutTrack getConnection(HitPointType connectionType) throws jmri.JmriException { 237 return xing.getConnection(connectionType); 238 } 239 240 /** 241 * {@inheritDoc} 242 */ 243 @Override 244 public void setConnection(HitPointType connectionType, LayoutTrack o, HitPointType type) throws jmri.JmriException { 245 xing.setConnection(connectionType, o, type); 246 } 247 248 public LayoutTrack getConnectA() { 249 return xing.getConnectA(); 250 } 251 252 public LayoutTrack getConnectB() { 253 return xing.getConnectB(); 254 } 255 256 public LayoutTrack getConnectC() { 257 return xing.getConnectC(); 258 } 259 260 public LayoutTrack getConnectD() { 261 return xing.getConnectD(); 262 } 263 264 public void setConnectA(LayoutTrack o, HitPointType type) { 265 xing.setConnectA(o, type); 266 } 267 268 public void setConnectB(LayoutTrack o, HitPointType type) { 269 xing.setConnectB(o, type); 270 } 271 272 public void setConnectC(LayoutTrack o, HitPointType type) { 273 xing.setConnectC(o, type); 274 } 275 276 public void setConnectD(LayoutTrack o, HitPointType type) { 277 xing.setConnectD(o, type); 278 } 279 280 public LayoutBlock getLayoutBlockAC() { 281 return xing.getLayoutBlockAC(); 282 } 283 284 public LayoutBlock getLayoutBlockBD() { 285 return xing.getLayoutBlockBD(); 286 } 287 288 289 290 public Point2D getCoordsA() { 291 return MathUtil.add(getCoordsCenter(), dispA); 292 } 293 294 public Point2D getCoordsB() { 295 return MathUtil.add(getCoordsCenter(), dispB); 296 } 297 298 public Point2D getCoordsC() { 299 return MathUtil.subtract(getCoordsCenter(), dispA); 300 } 301 302 public Point2D getCoordsD() { 303 return MathUtil.subtract(getCoordsCenter(), dispB); 304 } 305 306 /** 307 * Get the coordinates for a specified connection type. 308 * 309 * @param connectionType the connection type 310 * @return the coordinates for the specified connection type 311 */ 312 @Override 313 public Point2D getCoordsForConnectionType(HitPointType connectionType) { 314 Point2D result = getCoordsCenter(); 315 switch (connectionType) { 316 case LEVEL_XING_CENTER: 317 break; 318 case LEVEL_XING_A: 319 result = getCoordsA(); 320 break; 321 case LEVEL_XING_B: 322 result = getCoordsB(); 323 break; 324 case LEVEL_XING_C: 325 result = getCoordsC(); 326 break; 327 case LEVEL_XING_D: 328 result = getCoordsD(); 329 break; 330 default: 331 log.error("{}.getCoordsForConnectionType({}); Invalid connection type ", 332 getName(), connectionType); //I18IN 333 } 334 return result; 335 } 336 337 /** 338 * @return the bounds of this crossing 339 */ 340 @Override 341 public Rectangle2D getBounds() { 342 Rectangle2D result; 343 344 Point2D pointA = getCoordsA(); 345 result = new Rectangle2D.Double(pointA.getX(), pointA.getY(), 0, 0); 346 result.add(getCoordsB()); 347 result.add(getCoordsC()); 348 result.add(getCoordsD()); 349 return result; 350 } 351 352 /** 353 * Add Layout Blocks. 354 */ 355// @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Null is accepted as a valid value") 356// public void setLayoutBlockAC(LayoutBlock newLayoutBlock) { 357// LayoutBlock blockAC = getLayoutBlockAC(); 358// LayoutBlock blockBD = getLayoutBlockBD(); 359// if (blockAC != newLayoutBlock) { 360// // block 1 has changed, if old block exists, decrement use 361// if ((blockAC != null) && (blockAC != blockBD)) { 362// blockAC.decrementUse(); 363// } 364// blockAC = newLayoutBlock; 365// if (newLayoutBlock != null) { 366// namedLayoutBlockAC = InstanceManager.getDefault(jmri.NamedBeanHandleManager.class).getNamedBeanHandle(newLayoutBlock.getUserName(), newLayoutBlock); 367// } else { 368// namedLayoutBlockAC = null; 369// } 370// 371// // decrement use if block was previously counted 372// if ((blockAC != null) && (blockAC == blockBD)) { 373// blockAC.decrementUse(); 374// } 375// } 376// } 377 378// @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Null is accepted as a valid value") 379// public void setLayoutBlockBD(LayoutBlock newLayoutBlock) { 380// LayoutBlock blockAC = getLayoutBlockAC(); 381// LayoutBlock blockBD = getLayoutBlockBD(); 382// if (blockBD != newLayoutBlock) { 383// // block 1 has changed, if old block exists, decrement use 384// if ((blockBD != null) && (blockBD != blockAC)) { 385// blockBD.decrementUse(); 386// } 387// blockBD = newLayoutBlock; 388// if (newLayoutBlock != null) { 389// namedLayoutBlockBD = InstanceManager.getDefault(jmri.NamedBeanHandleManager.class).getNamedBeanHandle(newLayoutBlock.getUserName(), newLayoutBlock); 390// } else { 391// namedLayoutBlockBD = null; 392// } 393// // decrement use if block was previously counted 394// if ((blockBD != null) && (blockBD == blockAC)) { 395// blockBD.decrementUse(); 396// } 397// } 398// 399// } 400// 401// public void updateBlockInfo() { 402// LayoutBlock blockAC = getLayoutBlockAC(); 403// LayoutBlock blockBD = getLayoutBlockBD(); 404// LayoutBlock b1 = null; 405// LayoutBlock b2 = null; 406// if (blockAC != null) { 407// blockAC.updatePaths(); 408// } 409// if (connectA != null) { 410// b1 = ((TrackSegment) connectA).getLayoutBlock(); 411// if ((b1 != null) && (b1 != blockAC)) { 412// b1.updatePaths(); 413// } 414// } 415// if (connectC != null) { 416// b2 = ((TrackSegment) connectC).getLayoutBlock(); 417// if ((b2 != null) && (b2 != blockAC) && (b2 != b1)) { 418// b2.updatePaths(); 419// } 420// } 421// if (blockBD != null) { 422// blockBD.updatePaths(); 423// } 424// if (connectB != null) { 425// b1 = ((TrackSegment) connectB).getLayoutBlock(); 426// if ((b1 != null) && (b1 != blockBD)) { 427// b1.updatePaths(); 428// } 429// } 430// if (connectD != null) { 431// b2 = ((TrackSegment) connectD).getLayoutBlock(); 432// if ((b2 != null) && (b2 != blockBD) && (b2 != b1)) { 433// b2.updatePaths(); 434// } 435// } 436// reCheckBlockBoundary(); 437// } 438// 439// void removeSML(SignalMast signalMast) { 440// if (signalMast == null) { 441// return; 442// } 443// if (jmri.InstanceManager.getDefault(LayoutBlockManager.class).isAdvancedRoutingEnabled() && InstanceManager.getDefault(jmri.SignalMastLogicManager.class).isSignalMastUsed(signalMast)) { 444// SignallingGuiTools.removeSignalMastLogic(null, signalMast); 445// } 446// } 447 448 /** 449 * Test if mainline track or not. 450 * 451 * @return true if either connecting track segment is mainline; Defaults to 452 * not mainline if connecting track segments are missing 453 */ 454 public boolean isMainlineAC() { 455 return xing.isMainlineAC(); 456 } 457 458 public boolean isMainlineBD() { 459 return xing.isMainlineBD(); 460 } 461 462 /* 463 * Modify coordinates methods. 464 */ 465 public void setCoordsA(Point2D p) { 466 dispA = MathUtil.subtract(p, getCoordsCenter()); 467 } 468 469 public void setCoordsB(Point2D p) { 470 dispB = MathUtil.subtract(p, getCoordsCenter()); 471 } 472 473 public void setCoordsC(Point2D p) { 474 dispA = MathUtil.subtract(getCoordsCenter(), p); 475 } 476 477 public void setCoordsD(Point2D p) { 478 dispB = MathUtil.subtract(getCoordsCenter(), p); 479 } 480 481 /** 482 * {@inheritDoc} 483 */ 484 @Override 485 public void scaleCoords(double xFactor, double yFactor) { 486 Point2D factor = new Point2D.Double(xFactor, yFactor); 487 super.setCoordsCenter(MathUtil.granulize(MathUtil.multiply(getCoordsCenter(), factor), 1.0)); 488 dispA = MathUtil.granulize(MathUtil.multiply(dispA, factor), 1.0); 489 dispB = MathUtil.granulize(MathUtil.multiply(dispB, factor), 1.0); 490 } 491 492 /** 493 * {@inheritDoc} 494 */ 495 @Override 496 public void translateCoords(double xFactor, double yFactor) { 497 Point2D factor = new Point2D.Double(xFactor, yFactor); 498 super.setCoordsCenter(MathUtil.add(getCoordsCenter(), factor)); 499 } 500 501 /** 502 * {@inheritDoc} 503 */ 504 @Override 505 public void rotateCoords(double angleDEG) { 506 // rotate coordinates 507 double rotRAD = Math.toRadians(angleDEG); 508 double sineRot = Math.sin(rotRAD); 509 double cosineRot = Math.cos(rotRAD); 510 511 // rotate displacements around origin {0, 0} 512 Point2D center_temp = getCoordsCenter(); 513 super.setCoordsCenter(MathUtil.zeroPoint2D); 514 dispA = rotatePoint(dispA, sineRot, cosineRot); 515 dispB = rotatePoint(dispB, sineRot, cosineRot); 516 super.setCoordsCenter(center_temp); 517 518 } 519 520 /** 521 * {@inheritDoc} 522 */ 523 @Override 524 protected HitPointType findHitPointType(Point2D hitPoint, boolean useRectangles, boolean requireUnconnected) { 525 HitPointType result = HitPointType.NONE; // assume point not on connection 526 //note: optimization here: instead of creating rectangles for all the 527 // points to check below, we create a rectangle for the test point 528 // and test if the points below are in that rectangle instead. 529 Rectangle2D r = trackControlCircleRectAt(hitPoint); 530 Point2D p, minPoint = MathUtil.zeroPoint2D; 531 532 double circleRadius = LayoutEditor.SIZE * layoutEditor.getTurnoutCircleSize(); 533 double distance, minDistance = POSITIVE_INFINITY; 534 535 //check the center point 536 if (!requireUnconnected) { 537 p = getCoordsCenter(); 538 distance = MathUtil.distance(p, hitPoint); 539 if (distance < minDistance) { 540 minDistance = distance; 541 minPoint = p; 542 result = HitPointType.LEVEL_XING_CENTER; 543 } 544 } 545 546 //check the A connection point 547 if (!requireUnconnected || (getConnectA() == null)) { 548 p = getCoordsA(); 549 distance = MathUtil.distance(p, hitPoint); 550 if (distance < minDistance) { 551 minDistance = distance; 552 minPoint = p; 553 result = HitPointType.LEVEL_XING_A; 554 } 555 } 556 557 //check the B connection point 558 if (!requireUnconnected || (getConnectB() == null)) { 559 p = getCoordsB(); 560 distance = MathUtil.distance(p, hitPoint); 561 if (distance < minDistance) { 562 minDistance = distance; 563 minPoint = p; 564 result = HitPointType.LEVEL_XING_B; 565 } 566 } 567 568 //check the C connection point 569 if (!requireUnconnected || (getConnectC() == null)) { 570 p = getCoordsC(); 571 distance = MathUtil.distance(p, hitPoint); 572 if (distance < minDistance) { 573 minDistance = distance; 574 minPoint = p; 575 result = HitPointType.LEVEL_XING_C; 576 } 577 } 578 579 //check the D connection point 580 if (!requireUnconnected || (getConnectD() == null)) { 581 p = getCoordsD(); 582 distance = MathUtil.distance(p, hitPoint); 583 if (distance < minDistance) { 584 minDistance = distance; 585 minPoint = p; 586 result = HitPointType.LEVEL_XING_D; 587 } 588 } 589 if ((useRectangles && !r.contains(minPoint)) 590 || (!useRectangles && (minDistance > circleRadius))) { 591 result = HitPointType.NONE; 592 } 593 return result; 594 } // findHitPointType 595 596 // initialization instance variables (used when loading a LayoutEditor) 597// public String connectAName = ""; 598// public String connectBName = ""; 599// public String connectCName = ""; 600// public String connectDName = ""; 601// 602// public String tLayoutBlockNameAC = ""; 603// public String tLayoutBlockNameBD = ""; 604 605 /** 606 * {@inheritDoc} 607 */ 608 @Override 609 public boolean canRemove() { 610 return xing.canRemove(); 611 } 612 613// * 614// * Build a list of sensors, signal heads, and signal masts attached to a 615// * level crossing point. 616// * 617// * @param pointName Specify the point (A-D) or all (All) points. 618// * @return a list of bean reference names. 619// */ 620// public ArrayList<String> getBeanReferences(String pointName) { 621// ArrayList<String> references = new ArrayList<>(); 622// if (pointName.equals("A") || pointName.equals("All")) { // NOI18N 623// if (!getSignalAMastName().isEmpty()) { 624// references.add(getSignalAMastName()); 625// } 626// if (!getSensorAName().isEmpty()) { 627// references.add(getSensorAName()); 628// } 629// if (!getSignalAName().isEmpty()) { 630// references.add(getSignalAName()); 631// } 632// } 633// if (pointName.equals("B") || pointName.equals("All")) { // NOI18N 634// if (!getSignalBMastName().isEmpty()) { 635// references.add(getSignalBMastName()); 636// } 637// if (!getSensorBName().isEmpty()) { 638// references.add(getSensorBName()); 639// } 640// if (!getSignalBName().isEmpty()) { 641// references.add(getSignalBName()); 642// } 643// } 644// if (pointName.equals("C") || pointName.equals("All")) { // NOI18N 645// if (!getSignalCMastName().isEmpty()) { 646// references.add(getSignalCMastName()); 647// } 648// if (!getSensorCName().isEmpty()) { 649// references.add(getSensorCName()); 650// } 651// if (!getSignalCName().isEmpty()) { 652// references.add(getSignalCName()); 653// } 654// } 655// if (pointName.equals("D") || pointName.equals("All")) { // NOI18N 656// if (!getSignalDMastName().isEmpty()) { 657// references.add(getSignalDMastName()); 658// } 659// if (!getSensorDName().isEmpty()) { 660// references.add(getSensorDName()); 661// } 662// if (!getSignalDName().isEmpty()) { 663// references.add(getSignalDName()); 664// } 665// } 666// return references; 667// } 668 669 JPopupMenu popup = null; 670 671 /** 672 * {@inheritDoc} 673 */ 674 @Override 675 @Nonnull 676 protected JPopupMenu showPopup(@Nonnull JmriMouseEvent mouseEvent) { 677 if (popup != null) { 678 popup.removeAll(); 679 } else { 680 popup = new JPopupMenu(); 681 } 682 if (layoutEditor.isEditable()) { 683 JMenuItem jmi = popup.add(Bundle.getMessage("MakeLabel", Bundle.getMessage("LevelCrossing")) + getName()); 684 jmi.setEnabled(false); 685 686 boolean blockACAssigned = false; 687 boolean blockBDAssigned = false; 688 if (getLayoutBlockAC() == null) { 689 jmi = popup.add(Bundle.getMessage("NoBlockX", "AC")); 690 } else { 691 jmi = popup.add(Bundle.getMessage("MakeLabel", Bundle.getMessage("Block_ID", "AC")) + getLayoutBlockAC().getDisplayName()); 692 blockACAssigned = true; 693 } 694 jmi.setEnabled(false); 695 696 if (getLayoutBlockBD() == null) { 697 jmi = popup.add(Bundle.getMessage("NoBlockX", "BD")); 698 } else { 699 jmi = popup.add(Bundle.getMessage("MakeLabel", Bundle.getMessage("Block_ID", "BD")) + getLayoutBlockBD().getDisplayName()); 700 blockBDAssigned = true; 701 } 702 jmi.setEnabled(false); 703 704 // if there are any track connections 705 if ((getConnectA() != null) || (getConnectB() != null) 706 || (getConnectC() != null) || (getConnectD() != null)) { 707 JMenu connectionsMenu = new JMenu(Bundle.getMessage("Connections")); // there is no pane opening (which is what ... implies) 708 if (getConnectA() != null) { 709 connectionsMenu.add(new AbstractAction(Bundle.getMessage("MakeLabel", "A") + getConnectA().getName()) { 710 @Override 711 public void actionPerformed(ActionEvent e) { 712 LayoutEditorFindItems lf = layoutEditor.getFinder(); 713 LayoutTrack lt = lf.findObjectByName(getConnectA().getName()); 714 // this shouldn't ever be null... however... 715 if (lt != null) { 716 LayoutTrackView ltv = layoutEditor.getLayoutTrackView(lt); 717 layoutEditor.setSelectionRect(ltv.getBounds()); 718 ltv.showPopup(); 719 } 720 } 721 }); 722 } 723 if (getConnectB() != null) { 724 connectionsMenu.add(new AbstractAction(Bundle.getMessage("MakeLabel", "B") + getConnectB().getName()) { 725 @Override 726 public void actionPerformed(ActionEvent e) { 727 LayoutEditorFindItems lf = layoutEditor.getFinder(); 728 LayoutTrack lt = lf.findObjectByName(getConnectB().getName()); 729 // this shouldn't ever be null... however... 730 if (lt != null) { 731 LayoutTrackView ltv = layoutEditor.getLayoutTrackView(lt); 732 layoutEditor.setSelectionRect(ltv.getBounds()); 733 ltv.showPopup(); 734 } 735 } 736 }); 737 } 738 if (getConnectC() != null) { 739 connectionsMenu.add(new AbstractAction(Bundle.getMessage("MakeLabel", "C") + getConnectC().getName()) { 740 @Override 741 public void actionPerformed(ActionEvent e) { 742 LayoutEditorFindItems lf = layoutEditor.getFinder(); 743 LayoutTrack lt = lf.findObjectByName(getConnectC().getName()); 744 // this shouldn't ever be null... however... 745 if (lt != null) { 746 LayoutTrackView ltv = layoutEditor.getLayoutTrackView(lt); 747 layoutEditor.setSelectionRect(ltv.getBounds()); 748 ltv.showPopup(); 749 } 750 } 751 }); 752 } 753 if (getConnectD() != null) { 754 connectionsMenu.add(new AbstractAction(Bundle.getMessage("MakeLabel", "D") + getConnectD().getName()) { 755 @Override 756 public void actionPerformed(ActionEvent e) { 757 LayoutEditorFindItems lf = layoutEditor.getFinder(); 758 LayoutTrack lt = lf.findObjectByName(getConnectD().getName()); 759 // this shouldn't ever be null... however... 760 if (lt != null) { 761 LayoutTrackView ltv = layoutEditor.getLayoutTrackView(lt); 762 layoutEditor.setSelectionRect(ltv.getBounds()); 763 ltv.showPopup(); 764 } 765 } 766 }); 767 } 768 popup.add(connectionsMenu); 769 } 770 771 popup.add(new JSeparator(JSeparator.HORIZONTAL)); 772 773 JCheckBoxMenuItem hiddenCheckBoxMenuItem = new JCheckBoxMenuItem(Bundle.getMessage("Hidden")); 774 hiddenCheckBoxMenuItem.setSelected(isHidden()); 775 popup.add(hiddenCheckBoxMenuItem); 776 hiddenCheckBoxMenuItem.addActionListener((java.awt.event.ActionEvent e3) -> setHidden(hiddenCheckBoxMenuItem.isSelected())); 777 778 popup.add(new AbstractAction(Bundle.getMessage("ButtonEdit")) { 779 @Override 780 public void actionPerformed(ActionEvent e) { 781 editor.editLayoutTrack(LevelXingView.this); 782 } 783 }); 784 popup.add(new AbstractAction(Bundle.getMessage("ButtonDelete")) { 785 @Override 786 public void actionPerformed(ActionEvent e) { 787 if (canRemove() && removeInlineLogixNG() 788 && layoutEditor.removeLevelXing(xing)) { 789 // Returned true if user did not cancel 790 xing.remove(); 791 dispose(); 792 } 793 } 794 }); 795 if (blockACAssigned && blockBDAssigned) { 796 AbstractAction ssaa = new AbstractAction(Bundle.getMessage("SetSignals")) { 797 @Override 798 public void actionPerformed(ActionEvent e) { 799 // bring up signals at level crossing tool dialog 800 LayoutEditorToolBarPanel letbp = getLayoutEditorToolBarPanel(); 801 layoutEditor.getLETools(). 802 setSignalsAtLevelXingFromMenu(xing, 803 letbp.signalIconEditor, 804 letbp.signalFrame); 805 } 806 }; 807 JMenu jm = new JMenu(Bundle.getMessage("SignalHeads")); 808 if (layoutEditor.getLETools(). 809 addLevelXingSignalHeadInfoToMenu(xing, jm)) { 810 jm.add(ssaa); 811 popup.add(jm); 812 } else { 813 popup.add(ssaa); 814 } 815 } 816 817 final String[] boundaryBetween = xing.getBlockBoundaries(); 818 boolean blockBoundaries = false; 819 if (jmri.InstanceManager.getDefault(LayoutBlockManager.class).isAdvancedRoutingEnabled()) { 820 if (blockACAssigned && !blockBDAssigned) { 821 popup.add(new AbstractAction(Bundle.getMessage("ViewBlockRouting")) { 822 @Override 823 public void actionPerformed(ActionEvent e) { 824 AbstractAction routeTableAction = new LayoutBlockRouteTableAction("ViewRouting", getLayoutBlockAC()); 825 routeTableAction.actionPerformed(e); 826 } 827 }); 828 } else if (!blockACAssigned && blockBDAssigned) { 829 popup.add(new AbstractAction(Bundle.getMessage("ViewBlockRouting")) { 830 @Override 831 public void actionPerformed(ActionEvent e) { 832 AbstractAction routeTableAction = new LayoutBlockRouteTableAction("ViewRouting", getLayoutBlockBD()); 833 routeTableAction.actionPerformed(e); 834 } 835 }); 836 } else if (blockACAssigned && blockBDAssigned) { 837 JMenu viewRouting = new JMenu(Bundle.getMessage("ViewBlockRouting")); 838 viewRouting.add(new AbstractAction(getLayoutBlockAC().getDisplayName()) { 839 @Override 840 public void actionPerformed(ActionEvent e) { 841 AbstractAction routeTableAction = new LayoutBlockRouteTableAction(getLayoutBlockAC().getDisplayName(), getLayoutBlockAC()); 842 routeTableAction.actionPerformed(e); 843 } 844 }); 845 846 viewRouting.add(new AbstractAction(getLayoutBlockBD().getDisplayName()) { 847 @Override 848 public void actionPerformed(ActionEvent e) { 849 AbstractAction routeTableAction = new LayoutBlockRouteTableAction(getLayoutBlockBD().getDisplayName(), getLayoutBlockBD()); 850 routeTableAction.actionPerformed(e); 851 } 852 }); 853 854 popup.add(viewRouting); 855 } 856 } 857 858 for (int i = 0; i < 4; i++) { 859 if (boundaryBetween[i] != null) { 860 blockBoundaries = true; 861 } 862 } 863 if (blockBoundaries) { 864 popup.add(new AbstractAction(Bundle.getMessage("SetSignalMasts")) { 865 @Override 866 public void actionPerformed(ActionEvent e) { 867 LayoutEditorToolBarPanel letbp = getLayoutEditorToolBarPanel(); 868 layoutEditor.getLETools(). 869 setSignalMastsAtLevelXingFromMenu( 870 xing, boundaryBetween, 871 letbp.signalFrame); 872 } 873 }); 874 popup.add(new AbstractAction(Bundle.getMessage("SetSensors")) { 875 @Override 876 public void actionPerformed(ActionEvent e) { 877 LayoutEditorToolBarPanel letbp = getLayoutEditorToolBarPanel(); 878 layoutEditor.getLETools().setSensorsAtLevelXingFromMenu( 879 xing, boundaryBetween, 880 letbp.sensorIconEditor, 881 letbp.sensorFrame); 882 } 883 }); 884 } 885 886 layoutEditor.setShowAlignmentMenu(popup); 887 addCommonPopupItems(mouseEvent, popup); 888 popup.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); 889 } else if (!viewAdditionalMenu.isEmpty()) { 890 setAdditionalViewPopUpMenu(popup); 891 addCommonPopupItems(mouseEvent, popup); 892 popup.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); 893 } 894 return popup; 895 } // showPopup 896 897// public String[] getBlockBoundaries() { 898// final String[] boundaryBetween = new String[4]; 899// 900// String blockNameAC = getBlockNameAC(); 901// String blockNameBD = getBlockNameBD(); 902// 903// LayoutBlock blockAC = getLayoutBlockAC(); 904// LayoutBlock blockBD = getLayoutBlockAC(); 905// 906// if (!blockNameAC.isEmpty() && (blockAC != null)) { 907// if ((connectA instanceof TrackSegment) && (((TrackSegment) connectA).getLayoutBlock() != blockAC)) { 908// try { 909// boundaryBetween[0] = (((TrackSegment) connectA).getLayoutBlock().getDisplayName() + " - " + blockAC.getDisplayName()); 910// } catch (java.lang.NullPointerException e) { 911// //Can be considered normal if tracksegement hasn't yet been allocated a block 912// log.debug("TrackSegement at connection A doesn't contain a layout block"); 913// } 914// } 915// if ((connectC instanceof TrackSegment) && (((TrackSegment) connectC).getLayoutBlock() != blockAC)) { 916// try { 917// boundaryBetween[2] = (((TrackSegment) connectC).getLayoutBlock().getDisplayName() + " - " + blockAC.getDisplayName()); 918// } catch (java.lang.NullPointerException e) { 919// //Can be considered normal if tracksegement hasn't yet been allocated a block 920// log.debug("TrackSegement at connection C doesn't contain a layout block"); 921// } 922// } 923// } 924// if (!blockNameBD.isEmpty() && (blockBD != null)) { 925// if ((connectB instanceof TrackSegment) && (((TrackSegment) connectB).getLayoutBlock() != blockBD)) { 926// try { 927// boundaryBetween[1] = (((TrackSegment) connectB).getLayoutBlock().getDisplayName() + " - " + blockBD.getDisplayName()); 928// } catch (java.lang.NullPointerException e) { 929// //Can be considered normal if tracksegement hasn't yet been allocated a block 930// log.debug("TrackSegement at connection B doesn't contain a layout block"); 931// } 932// } 933// if ((connectD instanceof TrackSegment) && (((TrackSegment) connectD).getLayoutBlock() != blockBD)) { 934// try { 935// boundaryBetween[3] = (((TrackSegment) connectD).getLayoutBlock().getDisplayName() + " - " + blockBD.getDisplayName()); 936// } catch (java.lang.NullPointerException e) { 937// //Can be considered normal if tracksegement hasn't yet been allocated a block 938// log.debug("TrackSegement at connection D doesn't contain a layout block"); 939// } 940// } 941// } 942// return boundaryBetween; 943// } 944 945 /** 946 * Clean up when this object is no longer needed. Should not be called while 947 * the object is still displayed; see remove(). 948 */ 949 public void dispose() { 950 if (popup != null) { 951 popup.removeAll(); 952 } 953 popup = null; 954 } 955 956 /** 957 * Remove this object from display and persistance. 958 */ 959// public void remove() { 960// // remove from persistance by flagging inactive 961// active = false; 962// } 963// 964// boolean active = true; 965// 966// * 967// * "active" means that the object is still displayed, and should be stored. 968// */ 969// public boolean isActive() { 970// return active; 971// } 972 973// ArrayList<SignalMast> sml = new ArrayList<>(); 974// 975// public void addSignalMastLogic(SignalMast sm) { 976// if (sml.contains(sm)) { 977// return; 978// } 979// if (sml.isEmpty()) { 980// sml.add(sm); 981// return; 982// } 983// SignalMastLogic sl = InstanceManager.getDefault(jmri.SignalMastLogicManager.class).getSignalMastLogic(sm); 984// for (SignalMast signalMast : sml) { 985// SignalMastLogic s = InstanceManager.getDefault(SignalMastLogicManager.class).getSignalMastLogic(signalMast); 986// if (s != null) { 987// s.setConflictingLogic(sm, xing); 988// } 989// sl.setConflictingLogic(signalMast, xing); 990// } 991// sml.add(sm); 992// } 993// 994// public void removeSignalMastLogic(SignalMast sm) { 995// if (!sml.contains(sm)) { 996// return; 997// } 998// sml.remove(sm); 999// if (sml.isEmpty()) { 1000// return; 1001// } 1002// for (int i = 0; i < sml.size(); i++) { 1003// SignalMastLogic s = InstanceManager.getDefault(jmri.SignalMastLogicManager.class).getSignalMastLogic(sm); 1004// if (s != null) { 1005// s.removeConflictingLogic(sm, xing); 1006// } 1007// } 1008// } 1009 1010 ArrayList<JMenuItem> editAdditionalMenu = new ArrayList<>(0); 1011 ArrayList<JMenuItem> viewAdditionalMenu = new ArrayList<>(0); 1012 1013 public void addEditPopUpMenu(JMenuItem menu) { 1014 if (!editAdditionalMenu.contains(menu)) { 1015 editAdditionalMenu.add(menu); 1016 } 1017 } 1018 1019 public void addViewPopUpMenu(JMenuItem menu) { 1020 if (!viewAdditionalMenu.contains(menu)) { 1021 viewAdditionalMenu.add(menu); 1022 } 1023 } 1024 1025 public void setAdditionalEditPopUpMenu(JPopupMenu popup) { 1026 if (editAdditionalMenu.isEmpty()) { 1027 return; 1028 } 1029 popup.addSeparator(); 1030 for (JMenuItem mi : editAdditionalMenu) { 1031 popup.add(mi); 1032 } 1033 } 1034 1035 public void setAdditionalViewPopUpMenu(JPopupMenu popup) { 1036 if (viewAdditionalMenu.isEmpty()) { 1037 return; 1038 } 1039 popup.addSeparator(); 1040 for (JMenuItem mi : viewAdditionalMenu) { 1041 popup.add(mi); 1042 } 1043 } 1044 1045 /** 1046 * Draw track decorations. 1047 * 1048 * This type of track has none, so this method is empty. 1049 */ 1050 @Override 1051 protected void drawDecorations(Graphics2D g2) {} 1052 1053 /** 1054 * Draw this level crossing. 1055 * 1056 * @param g2 the graphics port to draw to 1057 */ 1058 @Override 1059 protected void draw1(Graphics2D g2, boolean isMain, boolean isBlock) { 1060 if (isMain == isMainlineAC()) { 1061 if (isBlock) { 1062 setColorForTrackBlock(g2, getLayoutBlockAC()); 1063 } 1064 g2.draw(new Line2D.Double(getCoordsA(), getCoordsC())); 1065 } 1066 if (isMain == isMainlineBD()) { 1067 if (isBlock) { 1068 setColorForTrackBlock(g2, getLayoutBlockBD()); 1069 } 1070 g2.draw(new Line2D.Double(getCoordsB(), getCoordsD())); 1071 } 1072 } 1073 1074 /** 1075 * {@inheritDoc} 1076 */ 1077 @Override 1078 protected void draw2(Graphics2D g2, boolean isMain, float railDisplacement) { 1079 Point2D pA = getCoordsA(); 1080 Point2D pB = getCoordsB(); 1081 Point2D pC = getCoordsC(); 1082 Point2D pD = getCoordsD(); 1083 Point2D pM = getCoordsCenter(); 1084 1085 Point2D vAC = MathUtil.normalize(MathUtil.subtract(pC, pA), railDisplacement); 1086 double dirAC_DEG = MathUtil.computeAngleDEG(pA, pC); 1087 Point2D vACo = MathUtil.orthogonal(vAC); 1088 Point2D pAL = MathUtil.subtract(pA, vACo); 1089 Point2D pAR = MathUtil.add(pA, vACo); 1090 Point2D pCL = MathUtil.subtract(pC, vACo); 1091 Point2D pCR = MathUtil.add(pC, vACo); 1092 1093 Point2D vBD = MathUtil.normalize(MathUtil.subtract(pD, pB), railDisplacement); 1094 double dirBD_DEG = MathUtil.computeAngleDEG(pB, pD); 1095 Point2D vBDo = MathUtil.orthogonal(vBD); 1096 Point2D pBL = MathUtil.subtract(pB, vBDo); 1097 Point2D pBR = MathUtil.add(pB, vBDo); 1098 Point2D pDL = MathUtil.subtract(pD, vBDo); 1099 Point2D pDR = MathUtil.add(pD, vBDo); 1100 1101 double deltaDEG = MathUtil.absDiffAngleDEG(dirAC_DEG, dirBD_DEG); 1102 double deltaRAD = Math.toRadians(deltaDEG); 1103 1104 double hypotK = railDisplacement / Math.cos((PI - deltaRAD) / 2.0); 1105 double hypotV = railDisplacement / Math.cos(deltaRAD / 2.0); 1106 1107 log.debug("dir AC: {}, BD: {}, diff: {}", dirAC_DEG, dirBD_DEG, deltaDEG); 1108 1109 Point2D vDisK = MathUtil.normalize(MathUtil.add(vAC, vBD), hypotK); 1110 Point2D vDisV = MathUtil.normalize(MathUtil.orthogonal(vDisK), hypotV); 1111 Point2D pKL = MathUtil.subtract(pM, vDisK); 1112 Point2D pKR = MathUtil.add(pM, vDisK); 1113 Point2D pVL = MathUtil.subtract(pM, vDisV); 1114 Point2D pVR = MathUtil.add(pM, vDisV); 1115 1116 if (isMain == isMainlineAC()) { 1117 // this is the *2.0 vector (rail gap) for the AC diamond parts 1118 Point2D vAC2 = MathUtil.normalize(vAC, 2.0); 1119 // KL toward C, VR toward A, VL toward C and KR toward A 1120 Point2D pKLtC = MathUtil.add(pKL, vAC2); 1121 Point2D pVRtA = MathUtil.subtract(pVR, vAC2); 1122 Point2D pVLtC = MathUtil.add(pVL, vAC2); 1123 Point2D pKRtA = MathUtil.subtract(pKR, vAC2); 1124 1125 // draw right AC rail: AR====KL == VR====CR 1126 g2.draw(new Line2D.Double(pAR, pKL)); 1127 g2.draw(new Line2D.Double(pKLtC, pVRtA)); 1128 g2.draw(new Line2D.Double(pVR, pCR)); 1129 1130 // draw left AC rail: AL====VL == KR====CL 1131 g2.draw(new Line2D.Double(pAL, pVL)); 1132 g2.draw(new Line2D.Double(pVLtC, pKRtA)); 1133 g2.draw(new Line2D.Double(pKR, pCL)); 1134 } 1135 if (isMain == isMainlineBD()) { 1136 // this is the *2.0 vector (rail gap) for the BD diamond parts 1137 Point2D vBD2 = MathUtil.normalize(vBD, 2.0); 1138 // VR toward D, KR toward B, KL toward D and VL toward B 1139 Point2D pVRtD = MathUtil.add(pVR, vBD2); 1140 Point2D pKRtB = MathUtil.subtract(pKR, vBD2); 1141 Point2D pKLtD = MathUtil.add(pKL, vBD2); 1142 Point2D pVLtB = MathUtil.subtract(pVL, vBD2); 1143 1144 // draw right BD rail: BR====VR == KR====DR 1145 g2.draw(new Line2D.Double(pBR, pVR)); 1146 g2.draw(new Line2D.Double(pVRtD, pKRtB)); 1147 g2.draw(new Line2D.Double(pKR, pDR)); 1148 1149 // draw left BD rail: BL====KL == VL====DL 1150 g2.draw(new Line2D.Double(pBL, pKL)); 1151 g2.draw(new Line2D.Double(pKLtD, pVLtB)); 1152 g2.draw(new Line2D.Double(pVL, pDL)); 1153 } 1154 } 1155 1156 /** 1157 * {@inheritDoc} 1158 */ 1159 @Override 1160 protected void highlightUnconnected(Graphics2D g2, HitPointType specificType) { 1161 if (((specificType == HitPointType.NONE) || (specificType == HitPointType.LEVEL_XING_A)) 1162 && (getConnectA() == null)) { 1163 g2.fill(trackControlCircleAt(getCoordsA())); 1164 } 1165 1166 if (((specificType == HitPointType.NONE) || (specificType == HitPointType.LEVEL_XING_B)) 1167 && (getConnectB() == null)) { 1168 g2.fill(trackControlCircleAt(getCoordsB())); 1169 } 1170 1171 if (((specificType == HitPointType.NONE) || (specificType == HitPointType.LEVEL_XING_C)) 1172 && (getConnectC() == null)) { 1173 g2.fill(trackControlCircleAt(getCoordsC())); 1174 } 1175 1176 if (((specificType == HitPointType.NONE) || (specificType == HitPointType.LEVEL_XING_D)) 1177 && (getConnectD() == null)) { 1178 g2.fill(trackControlCircleAt(getCoordsD())); 1179 } 1180 } 1181 1182 @Override 1183 protected void drawEditControls(Graphics2D g2) { 1184 g2.setColor(layoutEditor.getDefaultTrackColorColor()); 1185 g2.draw(trackEditControlCircleAt(getCoordsCenter())); 1186 1187 if (getConnectA() == null) { 1188 g2.setColor(Color.magenta); 1189 } else { 1190 g2.setColor(Color.blue); 1191 } 1192 g2.draw(layoutEditor.layoutEditorControlRectAt(getCoordsA())); 1193 1194 if (getConnectB() == null) { 1195 g2.setColor(Color.red); 1196 } else { 1197 g2.setColor(Color.green); 1198 } 1199 g2.draw(layoutEditor.layoutEditorControlRectAt(getCoordsB())); 1200 1201 if (getConnectC() == null) { 1202 g2.setColor(Color.red); 1203 } else { 1204 g2.setColor(Color.green); 1205 } 1206 g2.draw(layoutEditor.layoutEditorControlRectAt(getCoordsC())); 1207 1208 if (getConnectD() == null) { 1209 g2.setColor(Color.red); 1210 } else { 1211 g2.setColor(Color.green); 1212 } 1213 g2.draw(layoutEditor.layoutEditorControlRectAt(getCoordsD())); 1214 } 1215 1216 @Override 1217 protected void drawTurnoutControls(Graphics2D g2) { 1218 // LevelXings don't have turnout controls... 1219 // nothing to see here... move along... 1220 } 1221 1222 /* 1223 * {@inheritDoc} 1224 */ 1225 @Override 1226 public void reCheckBlockBoundary() { 1227 // nothing to see here... move along... 1228 } 1229 1230 /* 1231 * {@inheritDoc} temporary 1232 */ 1233 @Override 1234 protected ArrayList<LayoutConnectivity> getLayoutConnectivity() { 1235 // nothing to see here... move along... 1236 return null; 1237 } 1238 1239 /** 1240 * {@inheritDoc} 1241 */ 1242 @Override 1243 public List<HitPointType> checkForFreeConnections() { 1244 throw new IllegalArgumentException("should have called Object instead of view temporary"); 1245// List<HitPointType> result = new ArrayList<>(); 1246// 1247// //check the A connection point 1248// if (getConnectA() == null) { 1249// result.add(HitPointType.LEVEL_XING_A); 1250// } 1251// 1252// //check the B connection point 1253// if (getConnectB() == null) { 1254// result.add(HitPointType.LEVEL_XING_B); 1255// } 1256// 1257// //check the C connection point 1258// if (getConnectC() == null) { 1259// result.add(HitPointType.LEVEL_XING_C); 1260// } 1261// 1262// //check the D connection point 1263// if (getConnectD() == null) { 1264// result.add(HitPointType.LEVEL_XING_D); 1265// } 1266// return result; 1267 } 1268 1269 /** 1270 * {@inheritDoc} 1271 */ 1272 @Override 1273 public boolean checkForUnAssignedBlocks() { 1274// return ((getLayoutBlockAC() != null) && (getLayoutBlockBD() != null)); 1275 throw new IllegalArgumentException("should have called Object instead of View temporary"); 1276 } 1277 1278 /** 1279 * {@inheritDoc} 1280 */ 1281 @Override 1282 public void checkForNonContiguousBlocks( 1283 @Nonnull HashMap<String, List<Set<String>>> blockNamesToTrackNameSetsMap) { 1284 throw new IllegalArgumentException("should have called Object instead of View temporary"); 1285 1286 /* 1287 * For each (non-null) blocks of this track do: 1288 * #1) If it's got an entry in the blockNamesToTrackNameSetMap then 1289 * #2) If this track is already in the TrackNameSet for this block 1290 * then return (done!) 1291 * #3) else add a new set (with this block/track) to 1292 * blockNamesToTrackNameSetMap and check all the connections in this 1293 * block (by calling the 2nd method below) 1294 * <p> 1295 * Basically, we're maintaining contiguous track sets for each block found 1296 * (in blockNamesToTrackNameSetMap) 1297 */ 1298 1299 // We're only using a map here because it's convient to 1300 // use it to pair up blocks and connections 1301// Map<LayoutTrack, String> blocksAndTracksMap = new HashMap<>(); 1302// if ((getLayoutBlockAC() != null) && (connectA != null)) { 1303// blocksAndTracksMap.put(connectA, getLayoutBlockAC().getDisplayName()); 1304// } 1305// if ((getLayoutBlockAC() != null) && (connectC != null)) { 1306// blocksAndTracksMap.put(connectC, getLayoutBlockAC().getDisplayName()); 1307// } 1308// if ((getLayoutBlockBD() != null) && (connectB != null)) { 1309// blocksAndTracksMap.put(connectB, getLayoutBlockBD().getDisplayName()); 1310// } 1311// if ((getLayoutBlockBD() != null) && (connectD != null)) { 1312// blocksAndTracksMap.put(connectD, getLayoutBlockBD().getDisplayName()); 1313// } 1314// 1315// List<Set<String>> TrackNameSets = null; 1316// Set<String> TrackNameSet = null; 1317// for (Map.Entry<LayoutTrack, String> entry : blocksAndTracksMap.entrySet()) { 1318// LayoutTrack theConnect = entry.getKey(); 1319// String theBlockName = entry.getValue(); 1320// 1321// TrackNameSet = null; // assume not found (pessimist!) 1322// TrackNameSets = blockNamesToTrackNameSetsMap.get(theBlockName); 1323// if (TrackNameSets != null) { // (#1) 1324// for (Set<String> checkTrackNameSet : TrackNameSets) { 1325// if (checkTrackNameSet.contains(getName())) { // (#2) 1326// TrackNameSet = checkTrackNameSet; 1327// break; 1328// } 1329// } 1330// } else { // (#3) 1331// log.debug("*New block ('{}') trackNameSets", theBlockName); 1332// TrackNameSets = new ArrayList<>(); 1333// blockNamesToTrackNameSetsMap.put(theBlockName, TrackNameSets); 1334// } 1335// if (TrackNameSet == null) { 1336// TrackNameSet = new LinkedHashSet<>(); 1337// TrackNameSets.add(TrackNameSet); 1338// } 1339// if (TrackNameSet.add(getName())) { 1340// log.debug("* Add track ''{}'' to trackNameSet for block ''{}''", getName(), theBlockName); 1341// } 1342// theConnect.collectContiguousTracksNamesInBlockNamed(theBlockName, TrackNameSet); 1343// } 1344 } // collectContiguousTracksNamesInBlockNamed 1345 1346 /** 1347 * {@inheritDoc} 1348 */ 1349 @Override 1350 public void collectContiguousTracksNamesInBlockNamed(@Nonnull String blockName, 1351 @Nonnull Set<String> TrackNameSet) { 1352 throw new IllegalArgumentException("should have called Object instead of View temporary"); 1353// if (!TrackNameSet.contains(getName())) { 1354// // check all the matching blocks in this track and... 1355// // #1) add us to TrackNameSet and... 1356// // #2) flood them 1357// //check the AC blockName 1358// if (getBlockNameAC().equals(blockName)) { 1359// // if we are added to the TrackNameSet 1360// if (TrackNameSet.add(getName())) { 1361// log.debug("* Add track ''{}'for block ''{}''", getName(), blockName); 1362// } 1363// // it's time to play... flood your neighbours! 1364// if (connectA != null) { 1365// connectA.collectContiguousTracksNamesInBlockNamed(blockName, TrackNameSet); 1366// } 1367// if (connectC != null) { 1368// connectC.collectContiguousTracksNamesInBlockNamed(blockName, TrackNameSet); 1369// } 1370// } 1371// //check the BD blockName 1372// if (getBlockNameBD().equals(blockName)) { 1373// // if we are added to the TrackNameSet 1374// if (TrackNameSet.add(getName())) { 1375// log.debug("* Add track ''{}''for block ''{}''", getName(), blockName); 1376// } 1377// // it's time to play... flood your neighbours! 1378// if (connectB != null) { 1379// connectB.collectContiguousTracksNamesInBlockNamed(blockName, TrackNameSet); 1380// } 1381// if (connectD != null) { 1382// connectD.collectContiguousTracksNamesInBlockNamed(blockName, TrackNameSet); 1383// } 1384// } 1385// } 1386 } 1387 1388 /** 1389 * {@inheritDoc} 1390 */ 1391 @Override 1392 public void setAllLayoutBlocks(LayoutBlock layoutBlock) { 1393 throw new IllegalArgumentException("should have called Object instead of View temporary"); 1394// setLayoutBlockAC(layoutBlock); 1395// setLayoutBlockBD(layoutBlock); 1396 } 1397 1398 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LevelXingView.class); 1399}