001package jmri.jmrit.display.layoutEditor; 002 003import java.awt.BorderLayout; 004import java.awt.Color; 005import java.awt.Component; 006import java.awt.Container; 007import java.awt.FlowLayout; 008import java.awt.GridLayout; 009import java.awt.Point; 010import java.awt.event.ActionEvent; 011import java.awt.event.WindowAdapter; 012import java.awt.event.WindowEvent; 013import java.awt.geom.Point2D; 014 015import java.util.*; 016import javax.annotation.*; 017import javax.swing.*; 018import javax.swing.border.Border; 019 020import jmri.*; 021import jmri.NamedBean.DisplayOptions; 022import jmri.implementation.DefaultConditionalAction; 023import jmri.jmrit.blockboss.BlockBossLogic; 024import jmri.jmrit.blockboss.BlockBossLogicProvider; 025import jmri.jmrit.catalog.NamedIcon; 026import jmri.jmrit.display.*; 027import jmri.jmrit.signalling.SignallingGuiTools; 028import jmri.swing.NamedBeanComboBox; 029import jmri.util.JmriJFrame; 030import jmri.util.MathUtil; 031import jmri.util.swing.JComboBoxUtil; 032import jmri.util.swing.JmriJOptionPane; 033 034/** 035 * Layout Editor Tools provides tools making use of layout connectivity 036 * available in Layout Editor panels. 037 * <p> 038 * The tools in this module are accessed via the Tools menu in Layout Editor. 039 * 040 * @author Dave Duchamp Copyright (c) 2007 041 * @author George Warner Copyright (c) 2017-2019 042 */ 043public final class LayoutEditorTools { 044 045 //constants 046 //private final int NONE = 0; //Signal at Turnout Positions 047 //operational instance variables shared between tools 048 private LayoutEditor layoutEditor = null; 049 private MultiIconEditor signalIconEditor = null; 050 private JFrame signalFrame = null; 051 private boolean needRedraw = false; 052 private BlockBossLogic logic = null; 053 private SignalHead auxSignal = null; 054 055 //constructor method 056 public LayoutEditorTools(@Nonnull LayoutEditor thePanel) { 057 layoutEditor = thePanel; 058 059 //Turnouts 060 LayoutEditor.setupComboBox(sensorsTurnoutComboBox, true, true, false); 061 LayoutEditor.setupComboBox(signalMastsTurnoutComboBox, true, true, false); 062 LayoutEditor.setupComboBox(turnout1ComboBox, true, true, false); 063 LayoutEditor.setupComboBox(turnout2ComboBox, true, true, false); 064 LayoutEditor.setupComboBox(turnoutAComboBox, true, true, false); 065 LayoutEditor.setupComboBox(turnoutBComboBox, true, true, false); 066 LayoutEditor.setupComboBox(turnoutComboBox, true, true, false); 067 068 //Blocks 069 LayoutEditor.setupComboBox(block1IDComboBox, true, true, false); 070 LayoutEditor.setupComboBox(block2IDComboBox, true, true, false); 071 LayoutEditor.setupComboBox(blockACComboBox, true, true, false); 072 LayoutEditor.setupComboBox(blockBDComboBox, true, true, false); 073 LayoutEditor.setupComboBox(slipSensorsBlockAComboBox, true, true, false); 074 LayoutEditor.setupComboBox(slipSensorsBlockBComboBox, true, true, false); 075 LayoutEditor.setupComboBox(slipSensorsBlockCComboBox, true, true, false); 076 LayoutEditor.setupComboBox(slipSensorsBlockDComboBox, true, true, false); 077 LayoutEditor.setupComboBox(slipSignalBlockAComboBox, true, true, false); 078 LayoutEditor.setupComboBox(slipSignalBlockBComboBox, true, true, false); 079 LayoutEditor.setupComboBox(slipSignalBlockCComboBox, true, true, false); 080 LayoutEditor.setupComboBox(slipSignalBlockDComboBox, true, true, false); 081 LayoutEditor.setupComboBox(xingBlockACComboBox, true, true, false); 082 LayoutEditor.setupComboBox(xingBlockBDComboBox, true, true, false); 083 LayoutEditor.setupComboBox(xingSensorsBlockACComboBox, true, true, false); 084 LayoutEditor.setupComboBox(xingSensorsBlockBDComboBox, true, true, false); 085 086 //Signal Heads 087 LayoutEditor.setupComboBox(a1_3WaySignalHeadComboBox, true, true, false); 088 LayoutEditor.setupComboBox(a1SignalHeadComboBox, true, true, false); 089 LayoutEditor.setupComboBox(a1SlipSignalHeadComboBox, true, true, false); 090 LayoutEditor.setupComboBox(a1TToTSignalHeadComboBox, true, true, false); 091 LayoutEditor.setupComboBox(a2_3WaySignalHeadComboBox, true, true, false); 092 LayoutEditor.setupComboBox(a2SignalHeadComboBox, true, true, false); 093 LayoutEditor.setupComboBox(a2SlipSignalHeadComboBox, true, true, false); 094 LayoutEditor.setupComboBox(a2TToTSignalHeadComboBox, true, true, false); 095 LayoutEditor.setupComboBox(a3_3WaySignalHeadComboBox, true, true, false); 096 LayoutEditor.setupComboBox(aSignalHeadComboBox, true, true, false); 097 LayoutEditor.setupComboBox(b_3WaySignalHeadComboBox, true, true, false); 098 LayoutEditor.setupComboBox(b1SignalHeadComboBox, true, true, false); 099 LayoutEditor.setupComboBox(b1SlipSignalHeadComboBox, true, true, false); 100 LayoutEditor.setupComboBox(b1TToTSignalHeadComboBox, true, true, false); 101 LayoutEditor.setupComboBox(b2SignalHeadComboBox, true, true, false); 102 LayoutEditor.setupComboBox(b2SlipSignalHeadComboBox, true, true, false); 103 LayoutEditor.setupComboBox(b2TToTSignalHeadComboBox, true, true, false); 104 LayoutEditor.setupComboBox(bSignalHeadComboBox, true, true, false); 105 LayoutEditor.setupComboBox(c_3WaySignalHeadComboBox, true, true, false); 106 LayoutEditor.setupComboBox(c1SignalHeadComboBox, true, true, false); 107 LayoutEditor.setupComboBox(c1SlipSignalHeadComboBox, true, true, false); 108 LayoutEditor.setupComboBox(c1TToTSignalHeadComboBox, true, true, false); 109 LayoutEditor.setupComboBox(c2SignalHeadComboBox, true, true, false); 110 LayoutEditor.setupComboBox(c2SlipSignalHeadComboBox, true, true, false); 111 LayoutEditor.setupComboBox(c2TToTSignalHeadComboBox, true, true, false); 112 LayoutEditor.setupComboBox(continuingSignalHeadComboBox, false, true, false); 113 LayoutEditor.setupComboBox(cSignalHeadComboBox, true, true, false); 114 LayoutEditor.setupComboBox(d_3WaySignalHeadComboBox, true, true, false); 115 LayoutEditor.setupComboBox(d1SignalHeadComboBox, true, true, false); 116 LayoutEditor.setupComboBox(d1SlipSignalHeadComboBox, true, true, false); 117 LayoutEditor.setupComboBox(d1TToTSignalHeadComboBox, true, true, false); 118 LayoutEditor.setupComboBox(d2SignalHeadComboBox, true, true, false); 119 LayoutEditor.setupComboBox(d2SlipSignalHeadComboBox, true, true, false); 120 LayoutEditor.setupComboBox(d2TToTSignalHeadComboBox, true, true, false); 121 LayoutEditor.setupComboBox(divergingSignalHeadComboBox, false, true, false); 122 LayoutEditor.setupComboBox(dSignalHeadComboBox, true, true, false); 123 LayoutEditor.setupComboBox(eastBoundSignalHeadComboBox, true, true, false); 124 LayoutEditor.setupComboBox(throatContinuingSignalHeadComboBox, false, true, false); 125 LayoutEditor.setupComboBox(throatDivergingSignalHeadComboBox, false, true, false); 126 LayoutEditor.setupComboBox(westBoundSignalHeadComboBox, true, true, false); 127 128 // TODO: Set combobox exclude lists for turnouts, blocks and signal heads 129 // that are not part of the current layout panel 130 } 131 132 /*=====================*\ 133 |* setSignalsAtTurnout *| 134 \*=====================*/ 135 /** 136 * Tool to set signals at a turnout, including placing the signal icons and 137 * optionally setup of Simple Signal Logic for each signal head 138 * <p> 139 * This tool assumes left facing signal head icons have been selected, and 140 * will rotate the signal head icons accordingly. 141 * <p> 142 * This tool will place throat icons on the right side of the track, and 143 * continuing and diverging icons on the outside edge of the turnout. 144 */ 145 //operational variables for Set Signals at Turnout tool 146 private JmriJFrame setSignalsAtTurnoutFrame = null; 147 private boolean setSignalsAtTurnoutOpenFlag = false; 148 private boolean setSignalsAtTurnoutFromMenuFlag = false; 149 150 private JLabel turnoutNameLabel = null; 151 152 private final NamedBeanComboBox<Turnout> turnoutComboBox = new NamedBeanComboBox<>( 153 InstanceManager.turnoutManagerInstance(), 154 null, DisplayOptions.DISPLAYNAME); 155 156 private final NamedBeanComboBox<SignalHead> throatContinuingSignalHeadComboBox = new NamedBeanComboBox<>( 157 InstanceManager.getDefault(SignalHeadManager.class), 158 null, DisplayOptions.DISPLAYNAME); 159 private final NamedBeanComboBox<SignalHead> throatDivergingSignalHeadComboBox = new NamedBeanComboBox<>( 160 InstanceManager.getDefault(SignalHeadManager.class), 161 null, DisplayOptions.DISPLAYNAME); 162 private final NamedBeanComboBox<SignalHead> continuingSignalHeadComboBox = new NamedBeanComboBox<>( 163 InstanceManager.getDefault(SignalHeadManager.class), 164 null, DisplayOptions.DISPLAYNAME); 165 private final NamedBeanComboBox<SignalHead> divergingSignalHeadComboBox = new NamedBeanComboBox<>( 166 InstanceManager.getDefault(SignalHeadManager.class), 167 null, DisplayOptions.DISPLAYNAME); 168 169 private final JCheckBox setPlaceAllHeads = new JCheckBox(Bundle.getMessage("PlaceAllHeads")); 170 private final JCheckBox setupAllLogic = new JCheckBox(Bundle.getMessage("SetAllLogic")); 171 172 private final JCheckBox setThroatContinuing = new JCheckBox(Bundle.getMessage("PlaceHead")); 173 private final JCheckBox setupLogicThroatContinuing = new JCheckBox(Bundle.getMessage("SetLogic")); 174 private final JCheckBox setThroatDiverging = new JCheckBox(Bundle.getMessage("PlaceHead")); 175 private final JCheckBox setupLogicThroatDiverging = new JCheckBox(Bundle.getMessage("SetLogic")); 176 private final JCheckBox setContinuing = new JCheckBox(Bundle.getMessage("PlaceHead")); 177 private final JCheckBox setupLogicContinuing = new JCheckBox(Bundle.getMessage("SetLogic")); 178 private final JCheckBox setDiverging = new JCheckBox(Bundle.getMessage("PlaceHead")); 179 private final JCheckBox setupLogicDiverging = new JCheckBox(Bundle.getMessage("SetLogic")); 180 private JButton getSavedSignalHeads = null; 181 private JButton changeSignalIcon = null; 182 private JButton setSignalsDone = null; 183 private JButton setSignalsCancel = null; 184 185 private LayoutTurnout layoutTurnout = null; 186 private double placeSignalDirectionDEG = 0.0; 187 188 private Turnout turnout = null; 189 private SignalHead throatContinuingHead = null; 190 private SignalHead throatDivergingHead = null; 191 private SignalHead continuingHead = null; 192 private SignalHead divergingHead = null; 193 194 //display dialog for Set Signals at Turnout tool 195 public void setSignalsAtTurnoutFromMenu(@Nonnull LayoutTurnout to, 196 @Nonnull MultiIconEditor theEditor, @Nonnull JFrame theFrame) { 197 layoutTurnout = to; 198 turnout = to.getTurnout(); 199 turnoutComboBox.setSelectedItem(to.getTurnout()); 200 setSignalsAtTurnoutFromMenuFlag = true; 201 setSignalsAtTurnout(theEditor, theFrame); 202 setSignalsAtTurnoutFromMenuFlag = false; 203 } 204 205 public void setSignalsAtTurnout(@Nonnull MultiIconEditor theEditor, 206 @Nonnull JFrame theFrame) { 207 signalIconEditor = theEditor; 208 signalFrame = theFrame; 209 210 //Initialize if needed 211 if (setSignalsAtTurnoutFrame == null) { 212 setSignalsAtTurnoutOpenFlag = false; 213 setSignalsAtTurnoutFrame = new JmriJFrame(Bundle.getMessage("SignalsAtTurnout"), false, true); 214 oneFrameToRuleThemAll(setSignalsAtTurnoutFrame); 215 setSignalsAtTurnoutFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 216 217 setSignalsAtTurnoutFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtTurnout", true); 218 setSignalsAtTurnoutFrame.setLocation(70, 30); 219 Container theContentPane = setSignalsAtTurnoutFrame.getContentPane(); 220 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 221 222 JPanel panel1 = new JPanel(new FlowLayout()); 223 turnoutNameLabel = new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("BeanNameTurnout"))); 224 panel1.add(turnoutNameLabel); 225 panel1.add(turnoutComboBox); 226 turnoutNameLabel.setLabelFor(turnoutComboBox); 227 turnoutComboBox.setToolTipText(Bundle.getMessage("SignalsTurnoutNameHint")); 228 theContentPane.add(panel1); 229 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 230 231 JPanel panel2 = new JPanel(new FlowLayout()); 232 JLabel shTitle = new JLabel(Bundle.getMessage("SignalHeads")); 233 panel2.add(shTitle); 234 panel2.add(new JLabel(" ")); 235 panel2.add(getSavedSignalHeads = new JButton(Bundle.getMessage("GetSaved"))); 236 getSavedSignalHeads.addActionListener(this::turnoutSignalsGetSaved); 237 getSavedSignalHeads.setToolTipText(Bundle.getMessage("GetSavedHint")); 238 theContentPane.add(panel2); 239 240 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 241 JPanel panel2a = new JPanel(new FlowLayout()); 242 panel2a.add(new JLabel(" ")); 243 panel2a.add(setPlaceAllHeads); 244 setPlaceAllHeads.setToolTipText(Bundle.getMessage("PlaceAllHeadsHint")); 245 setPlaceAllHeads.addActionListener((ActionEvent e) -> { 246 boolean isSelected = setPlaceAllHeads.isSelected(); 247 //(de)select all checkboxes 248 setThroatContinuing.setSelected(isSelected); 249 setThroatDiverging.setSelected(isSelected); 250 setContinuing.setSelected(isSelected); 251 setDiverging.setSelected(isSelected); 252 }); 253 panel2a.add(new JLabel(" ")); 254 panel2a.add(setupAllLogic); 255 setupAllLogic.setToolTipText(Bundle.getMessage("SetAllLogicHint")); 256 setupAllLogic.addActionListener((ActionEvent e) -> { 257 boolean isSelected = setupAllLogic.isSelected(); 258 //(de)select all checkboxes 259 setupLogicThroatContinuing.setSelected(isSelected); 260 setupLogicThroatDiverging.setSelected(isSelected); 261 setupLogicContinuing.setSelected(isSelected); 262 setupLogicDiverging.setSelected(isSelected); 263 }); 264 theContentPane.add(panel2a); 265 266 JPanel panel21 = new JPanel(new FlowLayout()); 267 JLabel throatContinuingLabel = new JLabel( 268 Bundle.getMessage("MakeLabel", throatContinuingString)); 269 panel21.add(throatContinuingLabel); 270 panel21.add(throatContinuingSignalHeadComboBox); 271 throatContinuingLabel.setLabelFor(throatContinuingSignalHeadComboBox); 272 theContentPane.add(panel21); 273 throatContinuingSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 274 275 JPanel panel22 = new JPanel(new FlowLayout()); 276 panel22.add(new JLabel(" ")); 277 panel22.add(setThroatContinuing); 278 setThroatContinuing.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 279 panel22.add(new JLabel(" ")); 280 panel22.add(setupLogicThroatContinuing); 281 setupLogicThroatContinuing.setToolTipText(Bundle.getMessage("SetLogicHint")); 282 theContentPane.add(panel22); 283 284 JPanel panel31 = new JPanel(new FlowLayout()); 285 JLabel throatDivergingLabel = new JLabel( 286 Bundle.getMessage("MakeLabel", throatDivergingString)); 287 panel31.add(throatDivergingLabel); 288 panel31.add(throatDivergingSignalHeadComboBox); 289 throatDivergingLabel.setLabelFor(throatDivergingSignalHeadComboBox); 290 theContentPane.add(panel31); 291 throatDivergingSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 292 293 JPanel panel32 = new JPanel(new FlowLayout()); 294 panel32.add(new JLabel(" ")); 295 panel32.add(setThroatDiverging); 296 setThroatDiverging.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 297 panel32.add(new JLabel(" ")); 298 panel32.add(setupLogicThroatDiverging); 299 setupLogicThroatDiverging.setToolTipText(Bundle.getMessage("SetLogicHint")); 300 theContentPane.add(panel32); 301 302 JPanel panel41 = new JPanel(new FlowLayout()); 303 JLabel continuingLabel = new JLabel( 304 Bundle.getMessage("MakeLabel", continuingString)); 305 panel41.add(continuingLabel); 306 panel41.add(continuingSignalHeadComboBox); 307 continuingLabel.setLabelFor(continuingSignalHeadComboBox); 308 theContentPane.add(panel41); 309 continuingSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 310 311 JPanel panel42 = new JPanel(new FlowLayout()); 312 panel42.add(new JLabel(" ")); 313 panel42.add(setContinuing); 314 setContinuing.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 315 panel42.add(new JLabel(" ")); 316 panel42.add(setupLogicContinuing); 317 setupLogicContinuing.setToolTipText(Bundle.getMessage("SetLogicHint")); 318 theContentPane.add(panel42); 319 320 JPanel panel51 = new JPanel(new FlowLayout()); 321 JLabel divergingLabel = new JLabel( 322 Bundle.getMessage("MakeLabel", divergingString)); 323 panel51.add(divergingLabel); 324 panel51.add(divergingSignalHeadComboBox); 325 divergingLabel.setLabelFor(divergingSignalHeadComboBox); 326 theContentPane.add(panel51); 327 divergingSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 328 329 JPanel panel52 = new JPanel(new FlowLayout()); 330 panel52.add(new JLabel(" ")); 331 panel52.add(setDiverging); 332 setDiverging.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 333 panel52.add(new JLabel(" ")); 334 panel52.add(setupLogicDiverging); 335 setupLogicDiverging.setToolTipText(Bundle.getMessage("SetLogicHint")); 336 theContentPane.add(panel52); 337 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 338 339 JPanel panel6 = new JPanel(new FlowLayout()); 340 panel6.add(changeSignalIcon = new JButton(Bundle.getMessage("ChangeSignalIcon"))); 341 changeSignalIcon.addActionListener((ActionEvent e) -> signalFrame.setVisible(true)); 342 changeSignalIcon.setToolTipText(Bundle.getMessage("ChangeSignalIconHint")); 343 panel6.add(new JLabel(" ")); 344 panel6.add(setSignalsDone = new JButton(Bundle.getMessage("ButtonDone"))); 345 setSignalsDone.addActionListener(this::setSignalsDonePressed); 346 setSignalsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 347 348 panel6.add(setSignalsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 349 setSignalsCancel.addActionListener(this::setSignalsCancelPressed); 350 setSignalsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 351 theContentPane.add(panel6); 352 setSignalsAtTurnoutFrame.addWindowListener(new WindowAdapter() { 353 @Override 354 public void windowClosing(WindowEvent e) { 355 setSignalsCancelPressed(null); 356 } 357 }); 358 } 359 setPlaceAllHeads.setSelected(false); 360 setupAllLogic.setSelected(false); 361 362 turnoutComboBox.setVisible(!setSignalsAtTurnoutFromMenuFlag); 363 String turnoutLabelString = Bundle.getMessage("MakeLabel", Bundle.getMessage("BeanNameTurnout")); 364 if (setSignalsAtTurnoutFromMenuFlag) { 365 turnoutNameLabel.setText(turnoutLabelString + layoutTurnout.getTurnoutName()); 366 turnoutSignalsGetSaved(null); 367 } else { 368 turnoutNameLabel.setText(turnoutLabelString); 369 } 370 371 if (!setSignalsAtTurnoutOpenFlag) { 372 setSignalsAtTurnoutFrame.setPreferredSize(null); 373 setSignalsAtTurnoutFrame.pack(); 374 setSignalsAtTurnoutOpenFlag = true; 375 } 376 setSignalsAtTurnoutFrame.setVisible(true); 377 } //setSignalsAtTurnout 378 379 private void turnoutSignalsGetSaved(ActionEvent a) { 380 if (getTurnoutInformation(false)) { 381 throatContinuingSignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalA1()); 382 throatDivergingSignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalA2()); 383 continuingSignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalB1()); 384 divergingSignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalC1()); 385 } 386 } 387 388 private void setSignalsCancelPressed(ActionEvent a) { 389 setSignalsAtTurnoutOpenFlag = false; 390 setSignalsAtTurnoutFrame.setVisible(false); 391 } 392 393 private void setSignalsDonePressed(ActionEvent a) { 394 //process turnout name 395 if (!getTurnoutInformation(false)) { 396 return; 397 } 398 //process signal head names 399 if (!getTurnoutSignalHeadInformation()) { 400 return; 401 } 402 //place signals as requested 403 String signalHeadName = throatContinuingSignalHeadComboBox.getSelectedItemDisplayName(); 404 if (signalHeadName == null) { 405 signalHeadName = ""; 406 } 407 if (setThroatContinuing.isSelected()) { 408 if (isHeadOnPanel(throatContinuingHead) 409 && (throatContinuingHead != getHeadFromName(layoutTurnout.getSignalA1Name()))) { 410 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 411 Bundle.getMessage("SignalsError6", 412 new Object[]{signalHeadName}), 413 Bundle.getMessage("ErrorTitle"), 414 JmriJOptionPane.ERROR_MESSAGE); 415 return; 416 } else { 417 removeSignalHeadFromPanel(layoutTurnout.getSignalA1Name()); 418 placeThroatContinuing(); 419 removeAssignment(throatContinuingHead); 420 layoutTurnout.setSignalA1Name(signalHeadName); 421 needRedraw = true; 422 } 423 } else { 424 LayoutTurnout.Geometry assigned = isHeadAssignedHere(throatContinuingHead, layoutTurnout); 425 if (assigned == LayoutTurnout.Geometry.NONE) { 426 if (isHeadOnPanel(throatContinuingHead) 427 && isHeadAssignedAnywhere(throatContinuingHead)) { 428 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 429 Bundle.getMessage("SignalsError8", 430 new Object[]{signalHeadName}), 431 Bundle.getMessage("ErrorTitle"), 432 JmriJOptionPane.ERROR_MESSAGE); 433 return; 434 } else { 435 removeSignalHeadFromPanel(layoutTurnout.getSignalA1Name()); 436 removeAssignment(throatContinuingHead); 437 layoutTurnout.setSignalA1Name(signalHeadName); 438 } 439 //} else if (assigned != A1) { 440 //TODO: need to figure out what to do in this case 441 //assigned to a different position on the same turnout. 442 //} 443 } 444 } 445 signalHeadName = throatDivergingSignalHeadComboBox.getSelectedItemDisplayName(); 446 if (signalHeadName == null) { 447 signalHeadName = ""; 448 } 449 if ((setThroatDiverging.isSelected()) && (throatDivergingHead != null)) { 450 if (isHeadOnPanel(throatDivergingHead) 451 && (throatDivergingHead != getHeadFromName(layoutTurnout.getSignalA2Name()))) { 452 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 453 Bundle.getMessage("SignalsError6", 454 new Object[]{signalHeadName}), 455 Bundle.getMessage("ErrorTitle"), 456 JmriJOptionPane.ERROR_MESSAGE); 457 return; 458 } else { 459 removeSignalHeadFromPanel(layoutTurnout.getSignalA2Name()); 460 placeThroatDiverging(); 461 removeAssignment(throatDivergingHead); 462 layoutTurnout.setSignalA2Name(signalHeadName); 463 needRedraw = true; 464 } 465 } else if (throatDivergingHead != null) { 466 LayoutTurnout.Geometry assigned = isHeadAssignedHere(throatDivergingHead, layoutTurnout); 467 if (assigned == LayoutTurnout.Geometry.NONE) { 468 if (isHeadOnPanel(throatDivergingHead) 469 && isHeadAssignedAnywhere(throatDivergingHead)) { 470 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 471 Bundle.getMessage("SignalsError8", 472 new Object[]{signalHeadName}), 473 Bundle.getMessage("ErrorTitle"), 474 JmriJOptionPane.ERROR_MESSAGE); 475 return; 476 } else { 477 removeSignalHeadFromPanel(layoutTurnout.getSignalA2Name()); 478 removeAssignment(throatDivergingHead); 479 layoutTurnout.setSignalA2Name(signalHeadName); 480 } 481 //} else if (assigned != A2) { 482 //need to figure out what to do in this case - assigned to a different position on the same turnout. 483 } 484 } else { //throatDivergingHead is always null here 485 removeSignalHeadFromPanel(layoutTurnout.getSignalA2Name()); 486 layoutTurnout.setSignalA2Name(""); 487 } 488 489 signalHeadName = continuingSignalHeadComboBox.getSelectedItemDisplayName(); 490 if (signalHeadName == null) { 491 signalHeadName = ""; 492 } 493 if (setContinuing.isSelected()) { 494 if (isHeadOnPanel(continuingHead) 495 && (continuingHead != getHeadFromName(layoutTurnout.getSignalB1Name()))) { 496 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 497 Bundle.getMessage("SignalsError6", 498 new Object[]{signalHeadName}), 499 Bundle.getMessage("ErrorTitle"), 500 JmriJOptionPane.ERROR_MESSAGE); 501 return; 502 } else { 503 removeSignalHeadFromPanel(layoutTurnout.getSignalB1Name()); 504 if (layoutTurnout.getContinuingSense() == Turnout.CLOSED) { 505 placeContinuing(signalHeadName); 506 } else { 507 placeDiverging(signalHeadName); 508 } 509 removeAssignment(continuingHead); 510 layoutTurnout.setSignalB1Name(signalHeadName); 511 needRedraw = true; 512 } 513 } else { 514 LayoutTurnout.Geometry assigned = isHeadAssignedHere(continuingHead, layoutTurnout); 515 if (assigned == LayoutTurnout.Geometry.NONE) { 516 if (isHeadOnPanel(continuingHead) 517 && isHeadAssignedAnywhere(continuingHead)) { 518 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 519 Bundle.getMessage("SignalsError8", 520 new Object[]{signalHeadName}), 521 Bundle.getMessage("ErrorTitle"), 522 JmriJOptionPane.ERROR_MESSAGE); 523 return; 524 } else { 525 removeSignalHeadFromPanel(layoutTurnout.getSignalB1Name()); 526 removeAssignment(continuingHead); 527 layoutTurnout.setSignalB1Name(signalHeadName); 528 } 529 //} else if (assigned != B1) { 530 //need to figure out what to do in this case - assigned to a different position on the same turnout. 531 } 532 } 533 534 signalHeadName = divergingSignalHeadComboBox.getSelectedItemDisplayName(); 535 if (signalHeadName == null) { 536 signalHeadName = ""; 537 } 538 if (setDiverging.isSelected()) { 539 if (isHeadOnPanel(divergingHead) 540 && (divergingHead != getHeadFromName(layoutTurnout.getSignalC1Name()))) { 541 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 542 Bundle.getMessage("SignalsError6", 543 new Object[]{signalHeadName}), 544 Bundle.getMessage("ErrorTitle"), 545 JmriJOptionPane.ERROR_MESSAGE); 546 return; 547 } else { 548 removeSignalHeadFromPanel(layoutTurnout.getSignalC1Name()); 549 if (layoutTurnout.getContinuingSense() == Turnout.CLOSED) { 550 placeDiverging(signalHeadName); 551 } else { 552 placeContinuing(signalHeadName); 553 } 554 removeAssignment(divergingHead); 555 layoutTurnout.setSignalC1Name(signalHeadName); 556 needRedraw = true; 557 } 558 } else { 559 LayoutTurnout.Geometry assigned = isHeadAssignedHere(divergingHead, layoutTurnout); 560 if (assigned == LayoutTurnout.Geometry.NONE) { 561 if (isHeadOnPanel(divergingHead) 562 && isHeadAssignedAnywhere(divergingHead)) { 563 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 564 Bundle.getMessage("SignalsError8", 565 new Object[]{signalHeadName}), 566 Bundle.getMessage("ErrorTitle"), 567 JmriJOptionPane.ERROR_MESSAGE); 568 return; 569 } else { 570 removeSignalHeadFromPanel(layoutTurnout.getSignalC1Name()); 571 removeAssignment(divergingHead); 572 layoutTurnout.setSignalC1Name(signalHeadName); 573 } 574 //} else if (assigned != C1) { 575 //need to figure out what to do in this case - assigned to a different position on the same turnout. 576 } 577 } 578 //setup Logic if requested and enough information is available 579 if (setupLogicThroatContinuing.isSelected()) { 580 setLogicThroatContinuing(); 581 } 582 if ((throatDivergingHead != null) && setupLogicThroatDiverging.isSelected()) { 583 setLogicThroatDiverging(); 584 } 585 if (setupLogicContinuing.isSelected()) { 586 setLogicContinuing(); 587 } 588 if (setupLogicDiverging.isSelected()) { 589 setLogicDiverging(); 590 } 591 //make sure this layout turnout is not linked to another 592 layoutTurnout.setLinkType(LayoutTurnout.LinkType.NO_LINK); 593 layoutTurnout.setLinkedTurnoutName(""); 594 //finish up 595 setSignalsAtTurnoutOpenFlag = false; 596 setSignalsAtTurnoutFrame.setVisible(false); 597 if (needRedraw) { 598 layoutEditor.redrawPanel(); 599 layoutEditor.setDirty(); 600 needRedraw = false; 601 } 602 } //setSignalsDonePressed 603 604 /** 605 * Checks the turnout name (could also be a crossover, ...) 606 * 1) checks setSignalsAtTurnoutFromMenuFlag (bis setSignalsAtXoverTurnoutFromMenuFlag) 607 * skip to 6 if true 608 * 2) get a name string from turnoutComboBox (bis NamedBean.normalizeUserName(xoverTurnoutName) ), 609 * showing an error dialog if not present 610 * 3) Gets turnout by that name, showing a error and returning false if not 611 * 4) (??) if the turnout's user name is non-existant or not matching, reset the turnout name string source 612 * used in 2 (does this ever work?) 613 * 5) Search through all LayoutTurnout (and subclass) objects, looking for a match. If 614 * is the other type (LayoutTurnout vs XOver or vice-versa), so an error, 615 * call a cancel routine and return false. Save the found item in the 616 * 'layoutTurnout' non-local variable 617 * 618 * 6) If the above succeed in finding a layoutTurnout, calculate an angle and 619 * store in the `placeSignalDirectionDEG` non-local variable 620 * and return true (success) 621 * 7) Finally, show an error saying the turnout is not displayed on this panel and return false. 622 * 623 * In summary, this makes some checks, and then (re)loads the 'layoutTurnout' and 624 * 'placeSignalDirectionDEG' non-local variables, returning true for success 625 * 626 * @return true if ok, false if not for various reasons 627 */ 628 private boolean getTurnoutInformation(boolean isCrossover) { 629 String str = ""; 630 if (isCrossover ? !setSignalsAtXoverTurnoutFromMenuFlag : !setSignalsAtTurnoutFromMenuFlag) { 631 turnout = null; 632 layoutTurnout = null; 633 str = isCrossover ? NamedBean.normalizeUserName(xoverTurnoutName) 634 : turnoutComboBox.getSelectedItemDisplayName(); 635 if ((str == null) || str.isEmpty()) { 636 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 637 Bundle.getMessage("SignalsError1"), 638 Bundle.getMessage("ErrorTitle"), 639 JmriJOptionPane.ERROR_MESSAGE); 640 return false; 641 } 642 turnout = InstanceManager.turnoutManagerInstance().getTurnout(str); 643 if (turnout == null) { 644 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 645 Bundle.getMessage("SignalsError2", 646 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 647 JmriJOptionPane.ERROR_MESSAGE); 648 return false; 649 } else { 650 String uname = turnout.getUserName(); 651 if ((uname == null) || uname.isEmpty() || !uname.equals(str)) { 652 if (isCrossover) { 653 xoverTurnoutName = str; 654 } else { 655 turnoutComboBox.setSelectedItem(turnout); 656 } 657 } 658 } 659 for (LayoutTurnout t : layoutEditor.getLayoutTurnouts()) { 660 if (t.getTurnout() == turnout) { 661 layoutTurnout = t; 662 if (t.isTurnoutTypeXover() != isCrossover) { 663 if (isCrossover) { 664 JmriJOptionPane.showMessageDialog(layoutEditor, 665 Bundle.getMessage("InfoMessage8"), 666 Bundle.getMessage("MessageTitle"), 667 JmriJOptionPane.INFORMATION_MESSAGE); 668 setXoverSignalsCancelPressed(null); 669 } else { 670 JmriJOptionPane.showMessageDialog(layoutEditor, 671 Bundle.getMessage("InfoMessage1"), 672 Bundle.getMessage("MessageTitle"), 673 JmriJOptionPane.INFORMATION_MESSAGE); 674 setSignalsCancelPressed(null); 675 } 676 return false; 677 } 678 break; 679 } 680 } 681 } 682 683 if (layoutTurnout != null) { 684 // convert to view to get angle on screen display 685 LayoutTurnoutView ltv = layoutEditor.getLayoutTurnoutView(layoutTurnout); 686 687 Point2D coordsA = ltv.getCoordsA(), coords2; 688 if (isCrossover) { 689 coords2 = ltv.getCoordsB(); 690 } else { 691 coords2 = ltv.getCoordsCenter(); 692 } 693 placeSignalDirectionDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coords2, coordsA)); 694 return true; 695 } 696 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 697 Bundle.getMessage("SignalsError3", 698 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 699 JmriJOptionPane.ERROR_MESSAGE); 700 return false; 701 } //getTurnoutInformation 702 703 private boolean getTurnoutSignalHeadInformation() { 704 throatContinuingHead = getSignalHeadFromEntry(throatContinuingSignalHeadComboBox, true, setSignalsAtTurnoutFrame); 705 if (throatContinuingHead == null) { 706 return false; 707 } 708 throatDivergingHead = getSignalHeadFromEntry(throatDivergingSignalHeadComboBox, false, setSignalsAtTurnoutFrame); 709 continuingHead = getSignalHeadFromEntry(continuingSignalHeadComboBox, true, setSignalsAtTurnoutFrame); 710 if (continuingHead == null) { 711 return false; 712 } 713 divergingHead = getSignalHeadFromEntry(divergingSignalHeadComboBox, true, setSignalsAtTurnoutFrame); 714 if (divergingHead == null) { 715 return false; 716 } 717 return true; 718 } 719 private NamedIcon testIcon = null; 720 721 private void placeThroatContinuing() { 722 if (testIcon == null) { 723 testIcon = signalIconEditor.getIcon(0); 724 } 725 String signalHeadName = throatContinuingSignalHeadComboBox.getSelectedItemDisplayName(); 726 if (signalHeadName == null) { 727 signalHeadName = ""; 728 } 729 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 730 731 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 732 733 Point2D coordsA = layoutTurnoutView.getCoordsA(); 734 Point2D delta = new Point2D.Double(+shift, +shift); 735 736 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 737 Point2D where = MathUtil.add(coordsA, delta); 738 setSignalHeadOnPanel(placeSignalDirectionDEG + 180.0, signalHeadName, where); 739 } 740 741 private void placeThroatDiverging() { 742 if (testIcon == null) { 743 testIcon = signalIconEditor.getIcon(0); 744 } 745 String signalHeadName = throatDivergingSignalHeadComboBox.getSelectedItemDisplayName(); 746 if (signalHeadName == null) { 747 signalHeadName = ""; 748 } 749 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 750 751 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 752 753 Point2D coordsA = layoutTurnoutView.getCoordsA(); 754 Point2D delta = new Point2D.Double(-shift, +shift); 755 756 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 757 Point2D where = MathUtil.add(coordsA, delta); 758 setSignalHeadOnPanel(placeSignalDirectionDEG + 180.0, signalHeadName, where); 759 } 760 761 private void placeContinuing(@Nonnull String signalHeadName) { 762 if (testIcon == null) { 763 testIcon = signalIconEditor.getIcon(0); 764 } 765 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 766 767 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 768 769 Point2D coordsB = layoutTurnoutView.getCoordsB(); 770 Point2D coordsC = layoutTurnoutView.getCoordsC(); 771 Point2D coordsCenter = layoutTurnoutView.getCoordsCenter(); 772 773 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 774 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 775 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 776 double shiftX = 0.0; 777 if (diffDirDEG < 0.0) { 778 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 779 } 780 Point2D delta = new Point2D.Double(shiftX, -shift); 781 782 delta = MathUtil.rotateDEG(delta, bDirDEG); 783 Point2D where = MathUtil.add(coordsB, delta); 784 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 785 } 786 787 private void placeDiverging(String signalHeadName) { 788 if (testIcon == null) { 789 testIcon = signalIconEditor.getIcon(0); 790 } 791 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 792 793 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 794 795 Point2D coordsB = layoutTurnoutView.getCoordsB(); 796 Point2D coordsC = layoutTurnoutView.getCoordsC(); 797 Point2D coordsCenter = layoutTurnoutView.getCoordsCenter(); 798 799 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 800 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 801 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 802 double shiftX = 0.0; 803 if (diffDirDEG >= 0.0) { 804 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 805 } 806 Point2D delta = new Point2D.Double(shiftX, -shift); 807 808 delta = MathUtil.rotateDEG(delta, cDirDEG); 809 Point2D where = MathUtil.add(coordsC, delta); 810 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 811 } 812 813 private void setLogicThroatContinuing() { 814 TrackSegment track = null; 815 if (layoutTurnout.getContinuingSense() == Turnout.CLOSED) { 816 track = (TrackSegment) layoutTurnout.getConnectB(); 817 } else { 818 track = (TrackSegment) layoutTurnout.getConnectC(); 819 } 820 if (track == null) { 821 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 822 Bundle.getMessage("InfoMessage7"), 823 Bundle.getMessage("MessageTitle"), 824 JmriJOptionPane.INFORMATION_MESSAGE); 825 return; 826 } 827 LayoutBlock block = track.getLayoutBlock(); 828 if (block == null) { 829 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 830 Bundle.getMessage("InfoMessage6"), 831 Bundle.getMessage("MessageTitle"), 832 JmriJOptionPane.INFORMATION_MESSAGE); 833 return; 834 } 835 Sensor occupancy = block.getOccupancySensor(); 836 if (occupancy == null) { 837 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 838 Bundle.getMessage("InfoMessage4", 839 new Object[]{block.getUserName()}), 840 Bundle.getMessage("MessageTitle"), 841 JmriJOptionPane.INFORMATION_MESSAGE); 842 return; 843 } 844 845 String signalHeadName = throatContinuingSignalHeadComboBox.getSelectedItemDisplayName(); 846 if (signalHeadName == null) { 847 signalHeadName = ""; 848 } 849 SignalHead nextHead = getNextSignalFromObject(track, 850 layoutTurnout, signalHeadName, setSignalsAtTurnoutFrame); 851 if ((nextHead == null) && (!reachedEndBumper())) { 852 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 853 Bundle.getMessage("InfoMessage5", 854 new Object[]{block.getUserName()}), 855 Bundle.getMessage("MessageTitle"), 856 JmriJOptionPane.INFORMATION_MESSAGE); 857 return; 858 } 859 if (throatDivergingHead != null) { 860 if (!initializeBlockBossLogic(signalHeadName)) { 861 return; 862 } 863 logic.setMode(BlockBossLogic.TRAILINGMAIN); 864 logic.setTurnout(turnout.getDisplayName()); 865 logic.setSensor1(occupancy.getDisplayName()); 866 if (nextHead != null) { 867 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 868 } 869 if (auxSignal != null) { 870 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 871 } 872 finalizeBlockBossLogic(); 873 return; 874 } 875 SignalHead savedAuxSignal = auxSignal; 876 TrackSegment track2 = null; 877 if (layoutTurnout.getContinuingSense() == Turnout.CLOSED) { 878 track2 = (TrackSegment) layoutTurnout.getConnectC(); 879 } else { 880 track2 = (TrackSegment) layoutTurnout.getConnectB(); 881 } 882 if (track2 == null) { 883 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 884 Bundle.getMessage("InfoMessage7"), 885 Bundle.getMessage("MessageTitle"), 886 JmriJOptionPane.INFORMATION_MESSAGE); 887 return; 888 } 889 LayoutBlock block2 = track2.getLayoutBlock(); 890 if (block2 == null) { 891 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 892 Bundle.getMessage("InfoMessage6"), 893 Bundle.getMessage("MessageTitle"), 894 JmriJOptionPane.INFORMATION_MESSAGE); 895 return; 896 } 897 Sensor occupancy2 = block2.getOccupancySensor(); 898 if (occupancy2 == null) { 899 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 900 Bundle.getMessage("InfoMessage4", 901 new Object[]{block2.getUserName()}), 902 Bundle.getMessage("MessageTitle"), 903 JmriJOptionPane.INFORMATION_MESSAGE); 904 return; 905 } 906 signalHeadName = throatContinuingSignalHeadComboBox.getSelectedItemDisplayName(); 907 if (signalHeadName == null) { 908 signalHeadName = ""; 909 } 910 SignalHead nextHead2 = getNextSignalFromObject(track2, 911 layoutTurnout, signalHeadName, setSignalsAtTurnoutFrame); 912 if ((nextHead2 == null) && (!reachedEndBumper())) { 913 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 914 Bundle.getMessage("InfoMessage5", 915 new Object[]{block2.getUserName()}), 916 Bundle.getMessage("MessageTitle"), 917 JmriJOptionPane.INFORMATION_MESSAGE); 918 return; 919 } 920 if (!initializeBlockBossLogic(signalHeadName)) { 921 return; 922 } 923 logic.setMode(BlockBossLogic.FACING); 924 logic.setTurnout(turnout.getDisplayName()); 925 logic.setWatchedSensor1(occupancy.getDisplayName()); 926 logic.setWatchedSensor2(occupancy2.getDisplayName()); 927 if (nextHead != null) { 928 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 929 } 930 if (savedAuxSignal != null) { 931 logic.setWatchedSignal1Alt(savedAuxSignal.getDisplayName()); 932 } 933 if (nextHead2 != null) { 934 logic.setWatchedSignal2(nextHead2.getDisplayName()); 935 } 936 if (auxSignal != null) { 937 logic.setWatchedSignal2Alt(auxSignal.getDisplayName()); 938 } 939 if (!layoutTurnout.isMainlineC()) { 940 logic.setLimitSpeed2(true); 941 } 942 finalizeBlockBossLogic(); 943 } //setLogicThroatContinuing 944 945 private void setLogicThroatDiverging() { 946 TrackSegment track = null; 947 if (layoutTurnout.getContinuingSense() == Turnout.CLOSED) { 948 track = (TrackSegment) layoutTurnout.getConnectC(); 949 } else { 950 track = (TrackSegment) layoutTurnout.getConnectB(); 951 } 952 if (track == null) { 953 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 954 Bundle.getMessage("InfoMessage7"), 955 Bundle.getMessage("MessageTitle"), 956 JmriJOptionPane.INFORMATION_MESSAGE); 957 return; 958 } 959 LayoutBlock block = track.getLayoutBlock(); 960 if (block == null) { 961 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 962 Bundle.getMessage("InfoMessage6"), 963 Bundle.getMessage("MessageTitle"), 964 JmriJOptionPane.INFORMATION_MESSAGE); 965 return; 966 } 967 Sensor occupancy = block.getOccupancySensor(); 968 if (occupancy == null) { 969 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 970 Bundle.getMessage("InfoMessage4", 971 new Object[]{block.getUserName()}), 972 Bundle.getMessage("MessageTitle"), 973 JmriJOptionPane.INFORMATION_MESSAGE); 974 return; 975 } 976 String signalHeadName = throatDivergingSignalHeadComboBox.getSelectedItemDisplayName(); 977 if (signalHeadName == null) { 978 signalHeadName = ""; 979 } 980 SignalHead nextHead = getNextSignalFromObject(track, 981 layoutTurnout, signalHeadName, setSignalsAtTurnoutFrame); 982 if ((nextHead == null) && (!reachedEndBumper())) { 983 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 984 Bundle.getMessage("InfoMessage5", 985 new Object[]{block.getUserName()}), 986 Bundle.getMessage("MessageTitle"), 987 JmriJOptionPane.INFORMATION_MESSAGE); 988 return; 989 } 990 if (!initializeBlockBossLogic(signalHeadName)) { 991 return; 992 } 993 994 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 995 logic.setTurnout(turnout.getDisplayName()); 996 logic.setSensor1(occupancy.getDisplayName()); 997 if (nextHead != null) { 998 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 999 } 1000 if (auxSignal != null) { 1001 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 1002 } 1003 if (!layoutTurnout.isMainlineC()) { 1004 logic.setLimitSpeed2(true); 1005 } 1006 finalizeBlockBossLogic(); 1007 } //setLogicThroatDiverging 1008 1009 private void setLogicContinuing() { 1010 TrackSegment track = (TrackSegment) layoutTurnout.getConnectA(); 1011 if (track == null) { 1012 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 1013 Bundle.getMessage("InfoMessage7"), 1014 Bundle.getMessage("MessageTitle"), 1015 JmriJOptionPane.INFORMATION_MESSAGE); 1016 return; 1017 } 1018 LayoutBlock block = track.getLayoutBlock(); 1019 if (block == null) { 1020 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 1021 Bundle.getMessage("InfoMessage6"), 1022 Bundle.getMessage("MessageTitle"), 1023 JmriJOptionPane.INFORMATION_MESSAGE); 1024 return; 1025 } 1026 Sensor occupancy = block.getOccupancySensor(); 1027 if (occupancy == null) { 1028 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 1029 Bundle.getMessage("InfoMessage4", 1030 new Object[]{block.getUserName()}), 1031 Bundle.getMessage("MessageTitle"), 1032 JmriJOptionPane.INFORMATION_MESSAGE); 1033 return; 1034 } 1035 String signalHeadName = continuingSignalHeadComboBox.getSelectedItemDisplayName(); 1036 if (signalHeadName == null) { 1037 signalHeadName = ""; 1038 } 1039 SignalHead nextHead = getNextSignalFromObject(track, 1040 layoutTurnout, signalHeadName, setSignalsAtTurnoutFrame); 1041 if ((nextHead == null) && (!reachedEndBumper())) { 1042 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 1043 Bundle.getMessage("InfoMessage5", 1044 new Object[]{block.getUserName()}), 1045 Bundle.getMessage("MessageTitle"), 1046 JmriJOptionPane.INFORMATION_MESSAGE); 1047 return; 1048 } 1049 if (!initializeBlockBossLogic(signalHeadName)) { 1050 return; 1051 } 1052 logic.setMode(BlockBossLogic.TRAILINGMAIN); 1053 logic.setTurnout(turnout.getDisplayName()); 1054 logic.setSensor1(occupancy.getDisplayName()); 1055 if (nextHead != null) { 1056 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 1057 } 1058 if (auxSignal != null) { 1059 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 1060 } 1061 finalizeBlockBossLogic(); 1062 } //setLogicContinuing 1063 1064 private void setLogicDiverging() { 1065 TrackSegment track = (TrackSegment) layoutTurnout.getConnectA(); 1066 if (track == null) { 1067 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 1068 Bundle.getMessage("InfoMessage7"), 1069 Bundle.getMessage("MessageTitle"), 1070 JmriJOptionPane.INFORMATION_MESSAGE); 1071 return; 1072 } 1073 LayoutBlock block = track.getLayoutBlock(); 1074 if (block == null) { 1075 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 1076 Bundle.getMessage("InfoMessage6"), 1077 Bundle.getMessage("MessageTitle"), 1078 JmriJOptionPane.INFORMATION_MESSAGE); 1079 return; 1080 } 1081 Sensor occupancy = block.getOccupancySensor(); 1082 if (occupancy == null) { 1083 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 1084 Bundle.getMessage("InfoMessage4", 1085 new Object[]{block.getUserName()}), 1086 Bundle.getMessage("MessageTitle"), 1087 JmriJOptionPane.INFORMATION_MESSAGE); 1088 return; 1089 } 1090 String signalHeadName = divergingSignalHeadComboBox.getSelectedItemDisplayName(); 1091 if (signalHeadName == null) { 1092 signalHeadName = ""; 1093 } 1094 SignalHead nextHead = getNextSignalFromObject(track, 1095 layoutTurnout, signalHeadName, setSignalsAtTurnoutFrame); 1096 if ((nextHead == null) && (!reachedEndBumper())) { 1097 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 1098 Bundle.getMessage("InfoMessage5", 1099 new Object[]{block.getUserName()}), 1100 Bundle.getMessage("MessageTitle"), 1101 JmriJOptionPane.INFORMATION_MESSAGE); 1102 return; 1103 } 1104 if (!initializeBlockBossLogic(signalHeadName)) { 1105 return; 1106 } 1107 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 1108 logic.setTurnout(turnout.getDisplayName()); 1109 logic.setSensor1(occupancy.getDisplayName()); 1110 if (nextHead != null) { 1111 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 1112 } 1113 if (auxSignal != null) { 1114 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 1115 } 1116 if (!layoutTurnout.isMainlineC()) { 1117 logic.setLimitSpeed2(true); 1118 } 1119 finalizeBlockBossLogic(); 1120 } //setLogicDiverging 1121 1122 /*==========================================*\ 1123 | * Utility routines used by multiple tools *| 1124 \*==========================================*/ 1125 /** 1126 * Returns the layout turnout corresponding to a given turnout. 1127 * <p> 1128 * If require 1129 * double crossover is requested, an error message is sent to the user if 1130 * the layout turnout is not a double crossover, and null is returned. 1131 * <p> 1132 * If a layout turnout corresponding to the turnout is not found, an error 1133 * message is sent to the user and null is returned. 1134 * 1135 * @param turnout the base turnout. 1136 * @param requireDoubleXover true to force checking of turnout type. 1137 * @param str error message string. 1138 * @param theFrame main frame. 1139 * @return layout turnout, may be null. 1140 */ 1141 @CheckReturnValue 1142 public LayoutTurnout getLayoutTurnoutFromTurnout( 1143 @Nonnull Turnout turnout, 1144 boolean requireDoubleXover, 1145 @Nonnull String str, 1146 @CheckForNull JFrame theFrame) { 1147 for (LayoutTurnout t : layoutEditor.getLayoutTurnouts()) { 1148 if (t.getTurnout() == turnout) { 1149 //have the layout turnout corresponding to the turnout 1150 if ((t.getTurnoutType() == LayoutTurnout.TurnoutType.DOUBLE_XOVER) 1151 && (!requireDoubleXover)) { 1152 JmriJOptionPane.showMessageDialog(theFrame, 1153 Bundle.getMessage("InfoMessage1"), 1154 Bundle.getMessage("MessageTitle"), 1155 JmriJOptionPane.INFORMATION_MESSAGE); 1156 return null; 1157 } 1158 if (requireDoubleXover && (t.getTurnoutType() != LayoutTurnout.TurnoutType.DOUBLE_XOVER)) { 1159 JmriJOptionPane.showMessageDialog(theFrame, 1160 Bundle.getMessage("InfoMessage8"), 1161 Bundle.getMessage("MessageTitle"), 1162 JmriJOptionPane.INFORMATION_MESSAGE); 1163 return null; 1164 } 1165 return t; 1166 } 1167 } 1168 //layout turnout not found 1169 JmriJOptionPane.showMessageDialog(theFrame, 1170 Bundle.getMessage("SignalsError3", 1171 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 1172 JmriJOptionPane.ERROR_MESSAGE); 1173 return null; 1174 } 1175 1176 /** 1177 * Returns the SignalHead corresponding to an entry field in the specified 1178 * dialog. This also takes care of UpperCase and trimming of leading and 1179 * trailing blanks. If entry is required, and no entry is present, and error 1180 * message is sent. An error message also results if a signal head with the 1181 * entered name is not found in the SignalTable. 1182 * @param signalNameComboBox the combo box with signal name selected. 1183 * @param requireEntry true if mandatory field, else false. 1184 * @param frame the main frame. 1185 * @return signal head, may be null. 1186 */ 1187 @CheckReturnValue 1188 public SignalHead getSignalHeadFromEntry( 1189 @Nonnull NamedBeanComboBox<SignalHead> signalNameComboBox, 1190 boolean requireEntry, 1191 @Nonnull JmriJFrame frame) { 1192 String signalName = signalNameComboBox.getSelectedItemDisplayName(); 1193 SignalHead result = getSignalHeadFromEntry(signalName, requireEntry, frame); 1194 if (result != null) { 1195 String uname = result.getUserName(); 1196 if ((uname == null) || uname.isEmpty() || !uname.equals(signalName)) { 1197 signalNameComboBox.setSelectedItem(result); 1198 } 1199 } 1200 return result; 1201 } 1202 1203 @CheckReturnValue 1204 public SignalHead getSignalHeadFromEntry( 1205 @Nonnull JTextField signalNameTextField, 1206 boolean requireEntry, @Nonnull JmriJFrame frame) { 1207 String signalName = NamedBean.normalizeUserName(signalNameTextField.getText()); 1208 SignalHead result = getSignalHeadFromEntry(signalName, requireEntry, frame); 1209 if (result != null) { 1210 String uname = result.getUserName(); 1211 if ((uname == null) || uname.isEmpty() || !uname.equals(signalName)) { 1212 signalNameTextField.setText(signalName); 1213 } 1214 } 1215 return result; 1216 } 1217 1218 @CheckReturnValue 1219 public SignalHead getSignalHeadFromEntry(@CheckForNull String signalName, 1220 boolean requireEntry, @Nonnull JmriJFrame frame) { 1221 if ((signalName == null) || signalName.isEmpty()) { 1222 if (requireEntry) { 1223 JmriJOptionPane.showMessageDialog(frame, Bundle.getMessage("SignalsError5"), 1224 Bundle.getMessage("ErrorTitle"), 1225 JmriJOptionPane.ERROR_MESSAGE); 1226 } 1227 return null; 1228 } 1229 SignalHead head = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1230 if (head == null) { 1231 JmriJOptionPane.showMessageDialog(frame, 1232 Bundle.getMessage("SignalsError4", 1233 new Object[]{signalName}), Bundle.getMessage("ErrorTitle"), 1234 JmriJOptionPane.ERROR_MESSAGE); 1235 return null; 1236 } 1237 return (head); 1238 } 1239 1240 /** 1241 * Returns a SignalHead given a name. 1242 * @param str signal head name. 1243 * @return signal head, may be null. 1244 */ 1245 @CheckReturnValue 1246 public SignalHead getHeadFromName(@CheckForNull String str) { 1247 SignalHead result = null; 1248 if ((str != null) && !str.isEmpty()) { 1249 result = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(str); 1250 } 1251 return result; 1252 } 1253 1254 /** 1255 * Places a signal head icon on the panel after rotation at the designated 1256 * place, with all icons taken care of. 1257 * 1258 * @param directionDEG rotation in degrees. 1259 * @param signalHeadName name of a signal head. 1260 * @param where coordinates for placing signal head on panel. 1261 */ 1262 public void setSignalHeadOnPanel(double directionDEG, 1263 @Nonnull String signalHeadName, 1264 @Nonnull Point2D where) { 1265 setSignalHeadOnPanel(directionDEG, signalHeadName, (int) where.getX(), (int) where.getY()); 1266 } 1267 1268 /** 1269 * Places a signal head icon on the panel after rotation at the designated 1270 * place, with all icons taken care of. 1271 * 1272 * @param directionDEG rotation in degrees. 1273 * @param signalHeadName name of a signal head. 1274 * @param xLoc x coordinate for placing signal head on panel. 1275 * @param yLoc y coordinate for placing signal head on panel. 1276 */ 1277 public void setSignalHeadOnPanel(double directionDEG, @Nonnull String signalHeadName, int xLoc, int yLoc) { 1278 SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 1279 1280 if (directionDEG > 0) { 1281 Iterator<String> e = l.getIconStateNames(); 1282 while (e.hasNext()) { 1283 l.getIcon(e.next()).rotate((int) directionDEG, l); 1284 } 1285 } 1286 1287 l.setLocation(xLoc - (int) (l.maxWidth() / 2.0), yLoc - (int) (l.maxHeight() / 2.0)); 1288 1289 layoutEditor.putSignal(l); 1290 } 1291 1292 /** 1293 * Returns an index if the specified signal head is assigned to the 1294 * LayoutTurnout initialized. Otherwise returns the NONE index. The index 1295 * specifies the turnout position of the signal head according to the code 1296 * listed at the beginning of this module. 1297 */ 1298 private LayoutTurnout.Geometry isHeadAssignedHere(@Nonnull SignalHead head, @Nonnull LayoutTurnout lTurnout) { 1299 LayoutTurnout.Geometry result = LayoutTurnout.Geometry.NONE; 1300 1301 Map<String, LayoutTurnout.Geometry> map = new HashMap<>(); 1302 map.put(lTurnout.getSignalA1Name(), LayoutTurnout.Geometry.POINTA1); 1303 map.put(lTurnout.getSignalA2Name(), LayoutTurnout.Geometry.POINTA2); 1304 map.put(lTurnout.getSignalA3Name(), LayoutTurnout.Geometry.POINTA3); 1305 map.put(lTurnout.getSignalB1Name(), LayoutTurnout.Geometry.POINTB1); 1306 map.put(lTurnout.getSignalB2Name(), LayoutTurnout.Geometry.POINTB2); 1307 map.put(lTurnout.getSignalC1Name(), LayoutTurnout.Geometry.POINTC1); 1308 map.put(lTurnout.getSignalC2Name(), LayoutTurnout.Geometry.POINTC2); 1309 map.put(lTurnout.getSignalD1Name(), LayoutTurnout.Geometry.POINTD1); 1310 map.put(lTurnout.getSignalD2Name(), LayoutTurnout.Geometry.POINTD2); 1311 1312 String sName = head.getSystemName(); 1313 String uName = head.getUserName(); 1314 1315 for (Map.Entry<String, LayoutTurnout.Geometry> entry : map.entrySet()) { 1316 String signalName = entry.getKey(); 1317 1318 if (!signalName.isEmpty() && (signalName.equals(sName) || signalName.equals(uName))) { 1319 result = entry.getValue(); 1320 break; 1321 } 1322 } 1323 1324 return result; 1325 } 1326 1327 /** 1328 * Get if signal head is on the panel. 1329 * @param head the signal head to locate. 1330 * @return true if an icon for the specified SignalHead is on the panel. 1331 */ 1332 public boolean isHeadOnPanel(@Nonnull SignalHead head) { 1333 for (SignalHeadIcon h : layoutEditor.getSignalList()) { 1334 if (h.getSignalHead() == head) { 1335 return true; 1336 } 1337 } 1338 return false; 1339 } 1340 1341 /** 1342 * Returns true if the specified Signal Head is assigned to an object on the 1343 * panel, regardless of whether an icon is displayed or not. 1344 * @param head the signal head to locate. 1345 * @return true if the signal head is attached to a panel object. 1346 */ 1347 public boolean isHeadAssignedAnywhere(@Nonnull SignalHead head) { 1348 String sName = head.getSystemName(); 1349 String uName = head.getUserName(); 1350 1351 for (LayoutTurnout to : layoutEditor.getLayoutTurnouts()) { 1352 if (isHeadAssignedHere(head, to) != LayoutTurnout.Geometry.NONE) { 1353 return true; 1354 } 1355 } 1356 1357 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 1358 if ((po.getEastBoundSignal().equals(sName) || ((uName != null) 1359 && (po.getEastBoundSignal().equals(uName))))) { 1360 return true; 1361 } 1362 if ((po.getWestBoundSignal().equals(sName) || ((uName != null) 1363 && (po.getWestBoundSignal().equals(uName))))) { 1364 return true; 1365 } 1366 } 1367 1368 for (LevelXing x : layoutEditor.getLevelXings()) { 1369 if ( (x.getSignalAName().equals(sName) || ((uName != null) 1370 && (x.getSignalAName().equals(uName))))) { 1371 return true; 1372 } 1373 if ( (x.getSignalBName().equals(sName) || ((uName != null) 1374 && (x.getSignalBName().equals(uName))))) { 1375 return true; 1376 } 1377 if ( (x.getSignalCName().equals(sName) || ((uName != null) 1378 && (x.getSignalCName().equals(uName))))) { 1379 return true; 1380 } 1381 if ( (x.getSignalDName().equals(sName) || ((uName != null) 1382 && (x.getSignalDName().equals(uName))))) { 1383 return true; 1384 } 1385 } 1386 return false; 1387 } //isHeadAssignedAnywhere 1388 1389 /** 1390 * Removes the assignment of the specified SignalHead to either a turnout, a 1391 * positionable point, or a level crossing wherever it is assigned. 1392 * @param head the signal head to be removed. 1393 */ 1394 public void removeAssignment(@Nonnull SignalHead head) { 1395 String sName = head.getSystemName(); 1396 String uName = head.getUserName(); 1397 for (LayoutTurnout to : layoutEditor.getLayoutTurnouts()) { 1398 if ((to.getSignalA1Name().equals(sName) || ((uName != null) 1399 && to.getSignalA1Name().equals(uName)))) { 1400 to.setSignalA1Name(""); 1401 } 1402 if ((to.getSignalA2Name().equals(sName) || ((uName != null) 1403 && to.getSignalA2Name().equals(uName)))) { 1404 to.setSignalA2Name(""); 1405 } 1406 if ((to.getSignalA3Name().equals(sName) || ((uName != null) 1407 && to.getSignalA3Name().equals(uName)))) { 1408 to.setSignalA3Name(""); 1409 } 1410 if ((to.getSignalB1Name().equals(sName) || ((uName != null) 1411 && to.getSignalB1Name().equals(uName)))) { 1412 to.setSignalB1Name(""); 1413 } 1414 if ((to.getSignalB2Name().equals(sName) || ((uName != null) 1415 && to.getSignalB2Name().equals(uName)))) { 1416 to.setSignalB2Name(""); 1417 } 1418 if ((to.getSignalC1Name().equals(sName) || ((uName != null) 1419 && to.getSignalC1Name().equals(uName)))) { 1420 to.setSignalC1Name(""); 1421 } 1422 if ((to.getSignalC2Name().equals(sName) || ((uName != null) 1423 && to.getSignalC2Name().equals(uName)))) { 1424 to.setSignalC2Name(""); 1425 } 1426 if ((to.getSignalD1Name().equals(sName) || ((uName != null) 1427 && to.getSignalD1Name().equals(uName)))) { 1428 to.setSignalD1Name(""); 1429 } 1430 if ((to.getSignalD2Name().equals(sName) || ((uName != null) 1431 && to.getSignalD2Name().equals(uName)))) { 1432 to.setSignalD2Name(""); 1433 } 1434 } 1435 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 1436 if (po.getEastBoundSignal().equals(sName) || po.getEastBoundSignal().equals(uName)) { 1437 po.setEastBoundSignal(""); 1438 } 1439 if (po.getWestBoundSignal().equals(sName) || po.getWestBoundSignal().equals(uName)) { 1440 po.setWestBoundSignal(""); 1441 } 1442 } 1443 for (LevelXing x : layoutEditor.getLevelXings()) { 1444 if ( (x.getSignalAName().equals(sName) || ((uName != null) 1445 && (x.getSignalAName().equals(uName))))) { 1446 x.setSignalAName(""); 1447 } 1448 if ( (x.getSignalBName().equals(sName) || ((uName != null) 1449 && (x.getSignalBName().equals(uName))))) { 1450 x.setSignalBName(""); 1451 } 1452 if ( (x.getSignalCName().equals(sName) || ((uName != null) 1453 && (x.getSignalCName().equals(uName))))) { 1454 x.setSignalCName(""); 1455 } 1456 if ( (x.getSignalDName().equals(sName) || ((uName != null) 1457 && (x.getSignalDName().equals(uName))))) { 1458 x.setSignalDName(""); 1459 } 1460 } 1461 } //removeAssignment 1462 1463 /** 1464 * Removes the SignalHead with the specified name from the panel and from 1465 * assignment to any turnout, positionable point, or level crossing. 1466 * @param signalName name of signal head to be removed. 1467 */ 1468 public void removeSignalHeadFromPanel(@CheckForNull String signalName) { 1469 if ((signalName == null) || signalName.isEmpty()) { 1470 return; 1471 } 1472 SignalHead head = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1473 if (head != null) { 1474 removeAssignment(head); 1475 layoutEditor.removeSignalHead(head); 1476 } 1477 } 1478 1479 /* 1480 * Initializes a BlockBossLogic for creation of a signal logic for the signal 1481 * head named in "signalHeadName". 1482 * Should not be called until enough informmation has been gathered to allow 1483 * configuration of the Simple Signal Logic. 1484 */ 1485 public boolean initializeBlockBossLogic(@Nonnull String signalHeadName) { 1486 logic = BlockBossLogic.getStoppedObject(signalHeadName); 1487 return true; 1488 } 1489 1490 /* 1491 * Finalizes a successfully created signal logic 1492 */ 1493 public void finalizeBlockBossLogic() { 1494 if (logic == null) { 1495 return; 1496 } 1497 InstanceManager.getDefault(BlockBossLogicProvider.class).register(logic); 1498 logic.start(); 1499 logic = null; 1500 } 1501 1502 /* 1503 * Returns the signal head at the end of the block "track" is assigned to. 1504 * "track" is the Track Segment leaving "object". 1505 * "object" must be either an anchor point or one of the connecting 1506 * points of a turnout or level crossing. 1507 * Note: returns 'null' is signal is not present where it is expected, or 1508 * if an End Bumper is reached. To test for end bumper, use the 1509 * associated routine "reachedEndBumper()". Reaching a turntable ray 1510 * track connection is considered reaching an end bumper. 1511 * Note: Normally this routine requires a signal at any turnout it finds. 1512 * However, if 'skipIncludedTurnout' is true, this routine will skip 1513 * over an absent signal at an included turnout, that is a turnout 1514 * with its throat track segment and its continuing track segment in 1515 * the same block. When this happens, the user is warned. 1516 */ 1517 @CheckReturnValue 1518 public SignalHead getNextSignalFromObject(@Nonnull TrackSegment track, 1519 @Nonnull Object object, 1520 @Nonnull String signalHeadName, @Nonnull JmriJFrame frame) { 1521 hitEndBumper = false; 1522 auxSignal = null; 1523 TrackSegment t = track; 1524 Object obj = object; 1525 boolean inBlock = true; 1526 HitPointType type; // = LayoutEditor.HitPointType.NONE; 1527 Object connect = null; 1528 while (inBlock) { 1529 if (t.getConnect1() == obj) { 1530 type = t.getType2(); 1531 connect = t.getConnect2(); 1532 } else if (t.getConnect2() == obj) { 1533 type = t.getType1(); 1534 connect = t.getConnect1(); 1535 } else { 1536 log.error("Error obj not connected to {}!", t.getName()); 1537 return null; 1538 } 1539 if (type == HitPointType.POS_POINT) { 1540 PositionablePoint p = (PositionablePoint) connect; 1541 if (p.getType() == PositionablePoint.PointType.END_BUMPER) { 1542 hitEndBumper = true; 1543 return null; 1544 } 1545 if (p.getConnect1() == t) { 1546 t = p.getConnect2(); 1547 } else { 1548 t = p.getConnect1(); 1549 } 1550 if (t == null) { 1551 return null; 1552 } 1553 if (track.getLayoutBlock() != t.getLayoutBlock()) { 1554 //p is a block boundary - should be signalled 1555 String signalName; 1556 if (isAtWestEndOfAnchor(t, p)) { 1557 signalName = p.getWestBoundSignal(); 1558 } else { 1559 signalName = p.getEastBoundSignal(); 1560 } 1561 if (signalName.isEmpty()) { 1562 return null; 1563 } 1564 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1565 } 1566 obj = p; 1567 } else if (type == HitPointType.TURNOUT_A) { 1568 //Reached turnout throat, should be signalled 1569 LayoutTurnout to = (LayoutTurnout) connect; 1570 String signalName = to.getSignalA2Name(); 1571 if (!signalName.isEmpty()) { 1572 auxSignal = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1573 } 1574 signalName = to.getSignalA1Name(); 1575 if (signalName.isEmpty()) { 1576 if (!layoutEditor.isIncludedTurnoutSkipped()) { 1577 return null; 1578 } 1579 t = getContinuingTrack(to, type); 1580 if ((t == null) || (track.getLayoutBlock() != t.getLayoutBlock())) { 1581 return null; 1582 } 1583 warnOfSkippedTurnout(frame, to.getTurnoutName(), signalHeadName); 1584 obj = to; 1585 } else { 1586 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1587 } 1588 } else if (type == HitPointType.TURNOUT_B) { 1589 //Reached turnout continuing, should be signalled 1590 LayoutTurnout to = (LayoutTurnout) connect; 1591 String signalName = to.getSignalB2Name(); 1592 if (to.getContinuingSense() == Turnout.THROWN) { 1593 signalName = to.getSignalC2Name(); 1594 } 1595 if (!signalName.isEmpty()) { 1596 auxSignal = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1597 } 1598 if (to.getContinuingSense() == Turnout.CLOSED) { 1599 signalName = to.getSignalB1Name(); 1600 } else { 1601 signalName = to.getSignalC1Name(); 1602 } 1603 if (signalName.isEmpty()) { 1604 if (!layoutEditor.isIncludedTurnoutSkipped()) { 1605 return null; 1606 } 1607 t = getContinuingTrack(to, type); 1608 if ((t == null) || (track.getLayoutBlock() != t.getLayoutBlock())) { 1609 return null; 1610 } 1611 warnOfSkippedTurnout(frame, to.getTurnoutName(), signalHeadName); 1612 obj = to; 1613 } else { 1614 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1615 } 1616 } else if (type == HitPointType.TURNOUT_C) { 1617 //Reached turnout diverging, should be signalled 1618 LayoutTurnout to = (LayoutTurnout) connect; 1619 String signalName = to.getSignalC2Name(); 1620 if (to.getContinuingSense() == Turnout.THROWN) { 1621 signalName = to.getSignalB2Name(); 1622 } 1623 if (!signalName.isEmpty()) { 1624 auxSignal = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1625 } 1626 if (to.getContinuingSense() == Turnout.CLOSED) { 1627 signalName = to.getSignalC1Name(); 1628 } else { 1629 signalName = to.getSignalB1Name(); 1630 } 1631 if (signalName.isEmpty()) { 1632 if (!layoutEditor.isIncludedTurnoutSkipped()) { 1633 return null; 1634 } 1635 t = getContinuingTrack(to, type); 1636 if ((t == null) || (track.getLayoutBlock() != t.getLayoutBlock())) { 1637 return null; 1638 } 1639 warnOfSkippedTurnout(frame, to.getTurnoutName(), signalHeadName); 1640 obj = to; 1641 } else { 1642 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1643 } 1644 } else if (type == HitPointType.TURNOUT_D) { 1645 //Reached turnout xover 4, should be signalled 1646 LayoutTurnout to = (LayoutTurnout) connect; 1647 String signalName = to.getSignalD2Name(); 1648 if (!signalName.isEmpty()) { 1649 auxSignal = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1650 } 1651 signalName = to.getSignalD1Name(); 1652 if (signalName.isEmpty()) { 1653 if (!layoutEditor.isIncludedTurnoutSkipped()) { 1654 return null; 1655 } 1656 t = getContinuingTrack(to, type); 1657 if ((t == null) || (track.getLayoutBlock() != t.getLayoutBlock())) { 1658 return null; 1659 } 1660 warnOfSkippedTurnout(frame, to.getTurnoutName(), signalHeadName); 1661 obj = to; 1662 } else { 1663 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1664 } 1665 } else if (type == HitPointType.LEVEL_XING_A) { 1666 //Reached level crossing that may or may not be a block boundary 1667 LevelXing x = (LevelXing) connect; 1668 String signalName = x.getSignalAName(); 1669 if ( !signalName.isEmpty() ) { 1670 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1671 } 1672 t = (TrackSegment) x.getConnectC(); 1673 if (t == null) { 1674 return null; 1675 } 1676 if (track.getLayoutBlock() != t.getLayoutBlock()) { 1677 return null; 1678 } 1679 obj = x; 1680 } else if (type == HitPointType.LEVEL_XING_B) { 1681 //Reached level crossing that may or may not be a block boundary 1682 LevelXing x = (LevelXing) connect; 1683 String signalName = x.getSignalBName(); 1684 if ( !signalName.isEmpty() ) { 1685 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1686 } 1687 t = (TrackSegment) x.getConnectD(); 1688 if (t == null) { 1689 return null; 1690 } 1691 if (track.getLayoutBlock() != t.getLayoutBlock()) { 1692 return null; 1693 } 1694 obj = x; 1695 } else if (type == HitPointType.LEVEL_XING_C) { 1696 //Reached level crossing that may or may not be a block boundary 1697 LevelXing x = (LevelXing) connect; 1698 String signalName = x.getSignalCName(); 1699 if ( !signalName.isEmpty() ) { 1700 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1701 } 1702 t = (TrackSegment) x.getConnectA(); 1703 if (t == null) { 1704 return null; 1705 } 1706 if (track.getLayoutBlock() != t.getLayoutBlock()) { 1707 return null; 1708 } 1709 obj = x; 1710 } else if (type == HitPointType.LEVEL_XING_D) { 1711 //Reached level crossing that may or may not be a block boundary 1712 LevelXing x = (LevelXing) connect; 1713 String signalName = x.getSignalDName(); 1714 if ( !signalName.isEmpty() ) { 1715 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1716 } 1717 t = (TrackSegment) x.getConnectB(); 1718 if (t == null) { 1719 return null; 1720 } 1721 if (track.getLayoutBlock() != t.getLayoutBlock()) { 1722 return null; 1723 } 1724 obj = x; 1725 } else if (type == HitPointType.SLIP_A) { 1726 LayoutSlip sl = (LayoutSlip) connect; 1727 String signalName = sl.getSignalA2Name(); 1728 if (!signalName.isEmpty()) { 1729 auxSignal = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1730 } 1731 signalName = sl.getSignalA1Name(); 1732 if (signalName.isEmpty()) { 1733 if (!layoutEditor.isIncludedTurnoutSkipped()) { 1734 return null; 1735 } 1736 t = getContinuingTrack(sl, type); 1737 if ((t == null) || (track.getLayoutBlock() != t.getLayoutBlock())) { 1738 return null; 1739 } 1740 warnOfSkippedTurnout(frame, sl.getTurnoutName(), signalHeadName); 1741 obj = sl; 1742 } else { 1743 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1744 } 1745 } else if (type == HitPointType.SLIP_B) { 1746 LayoutSlip sl = (LayoutSlip) connect; 1747 String signalName; 1748 if (sl.getTurnoutType() == LayoutSlip.TurnoutType.DOUBLE_SLIP) { 1749 signalName = sl.getSignalB2Name(); 1750 if (!signalName.isEmpty()) { 1751 auxSignal = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1752 } 1753 } 1754 signalName = sl.getSignalB1Name(); 1755 if (signalName.isEmpty()) { 1756 if (!layoutEditor.isIncludedTurnoutSkipped()) { 1757 return null; 1758 } 1759 t = getContinuingTrack(sl, type); 1760 if ((t == null) || (track.getLayoutBlock() != t.getLayoutBlock())) { 1761 return null; 1762 } 1763 warnOfSkippedTurnout(frame, sl.getTurnoutName(), signalHeadName); 1764 obj = sl; 1765 } else { 1766 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1767 } 1768 } else if (type == HitPointType.SLIP_C) { 1769 LayoutSlip sl = (LayoutSlip) connect; 1770 String signalName; 1771 if (sl.getTurnoutType() == LayoutSlip.TurnoutType.DOUBLE_SLIP) { 1772 signalName = sl.getSignalC2Name(); 1773 if (!signalName.isEmpty()) { 1774 auxSignal = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1775 } 1776 } 1777 signalName = sl.getSignalC1Name(); 1778 if (signalName.isEmpty()) { 1779 if (!layoutEditor.isIncludedTurnoutSkipped()) { 1780 return null; 1781 } 1782 t = getContinuingTrack(sl, type); 1783 if ((t == null) || (track.getLayoutBlock() != t.getLayoutBlock())) { 1784 return null; 1785 } 1786 warnOfSkippedTurnout(frame, sl.getTurnoutName(), signalHeadName); 1787 obj = sl; 1788 } else { 1789 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1790 } 1791 } else if (type == HitPointType.SLIP_D) { 1792 LayoutSlip sl = (LayoutSlip) connect; 1793 String signalName = sl.getSignalD2Name(); 1794 if (!signalName.isEmpty()) { 1795 auxSignal = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1796 } 1797 signalName = sl.getSignalD1Name(); 1798 if (signalName.isEmpty()) { 1799 if (!layoutEditor.isIncludedTurnoutSkipped()) { 1800 return null; 1801 } 1802 t = getContinuingTrack(sl, type); 1803 if ((t == null) || (track.getLayoutBlock() != t.getLayoutBlock())) { 1804 return null; 1805 } 1806 warnOfSkippedTurnout(frame, sl.getTurnoutName(), signalHeadName); 1807 obj = sl; 1808 } else { 1809 return InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(signalName); 1810 } 1811 } else if (HitPointType.isTurntableRayHitType(type)) { 1812 hitEndBumper = true; 1813 return null; 1814 } 1815 } 1816 return null; 1817 } //getNextSignalFromObject 1818 1819 private boolean hitEndBumper = false; 1820 1821 private void warnOfSkippedTurnout( 1822 @Nonnull JFrame frame, 1823 @Nonnull String turnoutName, 1824 @Nonnull String signalHeadName) { 1825 JmriJOptionPane.showMessageDialog(frame, 1826 Bundle.getMessage("SignalsWarn2", 1827 new Object[]{turnoutName, signalHeadName}), 1828 Bundle.getMessage("WarningTitle"), 1829 JmriJOptionPane.WARNING_MESSAGE); 1830 } 1831 1832 @CheckReturnValue 1833 private TrackSegment getContinuingTrack(@Nonnull LayoutTurnout to, HitPointType type) { 1834 LayoutTurnout.TurnoutType ty = to.getTurnoutType(); 1835 if ((ty == LayoutTurnout.TurnoutType.RH_TURNOUT) || (ty == LayoutTurnout.TurnoutType.LH_TURNOUT)) { 1836 if (type == HitPointType.TURNOUT_A) { 1837 if (to.getContinuingSense() == Turnout.CLOSED) { 1838 return (TrackSegment) to.getConnectB(); 1839 } else { 1840 return (TrackSegment) to.getConnectC(); 1841 } 1842 } else { 1843 return (TrackSegment) to.getConnectA(); 1844 } 1845 } else if ((ty == LayoutTurnout.TurnoutType.DOUBLE_XOVER) || (ty == LayoutTurnout.TurnoutType.RH_XOVER) 1846 || (ty == LayoutTurnout.TurnoutType.LH_XOVER)) { 1847 if (type == HitPointType.TURNOUT_A) { 1848 return (TrackSegment) to.getConnectB(); 1849 } else if (type == HitPointType.TURNOUT_B) { 1850 return (TrackSegment) to.getConnectA(); 1851 } else if (type == HitPointType.TURNOUT_C) { 1852 return (TrackSegment) to.getConnectD(); 1853 } else if (type == HitPointType.TURNOUT_D) { 1854 return (TrackSegment) to.getConnectC(); 1855 } 1856 } 1857 log.error("Bad connection type around turnout {}", to.getTurnoutName()); 1858 return null; 1859 } 1860 1861 /* 1862 * Returns 'true' if an end bumper was reached during the last call to 1863 * GetNextSignalFromObject. Also used in the odd case of reaching a 1864 * turntable ray track connection, which is treated as an end 1865 * bumper here. 1866 */ 1867 public boolean reachedEndBumper() { 1868 return hitEndBumper; 1869 } 1870 1871 /* 1872 * Returns 'true' if "track" enters a block boundary at the west(north) end of 1873 * "point". Returns "false" otherwise. If track is neither horizontal or 1874 * vertical, assumes horizontal, as done when setting signals at block boundary. 1875 * "track" is a TrackSegment connected to "point". 1876 * "point" is an anchor point serving as a block boundary. 1877 * <p> 1878 * This is the member function method, which is preferred. See the static 1879 * method following. 1880 */ 1881 public boolean isAtWestEndOfAnchor(TrackSegment t, PositionablePoint p) { 1882 return LayoutEditorTools.isAtWestEndOfAnchor(layoutEditor, t, p); // invoke status locally 1883 } 1884 1885 1886 /* 1887 * Returns 'true' if "track" enters a block boundary at the west(north) end of 1888 * "point". Returns "false" otherwise. If track is neither horizontal or 1889 * vertical, assumes horizontal, as done when setting signals at block boundary. 1890 * "track" is a TrackSegment connected to "point". 1891 * "point" is an anchor point serving as a block boundary. 1892 * <p> 1893 * This is the static form, which requires context information from 1894 * a passed LayoutEditor reference; the member function is preferred because 1895 * some day we want to get rid of the LayoutEditor combined pseudo-global and panel reference. 1896 */ 1897 public static boolean isAtWestEndOfAnchor(LayoutEditor layoutEditor, TrackSegment t, PositionablePoint p) { 1898 if (p.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 1899 if (p.getConnect1() == t) { 1900 if (p.getConnect1Dir() == Path.NORTH || p.getConnect1Dir() == Path.WEST) { 1901 return false; 1902 } 1903 return true; 1904 } else { 1905 if (p.getConnect1Dir() == Path.NORTH || p.getConnect1Dir() == Path.WEST) { 1906 return true; 1907 } 1908 return false; 1909 } 1910 1911 } 1912 TrackSegment tx = null; 1913 if (p.getConnect1() == t) { 1914 tx = p.getConnect2(); 1915 } else if (p.getConnect2() == t) { 1916 tx = p.getConnect1(); 1917 } else { 1918 log.error("track not connected to anchor point"); 1919 return false; 1920 } 1921 1922 Point2D coords1; 1923 if (t.getConnect1() == p) { 1924 coords1 = layoutEditor.getCoords(t.getConnect2(), t.getType2()); 1925 } else { 1926 coords1 = layoutEditor.getCoords(t.getConnect1(), t.getType1()); 1927 } 1928 1929 Point2D coords2; 1930 if (tx != null) { 1931 if (tx.getConnect1() == p) { 1932 coords2 = layoutEditor.getCoords(tx.getConnect2(), tx.getType2()); 1933 } else { 1934 coords2 = layoutEditor.getCoords(tx.getConnect1(), tx.getType1()); 1935 } 1936 } else { 1937 if (t.getConnect1() == p) { 1938 coords2 = layoutEditor.getCoords(t.getConnect1(), t.getType1()); 1939 } else { 1940 coords2 = layoutEditor.getCoords(t.getConnect2(), t.getType2()); 1941 } 1942 } 1943 1944 double delX = coords1.getX() - coords2.getX(); 1945 double delY = coords1.getY() - coords2.getY(); 1946 if (Math.abs(delX) > 2.0 * Math.abs(delY)) { 1947 //track is primarily horizontal 1948 if (delX > 0.0) { 1949 return false; 1950 } else { 1951 return true; 1952 } 1953 } else if (Math.abs(delY) > 2.0 * Math.abs(delX)) { 1954 //track is primarily vertical 1955 if (delY > 0.0) { 1956 return false; 1957 } else { 1958 return true; 1959 } 1960 } 1961 // track is not primarily horizontal or vertical; assume horizontal 1962 // log.error ("Track is not vertical or horizontal at anchor"); 1963 if (delX > 0.0) { 1964 return false; 1965 } 1966 return true; 1967 } 1968 1969 /*===========================*\ 1970 |* setSignalsAtBlockBoundary *| 1971 \*===========================*/ 1972 /** 1973 * Tool to set signals at a block boundary, including placing the signal 1974 * icons and setup of Simple Signal Logic for each signal head 1975 * <p> 1976 * Block boundary must be at an Anchor Point on the LayoutEditor panel. 1977 */ 1978 //operational variables for Set Signals at Block Boundary tool 1979 private JmriJFrame setSignalsAtBlockBoundaryFrame = null; 1980 private boolean setSignalsAtBlockBoundaryOpenFlag = false; 1981 private boolean setSignalsAtBlockBoundaryFromMenuFlag = false; 1982 1983 private JLabel block1NameLabel = null; 1984 private JLabel block2NameLabel = null; 1985 1986 private final NamedBeanComboBox<Block> block1IDComboBox = new NamedBeanComboBox<>( 1987 InstanceManager.getDefault(BlockManager.class), 1988 null, DisplayOptions.DISPLAYNAME); 1989 private final NamedBeanComboBox<Block> block2IDComboBox = new NamedBeanComboBox<>( 1990 InstanceManager.getDefault(BlockManager.class), 1991 null, DisplayOptions.DISPLAYNAME); 1992 1993 private final NamedBeanComboBox<SignalHead> eastBoundSignalHeadComboBox = new NamedBeanComboBox<>( 1994 InstanceManager.getDefault(SignalHeadManager.class), 1995 null, DisplayOptions.DISPLAYNAME); 1996 private final NamedBeanComboBox<SignalHead> westBoundSignalHeadComboBox = new NamedBeanComboBox<>( 1997 InstanceManager.getDefault(SignalHeadManager.class), 1998 null, DisplayOptions.DISPLAYNAME); 1999 2000 private final JCheckBox setEastBound = new JCheckBox(Bundle.getMessage("PlaceHead")); 2001 private final JCheckBox setupLogicEastBound = new JCheckBox(Bundle.getMessage("SetLogic")); 2002 private final JCheckBox setWestBound = new JCheckBox(Bundle.getMessage("PlaceHead")); 2003 private final JCheckBox setupLogicWestBound = new JCheckBox(Bundle.getMessage("SetLogic")); 2004 2005 private JButton getAnchorSavedSignalHeads = null; 2006 private JButton changeSignalAtBoundaryIcon = null; 2007 private JButton setSignalsAtBlockBoundaryDone = null; 2008 private JButton setSignalsAtBlockBoundaryCancel = null; 2009 2010 private LayoutBlock block1 = null; 2011 private LayoutBlock block2 = null; 2012 2013 private TrackSegment eastTrack = null; 2014 private TrackSegment westTrack = null; 2015 2016 private PositionablePoint boundary = null; 2017 private SignalHead eastBoundHead = null; 2018 private SignalHead westBoundHead = null; 2019 2020 private boolean showWest = true; 2021 private boolean showEast = true; 2022 2023 //display dialog for Set Signals at Block Boundary tool 2024 public void setSignalsAtBlockBoundaryFromMenu(PositionablePoint p, 2025 MultiIconEditor theEditor, 2026 JFrame theFrame) { 2027 boundary = p; 2028 2029 //if this is an edge connector... 2030 if ((p.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) && ((p.getLinkedPoint() == null) 2031 || (p.getLinkedPoint().getConnect1() == null))) { 2032 if (p.getConnect1Dir() == Path.EAST || p.getConnect1Dir() == Path.SOUTH) { 2033 showWest = false; 2034 } else { 2035 showEast = false; 2036 } 2037 block1IDComboBox.setSelectedItem(boundary.getConnect1().getLayoutBlock().getBlock()); 2038 } else { 2039 block1IDComboBox.setSelectedItem(boundary.getConnect1().getLayoutBlock().getBlock()); 2040 block2IDComboBox.setSelectedItem(boundary.getConnect2().getLayoutBlock().getBlock()); 2041 } 2042 setSignalsAtBlockBoundaryFromMenuFlag = true; 2043 setSignalsAtBlockBoundary(theEditor, theFrame); 2044 setSignalsAtBlockBoundaryFromMenuFlag = false; 2045 } 2046 2047 public void setSignalsAtBlockBoundary(MultiIconEditor theEditor, JFrame theFrame) { 2048 signalIconEditor = theEditor; 2049 signalFrame = theFrame; 2050 2051 //Initialize if needed 2052 if (setSignalsAtBlockBoundaryFrame == null) { 2053 setSignalsAtBlockBoundaryOpenFlag = false; 2054 setSignalsAtBlockBoundaryFrame = new JmriJFrame(Bundle.getMessage("SignalsAtBoundary"), false, true); 2055 oneFrameToRuleThemAll(setSignalsAtBlockBoundaryFrame); 2056 setSignalsAtBlockBoundaryFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 2057 setSignalsAtBlockBoundaryFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtBoundary", true); 2058 setSignalsAtBlockBoundaryFrame.setLocation(70, 30); 2059 Container theContentPane = setSignalsAtBlockBoundaryFrame.getContentPane(); 2060 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 2061 2062 JPanel panel11 = new JPanel(new FlowLayout()); 2063 block1NameLabel = new JLabel( 2064 Bundle.getMessage("MakeLabel", 2065 Bundle.getMessage("BeanNameBlock") + " 1 ")); 2066 panel11.add(block1NameLabel); 2067 panel11.add(block1IDComboBox); 2068 block1IDComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHintNW")); 2069 theContentPane.add(panel11); 2070 2071 JPanel panel12 = new JPanel(new FlowLayout()); 2072 block2NameLabel = new JLabel( 2073 Bundle.getMessage("MakeLabel", 2074 Bundle.getMessage("BeanNameBlock") 2075 + " 2 " + Bundle.getMessage("Name"))); 2076 panel12.add(block2NameLabel); 2077 panel12.add(block2IDComboBox); 2078 block2IDComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHintSE")); 2079 theContentPane.add(panel12); 2080 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 2081 2082 JPanel panel2 = new JPanel(new FlowLayout()); 2083 JLabel shTitle = new JLabel(Bundle.getMessage("SignalHeads")); 2084 panel2.add(shTitle); 2085 panel2.add(new JLabel(" ")); 2086 panel2.add(getAnchorSavedSignalHeads = new JButton(Bundle.getMessage("GetSaved"))); 2087 getAnchorSavedSignalHeads.addActionListener(this::getSavedAnchorSignals); 2088 getAnchorSavedSignalHeads.setToolTipText(Bundle.getMessage("GetSavedHint")); 2089 theContentPane.add(panel2); 2090 if (showEast) { 2091 JPanel panel21 = new JPanel(new FlowLayout()); 2092 JLabel eastBoundLabel = new JLabel(Bundle.getMessage("East/SouthBound") + ": "); 2093 panel21.add(eastBoundLabel); 2094 panel21.add(eastBoundSignalHeadComboBox); 2095 theContentPane.add(panel21); 2096 eastBoundSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadEastNameHint")); 2097 2098 JPanel panel22 = new JPanel(new FlowLayout()); 2099 panel22.add(new JLabel(" ")); 2100 panel22.add(setEastBound); 2101 setEastBound.setToolTipText(Bundle.getMessage("AnchorPlaceHeadHint")); 2102 panel22.add(new JLabel(" ")); 2103 if (showWest) { 2104 panel22.add(setupLogicEastBound); 2105 setupLogicEastBound.setToolTipText(Bundle.getMessage("SetLogicHint")); 2106 } 2107 theContentPane.add(panel22); 2108 } 2109 if (showWest) { 2110 JPanel panel31 = new JPanel(new FlowLayout()); 2111 JLabel westBoundLabel = new JLabel(Bundle.getMessage("West/NorthBound") + ": "); 2112 panel31.add(westBoundLabel); 2113 panel31.add(westBoundSignalHeadComboBox); 2114 theContentPane.add(panel31); 2115 westBoundSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadWestNameHint")); 2116 2117 JPanel panel32 = new JPanel(new FlowLayout()); 2118 panel32.add(new JLabel(" ")); 2119 panel32.add(setWestBound); 2120 setWestBound.setToolTipText(Bundle.getMessage("AnchorPlaceHeadHint")); 2121 panel32.add(new JLabel(" ")); 2122 if (showEast) { 2123 panel32.add(setupLogicWestBound); 2124 setupLogicWestBound.setToolTipText(Bundle.getMessage("SetLogicHint")); 2125 } 2126 theContentPane.add(panel32); 2127 } 2128 2129 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 2130 2131 JPanel panel6 = new JPanel(new FlowLayout()); 2132 panel6.add(changeSignalAtBoundaryIcon = new JButton(Bundle.getMessage("ChangeSignalIcon"))); 2133 changeSignalAtBoundaryIcon.addActionListener((ActionEvent e) -> signalFrame.setVisible(true)); 2134 changeSignalAtBoundaryIcon.setToolTipText(Bundle.getMessage("ChangeSignalIconHint")); 2135 panel6.add(new JLabel(" ")); 2136 panel6.add(setSignalsAtBlockBoundaryDone = new JButton(Bundle.getMessage("ButtonDone"))); 2137 setSignalsAtBlockBoundaryDone.addActionListener(this::setSignalsAtBlockBoundaryDonePressed); 2138 setSignalsAtBlockBoundaryDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 2139 2140 panel6.add(setSignalsAtBlockBoundaryCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 2141 setSignalsAtBlockBoundaryCancel.addActionListener(this::setSignalsAtBlockBoundaryCancelPressed); 2142 setSignalsAtBlockBoundaryCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 2143 theContentPane.add(panel6); 2144 2145 //make this button the default button (return or enter activates) 2146 JRootPane rootPane = SwingUtilities.getRootPane(setSignalsAtBlockBoundaryDone); 2147 if (rootPane != null) { //this should never happen but just in case... 2148 rootPane.setDefaultButton(setSignalsAtBlockBoundaryDone); 2149 } 2150 2151 setSignalsAtBlockBoundaryFrame.addWindowListener(new WindowAdapter() { 2152 @Override 2153 public void windowClosing(WindowEvent e) { 2154 setSignalsAtBlockBoundaryCancelPressed(null); 2155 } 2156 }); 2157 } 2158 2159 block1IDComboBox.setVisible(!setSignalsAtBlockBoundaryFromMenuFlag); 2160 block2IDComboBox.setVisible(!setSignalsAtBlockBoundaryFromMenuFlag); 2161 2162 if (setSignalsAtBlockBoundaryFromMenuFlag) { 2163 getSavedAnchorSignals(null); 2164 block1NameLabel.setText(Bundle.getMessage("MakeLabel", 2165 Bundle.getMessage("BeanNameBlock") 2166 + " 1 " + Bundle.getMessage("Name")) 2167 + boundary.getConnect1().getLayoutBlock().getId()); 2168 if (boundary.getConnect2() != null) { 2169 block2NameLabel.setText(Bundle.getMessage("MakeLabel", 2170 Bundle.getMessage("BeanNameBlock") 2171 + " 2 " + Bundle.getMessage("Name")) 2172 + boundary.getConnect2().getLayoutBlock().getId()); 2173 } 2174 } 2175 2176 if (!setSignalsAtBlockBoundaryOpenFlag) { 2177 setSignalsAtBlockBoundaryFrame.setPreferredSize(null); 2178 setSignalsAtBlockBoundaryFrame.pack(); 2179 setSignalsAtBlockBoundaryOpenFlag = true; 2180 } 2181 setSignalsAtBlockBoundaryFrame.setVisible(true); 2182 } //setSignalsAtBlockBoundary 2183 2184 private void getSavedAnchorSignals(ActionEvent a) { 2185 if (!getBlockInformation()) { 2186 return; 2187 } 2188 eastBoundSignalHeadComboBox.setSelectedItem(boundary.getEastBoundSignalHead()); 2189 westBoundSignalHeadComboBox.setSelectedItem(boundary.getWestBoundSignalHead()); 2190 } 2191 2192 private void setSignalsAtBlockBoundaryCancelPressed(ActionEvent a) { 2193 setSignalsAtBlockBoundaryOpenFlag = false; 2194 setSignalsAtBlockBoundaryFrame.setVisible(false); 2195 } 2196 2197 private void setSignalsAtBlockBoundaryDonePressed(ActionEvent a) { 2198 if (!getBlockInformation()) { 2199 return; 2200 } 2201 eastBoundHead = getSignalHeadFromEntry(eastBoundSignalHeadComboBox, false, setSignalsAtBlockBoundaryFrame); 2202 westBoundHead = getSignalHeadFromEntry(westBoundSignalHeadComboBox, false, setSignalsAtBlockBoundaryFrame); 2203 if ((eastBoundHead == null) && (westBoundHead == null)) { 2204 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2205 Bundle.getMessage("SignalsError12"), 2206 Bundle.getMessage("ErrorTitle"), 2207 JmriJOptionPane.ERROR_MESSAGE); 2208 return; 2209 } 2210 //place or update signals as requested 2211 String newEastBoundSignalName = eastBoundSignalHeadComboBox.getSelectedItemDisplayName(); 2212 if (newEastBoundSignalName == null) { 2213 newEastBoundSignalName = ""; 2214 } 2215 if ((eastBoundHead != null) && setEastBound.isSelected()) { 2216 if (isHeadOnPanel(eastBoundHead) 2217 && (eastBoundHead != getHeadFromName(boundary.getEastBoundSignal()))) { 2218 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2219 Bundle.getMessage("SignalsError6", 2220 new Object[]{newEastBoundSignalName}), 2221 Bundle.getMessage("ErrorTitle"), 2222 JmriJOptionPane.ERROR_MESSAGE); 2223 return; 2224 } else { 2225 removeSignalHeadFromPanel(boundary.getEastBoundSignal()); 2226 placeEastBound(); 2227 removeAssignment(eastBoundHead); 2228 boundary.setEastBoundSignal(newEastBoundSignalName); 2229 needRedraw = true; 2230 } 2231 } else if ((eastBoundHead != null) 2232 && (eastBoundHead != getHeadFromName(boundary.getEastBoundSignal())) 2233 && (eastBoundHead != getHeadFromName(boundary.getWestBoundSignal()))) { 2234 if (isHeadOnPanel(eastBoundHead)) { 2235 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2236 Bundle.getMessage("SignalsError13", 2237 new Object[]{newEastBoundSignalName}), 2238 Bundle.getMessage("ErrorTitle"), 2239 JmriJOptionPane.ERROR_MESSAGE); 2240 return; 2241 } else { 2242 removeSignalHeadFromPanel(boundary.getEastBoundSignal()); 2243 removeAssignment(eastBoundHead); 2244 boundary.setEastBoundSignal(newEastBoundSignalName); 2245 } 2246 //} else if ((eastBoundHead != null) 2247 // && (eastBoundHead == getHeadFromName(boundary.getWestBoundSignal()))) { 2248 //need to figure out what to do in this case. 2249 } 2250 String newWestBoundSignalName = westBoundSignalHeadComboBox.getSelectedItemDisplayName(); 2251 if (newWestBoundSignalName == null) { 2252 newWestBoundSignalName = ""; 2253 } 2254 if ((westBoundHead != null) && setWestBound.isSelected()) { 2255 if (isHeadOnPanel(westBoundHead) 2256 && (westBoundHead != getHeadFromName(boundary.getWestBoundSignal()))) { 2257 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2258 Bundle.getMessage("SignalsError6", 2259 new Object[]{newWestBoundSignalName}), 2260 Bundle.getMessage("ErrorTitle"), 2261 JmriJOptionPane.ERROR_MESSAGE); 2262 return; 2263 } else { 2264 removeSignalHeadFromPanel(boundary.getWestBoundSignal()); 2265 placeWestBound(); 2266 removeAssignment(westBoundHead); 2267 boundary.setWestBoundSignal(newWestBoundSignalName); 2268 needRedraw = true; 2269 } 2270 } else if ((westBoundHead != null) 2271 && (westBoundHead != getHeadFromName(boundary.getEastBoundSignal())) 2272 && (westBoundHead != getHeadFromName(boundary.getWestBoundSignal()))) { 2273 if (isHeadOnPanel(westBoundHead)) { 2274 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2275 Bundle.getMessage("SignalsError13", 2276 new Object[]{newWestBoundSignalName}), 2277 Bundle.getMessage("ErrorTitle"), 2278 JmriJOptionPane.ERROR_MESSAGE); 2279 return; 2280 } else { 2281 removeSignalHeadFromPanel(boundary.getWestBoundSignal()); 2282 removeAssignment(westBoundHead); 2283 boundary.setWestBoundSignal(newWestBoundSignalName); 2284 } 2285 //} else if ((westBoundHead != null) 2286 // && (westBoundHead == getHeadFromName(boundary.getEastBoundSignal()))) { 2287 //need to figure out what to do in this case. 2288 } 2289 if ((eastBoundHead != null) && setupLogicEastBound.isSelected()) { 2290 setLogicEastBound(); 2291 } 2292 if ((westBoundHead != null) && setupLogicWestBound.isSelected()) { 2293 setLogicWestBound(); 2294 } 2295 setSignalsAtBlockBoundaryOpenFlag = false; 2296 setSignalsAtBlockBoundaryFrame.setVisible(false); 2297 if (needRedraw) { 2298 layoutEditor.redrawPanel(); 2299 needRedraw = false; 2300 layoutEditor.setDirty(); 2301 } 2302 } //setSignalsAtBlockBoundaryDonePressed 2303 2304 /* 2305 * Do some thing here for end bumpers. 2306 */ 2307 private boolean getBlockInformation() { 2308 //might have to do something to trick it with an end bumper 2309 if (!setSignalsAtBlockBoundaryFromMenuFlag) { 2310 block1 = getBlockFromEntry(block1IDComboBox); 2311 if (block1 == null) { 2312 return false; 2313 } 2314 block2 = getBlockFromEntry(block2IDComboBox); 2315 if (block2 == null) { 2316 return false; 2317 } 2318 boundary = null; 2319 for (PositionablePoint p : layoutEditor.getPositionablePoints()) { 2320 if (p.getType() == PositionablePoint.PointType.ANCHOR || p.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 2321 LayoutBlock bA = null; 2322 LayoutBlock bB = null; 2323 if (p.getConnect1() != null) { 2324 bA = p.getConnect1().getLayoutBlock(); 2325 } 2326 if (p.getConnect2() != null) { 2327 bB = p.getConnect2().getLayoutBlock(); 2328 } 2329 if ((bA != null) && (bB != null) && (bA != bB)) { 2330 if (((bA == block1) && (bB == block2)) 2331 || ((bA == block2) && (bB == block1))) { 2332 boundary = p; 2333 break; 2334 } 2335 } 2336 } 2337 } 2338 if (boundary == null) { 2339 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2340 Bundle.getMessage("SignalsError7"), 2341 Bundle.getMessage("ErrorTitle"), 2342 JmriJOptionPane.ERROR_MESSAGE); 2343 return false; 2344 } 2345 } 2346 //set track orientation at boundary 2347 eastTrack = null; 2348 westTrack = null; 2349 TrackSegment track1 = boundary.getConnect1(); 2350 Point2D coords1; 2351 if (track1.getConnect1() == boundary) { 2352 coords1 = layoutEditor.getCoords(track1.getConnect2(), track1.getType2()); 2353 } else { 2354 coords1 = layoutEditor.getCoords(track1.getConnect1(), track1.getType1()); 2355 } 2356 TrackSegment track2 = boundary.getConnect2(); 2357 2358 if (boundary.getType() == PositionablePoint.PointType.END_BUMPER) { 2359 return true; 2360 } 2361 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 2362 if (boundary.getConnect1Dir() == Path.EAST || boundary.getConnect1Dir() == Path.SOUTH) { 2363 eastTrack = track2; 2364 westTrack = track1; 2365 } else { 2366 westTrack = track2; 2367 eastTrack = track1; 2368 } 2369 return true; 2370 } 2371 Point2D coords2; 2372 if (track2.getConnect1() == boundary) { 2373 coords2 = layoutEditor.getCoords(track2.getConnect2(), track2.getType2()); 2374 } else { 2375 coords2 = layoutEditor.getCoords(track2.getConnect1(), track2.getType1()); 2376 } 2377 2378 placeSignalDirectionDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coords2, coords1)); 2379 2380 double delX = coords1.getX() - coords2.getX(); 2381 double delY = coords1.getY() - coords2.getY(); 2382 2383 if (Math.abs(delX) >= Math.abs(delY)) { 2384 if (delX > 0.0) { 2385 eastTrack = track1; 2386 westTrack = track2; 2387 } else { 2388 eastTrack = track2; 2389 westTrack = track1; 2390 } 2391 } else { 2392 if (delY > 0.0) { 2393 eastTrack = track1; //south 2394 westTrack = track2; //north 2395 } else { 2396 eastTrack = track2; //south 2397 westTrack = track1; //north 2398 } 2399 } 2400 return true; 2401 } //getBlockInformation 2402 2403 @CheckReturnValue 2404 private LayoutBlock getBlockFromEntry(@Nonnull NamedBeanComboBox<Block> blockNameComboBox) { 2405 return getBlockFromEntry(blockNameComboBox.getSelectedItemDisplayName()); 2406 } 2407 2408 @CheckReturnValue 2409 private LayoutBlock getBlockFromEntry(@CheckForNull String theBlockName) { 2410 if ((theBlockName == null) || theBlockName.isEmpty()) { 2411 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2412 Bundle.getMessage("SignalsError9"), 2413 Bundle.getMessage("ErrorTitle"), 2414 JmriJOptionPane.ERROR_MESSAGE); 2415 return null; 2416 } 2417 LayoutBlock block = InstanceManager.getDefault(LayoutBlockManager.class).getByUserName(theBlockName); 2418 if (block == null) { 2419 block = InstanceManager.getDefault(LayoutBlockManager.class).getBySystemName(theBlockName); 2420 if (block == null) { 2421 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2422 Bundle.getMessage("SignalsError10", 2423 new Object[]{theBlockName}), Bundle.getMessage("ErrorTitle"), 2424 JmriJOptionPane.ERROR_MESSAGE); 2425 return null; 2426 } 2427 } 2428 if (!block.isOnPanel(layoutEditor) 2429 && ((boundary == null) || boundary.getType() != PositionablePoint.PointType.EDGE_CONNECTOR)) { 2430 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2431 Bundle.getMessage("SignalsError11", 2432 new Object[]{theBlockName}), Bundle.getMessage("ErrorTitle"), 2433 JmriJOptionPane.ERROR_MESSAGE); 2434 return null; 2435 } 2436 return (block); 2437 } 2438 2439 private void placeEastBound() { 2440 if (testIcon == null) { 2441 testIcon = signalIconEditor.getIcon(0); 2442 } 2443 String signalHeadName = eastBoundSignalHeadComboBox.getSelectedItemDisplayName(); 2444 if (signalHeadName == null) { 2445 signalHeadName = ""; 2446 } 2447 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 2448 2449 Point2D coords = layoutEditor.getLayoutTrackView(boundary).getCoordsCenter(); 2450 Point2D delta = new Point2D.Double(0.0, +shift); 2451 2452 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 2453 Point2D where = MathUtil.add(coords, delta); 2454 setSignalHeadOnPanel(placeSignalDirectionDEG + 180.0, signalHeadName, where); 2455 } 2456 2457 private void placeWestBound() { 2458 if (testIcon == null) { 2459 testIcon = signalIconEditor.getIcon(0); 2460 } 2461 String signalHeadName = westBoundSignalHeadComboBox.getSelectedItemDisplayName(); 2462 if (signalHeadName == null) { 2463 signalHeadName = ""; 2464 } 2465 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 2466 2467 Point2D coords = layoutEditor.getLayoutTrackView(boundary).getCoordsCenter(); 2468 2469 Point2D delta = new Point2D.Double(0.0, -shift); 2470 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 2471 Point2D where = MathUtil.add(coords, delta); 2472 setSignalHeadOnPanel(placeSignalDirectionDEG, signalHeadName, where); 2473 } 2474 2475 private void setLogicEastBound() { 2476 LayoutBlock eastBlock = eastTrack.getLayoutBlock(); 2477 Sensor eastBlockOccupancy = eastBlock.getOccupancySensor(); 2478 if (eastBlockOccupancy == null) { 2479 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2480 Bundle.getMessage("InfoMessage4", 2481 new Object[]{eastBlock.getUserName()}), 2482 Bundle.getMessage("MessageTitle"), 2483 JmriJOptionPane.INFORMATION_MESSAGE); 2484 return; 2485 } 2486 PositionablePoint p = boundary; 2487 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR && eastTrack != boundary.getConnect1()) { 2488 p = boundary.getLinkedPoint(); 2489 } 2490 String newEastBoundSignalName = eastBoundSignalHeadComboBox.getSelectedItemDisplayName(); 2491 if (newEastBoundSignalName == null) { 2492 newEastBoundSignalName = ""; 2493 } 2494 SignalHead nextHead = getNextSignalFromObject(eastTrack, 2495 p, newEastBoundSignalName, setSignalsAtBlockBoundaryFrame); 2496 if ((nextHead == null) && (!reachedEndBumper())) { 2497 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2498 Bundle.getMessage("InfoMessage5", 2499 new Object[]{eastBlock.getUserName()}), 2500 Bundle.getMessage("MessageTitle"), 2501 JmriJOptionPane.INFORMATION_MESSAGE); 2502 return; 2503 } 2504 2505 if (!initializeBlockBossLogic(newEastBoundSignalName)) { 2506 return; 2507 } 2508 logic.setMode(BlockBossLogic.SINGLEBLOCK); 2509 logic.setSensor1(eastBlockOccupancy.getDisplayName()); 2510 if (nextHead != null) { 2511 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 2512 } 2513 if (auxSignal != null) { 2514 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 2515 } 2516 finalizeBlockBossLogic(); 2517 } 2518 2519 private void setLogicWestBound() { 2520 LayoutBlock westBlock = westTrack.getLayoutBlock(); 2521 Sensor westBlockOccupancy = westBlock.getOccupancySensor(); 2522 if (westBlockOccupancy == null) { 2523 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2524 Bundle.getMessage("InfoMessage4", 2525 new Object[]{westBlock.getUserName()}), 2526 Bundle.getMessage("MessageTitle"), 2527 JmriJOptionPane.INFORMATION_MESSAGE); 2528 return; 2529 } 2530 PositionablePoint p = boundary; 2531 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR && westTrack != boundary.getConnect1()) { 2532 p = boundary.getLinkedPoint(); 2533 } 2534 String newWestBoundSignalName = westBoundSignalHeadComboBox.getSelectedItemDisplayName(); 2535 if (newWestBoundSignalName == null) { 2536 newWestBoundSignalName = ""; 2537 } 2538 SignalHead nextHead = getNextSignalFromObject(westTrack, 2539 p, newWestBoundSignalName, setSignalsAtBlockBoundaryFrame); 2540 if ((nextHead == null) && (!reachedEndBumper())) { 2541 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 2542 Bundle.getMessage("InfoMessage5", 2543 new Object[]{westBlock.getUserName()}), 2544 Bundle.getMessage("MessageTitle"), 2545 JmriJOptionPane.INFORMATION_MESSAGE); 2546 return; 2547 } 2548 if (!initializeBlockBossLogic(newWestBoundSignalName)) { 2549 return; 2550 } 2551 logic.setMode(BlockBossLogic.SINGLEBLOCK); 2552 logic.setSensor1(westBlockOccupancy.getDisplayName()); 2553 if (nextHead != null) { 2554 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 2555 } 2556 if (auxSignal != null) { 2557 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 2558 } 2559 finalizeBlockBossLogic(); 2560 } 2561 2562 /*==========================*\ 2563 |* setSignalsAtXoverTurnout *| 2564 \*==========================*/ 2565 /** 2566 * Tool to set signals at a double crossover turnout, including placing the 2567 * signal icons and setup of Simple Signal Logic for each signal head 2568 * <p> 2569 * This tool assumes left facing signal head icons have been selected, and 2570 * will rotate the signal head icons accordingly. 2571 * <p> 2572 * This tool will place icons on the outside edge of the turnout. 2573 * <p> 2574 * At least one signal at each of the four connection points is required. A 2575 * second signal at each is optional. 2576 */ 2577 //operational variables for Set Signals at Double Crossover Turnout tool 2578 private JmriJFrame setSignalsAtXoverTurnoutFrame = null; 2579 private boolean setSignalsAtXoverTurnoutOpenFlag = false; 2580 private boolean setSignalsAtXoverTurnoutFromMenuFlag = false; 2581 2582 private final NamedBeanComboBox<SignalHead> a1SignalHeadComboBox = new NamedBeanComboBox<>( 2583 InstanceManager.getDefault(SignalHeadManager.class), 2584 null, DisplayOptions.DISPLAYNAME); 2585 private final NamedBeanComboBox<SignalHead> a2SignalHeadComboBox = new NamedBeanComboBox<>( 2586 InstanceManager.getDefault(SignalHeadManager.class), 2587 null, DisplayOptions.DISPLAYNAME); 2588 private final NamedBeanComboBox<SignalHead> b1SignalHeadComboBox = new NamedBeanComboBox<>( 2589 InstanceManager.getDefault(SignalHeadManager.class), 2590 null, DisplayOptions.DISPLAYNAME); 2591 private final NamedBeanComboBox<SignalHead> b2SignalHeadComboBox = new NamedBeanComboBox<>( 2592 InstanceManager.getDefault(SignalHeadManager.class), 2593 null, DisplayOptions.DISPLAYNAME); 2594 private final NamedBeanComboBox<SignalHead> c1SignalHeadComboBox = new NamedBeanComboBox<>( 2595 InstanceManager.getDefault(SignalHeadManager.class), 2596 null, DisplayOptions.DISPLAYNAME); 2597 private final NamedBeanComboBox<SignalHead> c2SignalHeadComboBox = new NamedBeanComboBox<>( 2598 InstanceManager.getDefault(SignalHeadManager.class), 2599 null, DisplayOptions.DISPLAYNAME); 2600 private final NamedBeanComboBox<SignalHead> d1SignalHeadComboBox = new NamedBeanComboBox<>( 2601 InstanceManager.getDefault(SignalHeadManager.class), 2602 null, DisplayOptions.DISPLAYNAME); 2603 private final NamedBeanComboBox<SignalHead> d2SignalHeadComboBox = new NamedBeanComboBox<>( 2604 InstanceManager.getDefault(SignalHeadManager.class), 2605 null, DisplayOptions.DISPLAYNAME); 2606 2607 private final JCheckBox setA1Head = new JCheckBox(Bundle.getMessage("PlaceHead")); 2608 private final JCheckBox setA2Head = new JCheckBox(Bundle.getMessage("PlaceHead")); 2609 private final JCheckBox setB1Head = new JCheckBox(Bundle.getMessage("PlaceHead")); 2610 private final JCheckBox setB2Head = new JCheckBox(Bundle.getMessage("PlaceHead")); 2611 private final JCheckBox setC1Head = new JCheckBox(Bundle.getMessage("PlaceHead")); 2612 private final JCheckBox setC2Head = new JCheckBox(Bundle.getMessage("PlaceHead")); 2613 private final JCheckBox setD1Head = new JCheckBox(Bundle.getMessage("PlaceHead")); 2614 private final JCheckBox setD2Head = new JCheckBox(Bundle.getMessage("PlaceHead")); 2615 2616 private final JCheckBox setupA1Logic = new JCheckBox(Bundle.getMessage("SetLogic")); 2617 private final JCheckBox setupA2Logic = new JCheckBox(Bundle.getMessage("SetLogic")); 2618 private final JCheckBox setupB1Logic = new JCheckBox(Bundle.getMessage("SetLogic")); 2619 private final JCheckBox setupB2Logic = new JCheckBox(Bundle.getMessage("SetLogic")); 2620 private final JCheckBox setupC1Logic = new JCheckBox(Bundle.getMessage("SetLogic")); 2621 private final JCheckBox setupC2Logic = new JCheckBox(Bundle.getMessage("SetLogic")); 2622 private final JCheckBox setupD1Logic = new JCheckBox(Bundle.getMessage("SetLogic")); 2623 private final JCheckBox setupD2Logic = new JCheckBox(Bundle.getMessage("SetLogic")); 2624 2625 private JButton getSavedXoverSignalHeads = null; 2626 private JButton changeXoverSignalIcon = null; 2627 private JButton setXoverSignalsDone = null; 2628 private JButton setXoverSignalsCancel = null; 2629 2630 private SignalHead a1Head = null; 2631 private SignalHead a2Head = null; 2632 private SignalHead b1Head = null; 2633 private SignalHead b2Head = null; 2634 private SignalHead c1Head = null; 2635 private SignalHead c2Head = null; 2636 private SignalHead d1Head = null; 2637 private SignalHead d2Head = null; 2638 2639 private LayoutTurnout.TurnoutType xoverType = LayoutTurnout.TurnoutType.DOUBLE_XOVER; // changes to RH_XOVER or LH_XOVER as required 2640 private LayoutTurnout.TurnoutType xoverCurr = LayoutTurnout.TurnoutType.NONE; // Controls creating the frame 2641 private String xoverTurnoutName = ""; 2642 private final JLabel xoverTurnoutNameLabel = new JLabel(""); 2643 2644 //display dialog for Set Signals at Crossover Turnout tool 2645 public void setSignalsAtXoverTurnoutFromMenu(@Nonnull LayoutTurnout to, 2646 @Nonnull MultiIconEditor theEditor, @Nonnull JFrame theFrame) { 2647 layoutTurnout = to; 2648 turnout = to.getTurnout(); 2649 xoverType = layoutTurnout.getTurnoutType(); 2650 if ((xoverType != LayoutTurnout.TurnoutType.DOUBLE_XOVER) && (xoverType != LayoutTurnout.TurnoutType.RH_XOVER) 2651 && (xoverType != LayoutTurnout.TurnoutType.LH_XOVER)) { 2652 log.error("entered Set Signals at XOver, with a non-crossover turnout"); 2653 return; 2654 } 2655 xoverTurnoutName = layoutTurnout.getTurnoutName(); 2656 setSignalsAtXoverTurnoutFromMenuFlag = true; 2657 setSignalsAtXoverTurnout(theEditor, theFrame); 2658 setSignalsAtXoverTurnoutFromMenuFlag = false; 2659 } 2660 2661 public void setSignalsAtXoverTurnout(@Nonnull MultiIconEditor theEditor, 2662 @Nonnull JFrame theFrame) { 2663 signalIconEditor = theEditor; 2664 signalFrame = theFrame; 2665 2666 if (!setSignalsAtXoverTurnoutFromMenuFlag) { 2667 2668 List<LayoutTurnout> xovers = new ArrayList<>(); 2669 for (LayoutTurnout layoutTurnout : layoutEditor.getLayoutTurnouts()) { 2670 if (layoutTurnout.isTurnoutTypeXover()) { 2671 xovers.add(layoutTurnout); 2672 } 2673 } 2674 JComboBox<LayoutTurnout> jcb = new JComboBox<>( 2675 xovers.toArray(new LayoutTurnout[xovers.size()])); 2676 jcb.setEditable(true); 2677 JmriJOptionPane.showMessageDialog(layoutEditor, jcb, 2678 Bundle.getMessage("MakeLabel", 2679 Bundle.getMessage("EnterXOverTurnout")), 2680 JmriJOptionPane.QUESTION_MESSAGE); 2681 LayoutTurnout layoutTurnout = (LayoutTurnout) jcb.getSelectedItem(); 2682 xoverTurnoutName = layoutTurnout.getTurnoutName(); 2683 2684 if (xoverTurnoutName.length() < 3) { 2685 return; 2686 } 2687 } 2688 2689 if (!getTurnoutInformation(true)) { 2690 return; 2691 } 2692 2693 //Initialize if needed which can be the first time or the crossover type has changed. 2694 if (setSignalsAtXoverTurnoutFrame == null || xoverCurr != xoverType) { 2695 xoverCurr = xoverType; 2696 setSignalsAtXoverTurnoutOpenFlag = false; 2697 setSignalsAtXoverTurnoutFrame = new JmriJFrame(Bundle.getMessage("SignalsAtXoverTurnout"), false, true); 2698 oneFrameToRuleThemAll(setSignalsAtXoverTurnoutFrame); 2699 setSignalsAtXoverTurnoutFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 2700 setSignalsAtXoverTurnoutFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtXoverTurnout", true); 2701 setSignalsAtXoverTurnoutFrame.setLocation(70, 30); 2702 Container theContentPane = setSignalsAtXoverTurnoutFrame.getContentPane(); 2703 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 2704 2705 JPanel panel1 = new JPanel(new FlowLayout()); 2706 panel1.add(xoverTurnoutNameLabel); 2707 theContentPane.add(panel1); 2708 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 2709 2710 JPanel panel2 = new JPanel(new FlowLayout()); 2711 JLabel shTitle = new JLabel(Bundle.getMessage("SignalHeads")); 2712 panel2.add(shTitle); 2713 panel2.add(new JLabel(" ")); 2714 panel2.add(getSavedXoverSignalHeads = new JButton(Bundle.getMessage("GetSaved"))); 2715 getSavedXoverSignalHeads.addActionListener(this::xoverTurnoutSignalsGetSaved); 2716 getSavedXoverSignalHeads.setToolTipText(Bundle.getMessage("GetSavedHint")); 2717 theContentPane.add(panel2); 2718 2719 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 2720 JPanel panel2a = new JPanel(new FlowLayout()); 2721 panel2a.add(new JLabel(" ")); 2722 panel2a.add(setPlaceAllHeads); 2723 setPlaceAllHeads.setToolTipText(Bundle.getMessage("PlaceAllHeadsHint")); 2724 setPlaceAllHeads.addActionListener((ActionEvent e) -> { 2725 boolean isSelected = setPlaceAllHeads.isSelected(); 2726 //(de)select all checkboxes 2727 setA1Head.setSelected(isSelected); 2728 setA2Head.setSelected(isSelected); 2729 setB1Head.setSelected(isSelected); 2730 setB2Head.setSelected(isSelected); 2731 setC1Head.setSelected(isSelected); 2732 setC2Head.setSelected(isSelected); 2733 setD1Head.setSelected(isSelected); 2734 setD2Head.setSelected(isSelected); 2735 }); 2736 panel2a.add(new JLabel(" ")); 2737 panel2a.add(setupAllLogic); 2738 setupAllLogic.setToolTipText(Bundle.getMessage("SetAllLogicHint")); 2739 setupAllLogic.addActionListener((ActionEvent e) -> { 2740 boolean isSelected = setupAllLogic.isSelected(); 2741 //(de)select all checkboxes 2742 setupA1Logic.setSelected(isSelected); 2743 setupA2Logic.setSelected(isSelected); 2744 setupB1Logic.setSelected(isSelected); 2745 setupB2Logic.setSelected(isSelected); 2746 setupC1Logic.setSelected(isSelected); 2747 setupC2Logic.setSelected(isSelected); 2748 setupD1Logic.setSelected(isSelected); 2749 setupD2Logic.setSelected(isSelected); 2750 }); 2751 theContentPane.add(panel2a); 2752 2753 JPanel panel21 = new JPanel(new FlowLayout()); 2754 JLabel a1Label = new JLabel( 2755 Bundle.getMessage("MakeLabel", 2756 Bundle.getMessage("XContinuing", "A"))); 2757 panel21.add(a1Label); 2758 panel21.add(a1SignalHeadComboBox); 2759 theContentPane.add(panel21); 2760 a1SignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 2761 2762 JPanel panel22 = new JPanel(new FlowLayout()); 2763 panel22.add(new JLabel(" ")); 2764 panel22.add(setA1Head); 2765 setA1Head.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 2766 panel22.add(new JLabel(" ")); 2767 panel22.add(setupA1Logic); 2768 setupA1Logic.setToolTipText(Bundle.getMessage("SetLogicHint")); 2769 theContentPane.add(panel22); 2770 if (!(xoverType == LayoutTurnout.TurnoutType.LH_XOVER)) { 2771 JPanel panel23 = new JPanel(new FlowLayout()); 2772 JLabel a2Label = new JLabel(Bundle.getMessage("MakeLabel", 2773 Bundle.getMessage("XDiverging", "A"))); 2774 panel23.add(a2Label); 2775 panel23.add(a2SignalHeadComboBox); 2776 theContentPane.add(panel23); 2777 a2SignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 2778 JPanel panel24 = new JPanel(new FlowLayout()); 2779 panel24.add(new JLabel(" ")); 2780 panel24.add(setA2Head); 2781 setA2Head.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 2782 panel24.add(new JLabel(" ")); 2783 panel24.add(setupA2Logic); 2784 setupA2Logic.setToolTipText(Bundle.getMessage("SetLogicHint")); 2785 theContentPane.add(panel24); 2786 } 2787 2788 JPanel panel31 = new JPanel(new FlowLayout()); 2789 JLabel b1Label = new JLabel(Bundle.getMessage("MakeLabel", 2790 Bundle.getMessage("XContinuing", "B"))); 2791 panel31.add(b1Label); 2792 panel31.add(b1SignalHeadComboBox); 2793 theContentPane.add(panel31); 2794 b1SignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 2795 2796 JPanel panel32 = new JPanel(new FlowLayout()); 2797 panel32.add(new JLabel(" ")); 2798 panel32.add(setB1Head); 2799 setB1Head.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 2800 panel32.add(new JLabel(" ")); 2801 panel32.add(setupB1Logic); 2802 setupB1Logic.setToolTipText(Bundle.getMessage("SetLogicHint")); 2803 theContentPane.add(panel32); 2804 if (!(xoverType == LayoutTurnout.TurnoutType.RH_XOVER)) { 2805 JPanel panel33 = new JPanel(new FlowLayout()); 2806 JLabel b2Label = new JLabel(Bundle.getMessage("MakeLabel", 2807 Bundle.getMessage("XDiverging", "B"))); 2808 panel33.add(b2Label); 2809 panel33.add(b2SignalHeadComboBox); 2810 theContentPane.add(panel33); 2811 b2SignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 2812 JPanel panel34 = new JPanel(new FlowLayout()); 2813 panel34.add(new JLabel(" ")); 2814 panel34.add(setB2Head); 2815 setB2Head.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 2816 panel34.add(new JLabel(" ")); 2817 panel34.add(setupB2Logic); 2818 setupB2Logic.setToolTipText(Bundle.getMessage("SetLogicHint")); 2819 theContentPane.add(panel34); 2820 } 2821 2822 JPanel panel41 = new JPanel(new FlowLayout()); 2823 JLabel c1Label = new JLabel(Bundle.getMessage("MakeLabel", 2824 Bundle.getMessage("XContinuing", "C"))); 2825 panel41.add(c1Label); 2826 panel41.add(c1SignalHeadComboBox); 2827 theContentPane.add(panel41); 2828 c1SignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 2829 2830 JPanel panel42 = new JPanel(new FlowLayout()); 2831 panel42.add(new JLabel(" ")); 2832 panel42.add(setC1Head); 2833 setC1Head.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 2834 panel42.add(new JLabel(" ")); 2835 panel42.add(setupC1Logic); 2836 setupC1Logic.setToolTipText(Bundle.getMessage("SetLogicHint")); 2837 theContentPane.add(panel42); 2838 if (!(xoverType == LayoutTurnout.TurnoutType.LH_XOVER)) { 2839 JPanel panel43 = new JPanel(new FlowLayout()); 2840 JLabel c2Label = new JLabel(Bundle.getMessage("MakeLabel", 2841 Bundle.getMessage("XDiverging", "C"))); 2842 panel43.add(c2Label); 2843 panel43.add(c2SignalHeadComboBox); 2844 theContentPane.add(panel43); 2845 c2SignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 2846 JPanel panel44 = new JPanel(new FlowLayout()); 2847 panel44.add(new JLabel(" ")); 2848 panel44.add(setC2Head); 2849 setC2Head.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 2850 panel44.add(new JLabel(" ")); 2851 panel44.add(setupC2Logic); 2852 setupC2Logic.setToolTipText(Bundle.getMessage("SetLogicHint")); 2853 theContentPane.add(panel44); 2854 } 2855 2856 JPanel panel51 = new JPanel(new FlowLayout()); 2857 JLabel d1Label = new JLabel(Bundle.getMessage("MakeLabel", 2858 Bundle.getMessage("XContinuing", "D"))); 2859 panel51.add(d1Label); 2860 panel51.add(d1SignalHeadComboBox); 2861 theContentPane.add(panel51); 2862 d1SignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 2863 2864 JPanel panel52 = new JPanel(new FlowLayout()); 2865 panel52.add(new JLabel(" ")); 2866 panel52.add(setD1Head); 2867 setD1Head.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 2868 panel52.add(new JLabel(" ")); 2869 panel52.add(setupD1Logic); 2870 setupD1Logic.setToolTipText(Bundle.getMessage("SetLogicHint")); 2871 theContentPane.add(panel52); 2872 if (xoverType != LayoutTurnout.TurnoutType.RH_XOVER) { 2873 JPanel panel53 = new JPanel(new FlowLayout()); 2874 JLabel d2Label = new JLabel(Bundle.getMessage("MakeLabel", 2875 Bundle.getMessage("XDiverging", "D"))); 2876 panel53.add(d2Label); 2877 panel53.add(d2SignalHeadComboBox); 2878 theContentPane.add(panel53); 2879 d2SignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 2880 JPanel panel54 = new JPanel(new FlowLayout()); 2881 panel54.add(new JLabel(" ")); 2882 panel54.add(setD2Head); 2883 setD2Head.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 2884 panel54.add(new JLabel(" ")); 2885 panel54.add(setupD2Logic); 2886 setupD2Logic.setToolTipText(Bundle.getMessage("SetLogicHint")); 2887 theContentPane.add(panel54); 2888 } 2889 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 2890 2891 JPanel panel6 = new JPanel(new FlowLayout()); 2892 panel6.add(changeXoverSignalIcon = new JButton(Bundle.getMessage("ChangeSignalIcon"))); 2893 changeXoverSignalIcon.addActionListener((ActionEvent e) -> signalFrame.setVisible(true)); 2894 changeXoverSignalIcon.setToolTipText(Bundle.getMessage("ChangeSignalIconHint")); 2895 panel6.add(new JLabel(" ")); 2896 panel6.add(setXoverSignalsDone = new JButton(Bundle.getMessage("ButtonDone"))); 2897 setXoverSignalsDone.addActionListener(this::setXoverSignalsDonePressed); 2898 setXoverSignalsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 2899 2900 panel6.add(setXoverSignalsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 2901 setXoverSignalsCancel.addActionListener(this::setXoverSignalsCancelPressed); 2902 setXoverSignalsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 2903 theContentPane.add(panel6); 2904 2905 //make this button the default button (return or enter activates) 2906 JRootPane rootPane = SwingUtilities.getRootPane(setXoverSignalsDone); 2907 if (rootPane != null) { 2908 rootPane.setDefaultButton(setXoverSignalsDone); 2909 } 2910 2911 setSignalsAtXoverTurnoutFrame.addWindowListener(new WindowAdapter() { 2912 @Override 2913 public void windowClosing(WindowEvent e) { 2914 setXoverSignalsCancelPressed(null); 2915 } 2916 }); 2917 } 2918 setPlaceAllHeads.setSelected(false); 2919 setupAllLogic.setSelected(false); 2920 2921 xoverTurnoutNameLabel.setText(Bundle.getMessage("MakeLabel", 2922 Bundle.getMessage("BeanNameTurnout") 2923 + " " + Bundle.getMessage("Name")) + xoverTurnoutName); 2924 xoverType = layoutTurnout.getTurnoutType(); 2925 2926 xoverTurnoutSignalsGetSaved(null); 2927 2928 if (!setSignalsAtXoverTurnoutOpenFlag) { 2929 setSignalsAtXoverTurnoutFrame.setPreferredSize(null); 2930 setSignalsAtXoverTurnoutFrame.pack(); 2931 setSignalsAtXoverTurnoutOpenFlag = true; 2932 } 2933 setSignalsAtXoverTurnoutFrame.setVisible(true); 2934 } //setSignalsAtXoverTurnout 2935 2936 private void xoverTurnoutSignalsGetSaved(ActionEvent a) { 2937 a1SignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalA1()); 2938 a2SignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalA2()); 2939 b1SignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalB1()); 2940 b2SignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalB2()); 2941 c1SignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalC1()); 2942 c2SignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalC2()); 2943 d1SignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalD1()); 2944 d2SignalHeadComboBox.setSelectedItem(layoutTurnout.getSignalD2()); 2945 } 2946 2947 private void setXoverSignalsCancelPressed(ActionEvent a) { 2948 setSignalsAtXoverTurnoutOpenFlag = false; 2949 setSignalsAtXoverTurnoutFrame.setVisible(false); 2950 } 2951 2952 private void setXoverSignalsDonePressed(ActionEvent a) { 2953 if (!getXoverSignalHeadInformation()) { 2954 return; 2955 } 2956 //place signal icons if requested, and assign signal heads to this turnout 2957 String signalHeadName = a1SignalHeadComboBox.getSelectedItemDisplayName(); 2958 if (signalHeadName == null) { 2959 signalHeadName = ""; 2960 } 2961 if (setA1Head.isSelected()) { 2962 if (isHeadOnPanel(a1Head) 2963 && (a1Head != getHeadFromName(layoutTurnout.getSignalA1Name()))) { 2964 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 2965 Bundle.getMessage("SignalsError6", 2966 new Object[]{signalHeadName}), 2967 Bundle.getMessage("ErrorTitle"), 2968 JmriJOptionPane.ERROR_MESSAGE); 2969 return; 2970 } else { 2971 removeSignalHeadFromPanel(layoutTurnout.getSignalA1Name()); 2972 placeA1(); 2973 removeAssignment(a1Head); 2974 layoutTurnout.setSignalA1Name(signalHeadName); 2975 needRedraw = true; 2976 } 2977 } else { 2978 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a1Head, layoutTurnout); 2979 if (assigned == LayoutTurnout.Geometry.NONE) { 2980 if (isHeadOnPanel(a1Head) 2981 && isHeadAssignedAnywhere(a1Head)) { 2982 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 2983 Bundle.getMessage("SignalsError8", 2984 new Object[]{signalHeadName}), 2985 Bundle.getMessage("ErrorTitle"), 2986 JmriJOptionPane.ERROR_MESSAGE); 2987 return; 2988 } else { 2989 removeSignalHeadFromPanel(layoutTurnout.getSignalA1Name()); 2990 removeAssignment(a1Head); 2991 layoutTurnout.setSignalA1Name(signalHeadName); 2992 } 2993 //} else if (assigned != A1) { 2994 //need to figure out what to do in this case. 2995 } 2996 } 2997 signalHeadName = a2SignalHeadComboBox.getSelectedItemDisplayName(); 2998 if (signalHeadName == null) { 2999 signalHeadName = ""; 3000 } 3001 if ((a2Head != null) && setA2Head.isSelected()) { 3002 if (isHeadOnPanel(a2Head) 3003 && (a2Head != getHeadFromName(layoutTurnout.getSignalA2Name()))) { 3004 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3005 Bundle.getMessage("SignalsError6", 3006 new Object[]{signalHeadName}), 3007 Bundle.getMessage("ErrorTitle"), 3008 JmriJOptionPane.ERROR_MESSAGE); 3009 return; 3010 } else { 3011 removeSignalHeadFromPanel(layoutTurnout.getSignalA2Name()); 3012 placeA2(); 3013 removeAssignment(a2Head); 3014 layoutTurnout.setSignalA2Name(signalHeadName); 3015 needRedraw = true; 3016 } 3017 } else if (a2Head != null) { 3018 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a2Head, layoutTurnout); 3019 if (assigned == LayoutTurnout.Geometry.NONE) { 3020 if (isHeadOnPanel(a2Head) 3021 && isHeadAssignedAnywhere(a2Head)) { 3022 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3023 Bundle.getMessage("SignalsError8", 3024 new Object[]{signalHeadName}), 3025 Bundle.getMessage("ErrorTitle"), 3026 JmriJOptionPane.ERROR_MESSAGE); 3027 return; 3028 } else { 3029 removeSignalHeadFromPanel(layoutTurnout.getSignalA2Name()); 3030 removeAssignment(a2Head); 3031 layoutTurnout.setSignalA2Name(signalHeadName); 3032 } 3033 //} else if (assigned != A2) { 3034 //need to figure out what to do in this case. 3035 } 3036 } else { //a2Head known to be null here 3037 removeSignalHeadFromPanel(layoutTurnout.getSignalA2Name()); 3038 layoutTurnout.setSignalA2Name(""); 3039 } 3040 signalHeadName = b1SignalHeadComboBox.getSelectedItemDisplayName(); 3041 if (signalHeadName == null) { 3042 signalHeadName = ""; 3043 } 3044 if (setB1Head.isSelected()) { 3045 if (isHeadOnPanel(b1Head) 3046 && (b1Head != getHeadFromName(layoutTurnout.getSignalB1Name()))) { 3047 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3048 Bundle.getMessage("SignalsError6", 3049 new Object[]{signalHeadName}), 3050 Bundle.getMessage("ErrorTitle"), 3051 JmriJOptionPane.ERROR_MESSAGE); 3052 return; 3053 } else { 3054 removeSignalHeadFromPanel(layoutTurnout.getSignalB1Name()); 3055 placeB1(); 3056 removeAssignment(b1Head); 3057 layoutTurnout.setSignalB1Name(signalHeadName); 3058 needRedraw = true; 3059 } 3060 } else { 3061 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b1Head, layoutTurnout); 3062 if (assigned == LayoutTurnout.Geometry.NONE) { 3063 if (isHeadOnPanel(b1Head) 3064 && isHeadAssignedAnywhere(b1Head)) { 3065 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3066 Bundle.getMessage("SignalsError8", 3067 new Object[]{signalHeadName}), 3068 Bundle.getMessage("ErrorTitle"), 3069 JmriJOptionPane.ERROR_MESSAGE); 3070 return; 3071 } else { 3072 removeSignalHeadFromPanel(layoutTurnout.getSignalB1Name()); 3073 removeAssignment(b1Head); 3074 layoutTurnout.setSignalB1Name(signalHeadName); 3075 } 3076 //} else if (assigned != B1) { 3077 //need to figure out what to do in this case. 3078 } 3079 } 3080 signalHeadName = b2SignalHeadComboBox.getSelectedItemDisplayName(); 3081 if (signalHeadName == null) { 3082 signalHeadName = ""; 3083 } 3084 if ((b2Head != null) && setB2Head.isSelected()) { 3085 if (isHeadOnPanel(b2Head) 3086 && (b2Head != getHeadFromName(layoutTurnout.getSignalB2Name()))) { 3087 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3088 Bundle.getMessage("SignalsError6", 3089 new Object[]{signalHeadName}), 3090 Bundle.getMessage("ErrorTitle"), 3091 JmriJOptionPane.ERROR_MESSAGE); 3092 return; 3093 } else { 3094 removeSignalHeadFromPanel(layoutTurnout.getSignalB2Name()); 3095 placeB2(); 3096 removeAssignment(b2Head); 3097 layoutTurnout.setSignalB2Name(signalHeadName); 3098 needRedraw = true; 3099 } 3100 } else if (b2Head != null) { 3101 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b2Head, layoutTurnout); 3102 if (assigned == LayoutTurnout.Geometry.NONE) { 3103 if (isHeadOnPanel(b2Head) 3104 && isHeadAssignedAnywhere(b2Head)) { 3105 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3106 Bundle.getMessage("SignalsError8", 3107 new Object[]{signalHeadName}), 3108 Bundle.getMessage("ErrorTitle"), 3109 JmriJOptionPane.ERROR_MESSAGE); 3110 return; 3111 } else { 3112 removeSignalHeadFromPanel(layoutTurnout.getSignalB2Name()); 3113 removeAssignment(b2Head); 3114 layoutTurnout.setSignalB2Name(signalHeadName); 3115 } 3116 //} else if (assigned != B2) { 3117 //need to figure out what to do in this case. 3118 } 3119 } else { //b2Head known to be null here 3120 removeSignalHeadFromPanel(layoutTurnout.getSignalB2Name()); 3121 layoutTurnout.setSignalB2Name(""); 3122 } 3123 signalHeadName = c1SignalHeadComboBox.getSelectedItemDisplayName(); 3124 if (signalHeadName == null) { 3125 signalHeadName = ""; 3126 } 3127 if (setC1Head.isSelected()) { 3128 if (isHeadOnPanel(c1Head) 3129 && (c1Head != getHeadFromName(layoutTurnout.getSignalC1Name()))) { 3130 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3131 Bundle.getMessage("SignalsError6", 3132 new Object[]{signalHeadName}), 3133 Bundle.getMessage("ErrorTitle"), 3134 JmriJOptionPane.ERROR_MESSAGE); 3135 return; 3136 } else { 3137 removeSignalHeadFromPanel(layoutTurnout.getSignalC1Name()); 3138 placeC1(); 3139 removeAssignment(c1Head); 3140 layoutTurnout.setSignalC1Name(signalHeadName); 3141 needRedraw = true; 3142 } 3143 } else { 3144 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c1Head, layoutTurnout); 3145 if (assigned == LayoutTurnout.Geometry.NONE) { 3146 if (isHeadOnPanel(c1Head) 3147 && isHeadAssignedAnywhere(c1Head)) { 3148 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3149 Bundle.getMessage("SignalsError8", 3150 new Object[]{signalHeadName}), 3151 Bundle.getMessage("ErrorTitle"), 3152 JmriJOptionPane.ERROR_MESSAGE); 3153 return; 3154 } else { 3155 removeSignalHeadFromPanel(layoutTurnout.getSignalC1Name()); 3156 removeAssignment(c1Head); 3157 layoutTurnout.setSignalC1Name(signalHeadName); 3158 } 3159 //} else if (assigned != C1) { 3160 //need to figure out what to do in this case. 3161 } 3162 } 3163 signalHeadName = c2SignalHeadComboBox.getSelectedItemDisplayName(); 3164 if (signalHeadName == null) { 3165 signalHeadName = ""; 3166 } 3167 if ((c2Head != null) && setC2Head.isSelected()) { 3168 if (isHeadOnPanel(c2Head) 3169 && (c2Head != getHeadFromName(layoutTurnout.getSignalC2Name()))) { 3170 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3171 Bundle.getMessage("SignalsError6", 3172 new Object[]{signalHeadName}), 3173 Bundle.getMessage("ErrorTitle"), 3174 JmriJOptionPane.ERROR_MESSAGE); 3175 return; 3176 } else { 3177 removeSignalHeadFromPanel(layoutTurnout.getSignalC2Name()); 3178 placeC2(); 3179 removeAssignment(c2Head); 3180 layoutTurnout.setSignalC2Name(signalHeadName); 3181 needRedraw = true; 3182 } 3183 } else if (c2Head != null) { 3184 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c2Head, layoutTurnout); 3185 if (assigned == LayoutTurnout.Geometry.NONE) { 3186 if (isHeadOnPanel(c2Head) 3187 && isHeadAssignedAnywhere(c2Head)) { 3188 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3189 Bundle.getMessage("SignalsError8", 3190 new Object[]{signalHeadName}), 3191 Bundle.getMessage("ErrorTitle"), 3192 JmriJOptionPane.ERROR_MESSAGE); 3193 return; 3194 } else { 3195 removeSignalHeadFromPanel(layoutTurnout.getSignalC2Name()); 3196 removeAssignment(c2Head); 3197 layoutTurnout.setSignalC2Name(signalHeadName); 3198 } 3199 //} else if (assigned != C2) { 3200 //need to figure out what to do in this case. 3201 } 3202 } else { //c2Head known to be null here 3203 removeSignalHeadFromPanel(layoutTurnout.getSignalC2Name()); 3204 layoutTurnout.setSignalC2Name(""); 3205 } 3206 signalHeadName = d1SignalHeadComboBox.getSelectedItemDisplayName(); 3207 if (signalHeadName == null) { 3208 signalHeadName = ""; 3209 } 3210 if (setD1Head.isSelected()) { 3211 if (isHeadOnPanel(d1Head) 3212 && (d1Head != getHeadFromName(layoutTurnout.getSignalD1Name()))) { 3213 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3214 Bundle.getMessage("SignalsError6", 3215 new Object[]{signalHeadName}), 3216 Bundle.getMessage("ErrorTitle"), 3217 JmriJOptionPane.ERROR_MESSAGE); 3218 return; 3219 } else { 3220 removeSignalHeadFromPanel(layoutTurnout.getSignalD1Name()); 3221 placeD1(); 3222 removeAssignment(d1Head); 3223 layoutTurnout.setSignalD1Name(signalHeadName); 3224 needRedraw = true; 3225 } 3226 } else { 3227 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d1Head, layoutTurnout); 3228 if (assigned == LayoutTurnout.Geometry.NONE) { 3229 if (isHeadOnPanel(d1Head) 3230 && isHeadAssignedAnywhere(d1Head)) { 3231 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3232 Bundle.getMessage("SignalsError8", 3233 new Object[]{signalHeadName}), 3234 Bundle.getMessage("ErrorTitle"), 3235 JmriJOptionPane.ERROR_MESSAGE); 3236 return; 3237 } else { 3238 removeSignalHeadFromPanel(layoutTurnout.getSignalD1Name()); 3239 removeAssignment(d1Head); 3240 layoutTurnout.setSignalD1Name(signalHeadName); 3241 } 3242 //} else if (assigned != D1) { 3243 //need to figure out what to do in this case. 3244 } 3245 } 3246 signalHeadName = d2SignalHeadComboBox.getSelectedItemDisplayName(); 3247 if (signalHeadName == null) { 3248 signalHeadName = ""; 3249 } 3250 if ((d2Head != null) && setD2Head.isSelected()) { 3251 if (isHeadOnPanel(d2Head) 3252 && (d2Head != getHeadFromName(layoutTurnout.getSignalD2Name()))) { 3253 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3254 Bundle.getMessage("SignalsError6", 3255 new Object[]{signalHeadName}), 3256 Bundle.getMessage("ErrorTitle"), 3257 JmriJOptionPane.ERROR_MESSAGE); 3258 return; 3259 } else { 3260 removeSignalHeadFromPanel(layoutTurnout.getSignalD2Name()); 3261 placeD2(); 3262 removeAssignment(d2Head); 3263 layoutTurnout.setSignalD2Name(signalHeadName); 3264 needRedraw = true; 3265 } 3266 } else if (d2Head != null) { 3267 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d2Head, layoutTurnout); 3268 if (assigned == LayoutTurnout.Geometry.NONE) { 3269 if (isHeadOnPanel(d2Head) 3270 && isHeadAssignedAnywhere(d2Head)) { 3271 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3272 Bundle.getMessage("SignalsError8", 3273 new Object[]{signalHeadName}), 3274 Bundle.getMessage("ErrorTitle"), 3275 JmriJOptionPane.ERROR_MESSAGE); 3276 return; 3277 } else { 3278 removeSignalHeadFromPanel(layoutTurnout.getSignalD2Name()); 3279 removeAssignment(d2Head); 3280 layoutTurnout.setSignalD2Name(signalHeadName); 3281 } 3282 //} else if (assigned != D2) { 3283 //need to figure out what to do in this case. 3284 } 3285 } else { //d2Head known to be null here 3286 removeSignalHeadFromPanel(layoutTurnout.getSignalD2Name()); 3287 layoutTurnout.setSignalD2Name(""); 3288 } 3289 //setup logic if requested 3290 if (setupA1Logic.isSelected() || setupA2Logic.isSelected()) { 3291 if (xoverType == LayoutTurnout.TurnoutType.LH_XOVER) { 3292 setLogicXoverContinuing(a1Head, (TrackSegment) layoutTurnout.getConnectB()); 3293 } else { 3294 setLogicXover(a1Head, (TrackSegment) layoutTurnout.getConnectB(), a2Head, 3295 (TrackSegment) layoutTurnout.getConnectC(), setupA1Logic.isSelected(), 3296 setupA2Logic.isSelected()); 3297 } 3298 } 3299 if (setupB1Logic.isSelected() || setupB2Logic.isSelected()) { 3300 if (xoverType == LayoutTurnout.TurnoutType.RH_XOVER) { 3301 setLogicXoverContinuing(b1Head, (TrackSegment) layoutTurnout.getConnectA()); 3302 } else { 3303 setLogicXover(b1Head, (TrackSegment) layoutTurnout.getConnectA(), b2Head, 3304 (TrackSegment) layoutTurnout.getConnectD(), setupB1Logic.isSelected(), 3305 setupB2Logic.isSelected()); 3306 } 3307 } 3308 if (setupC1Logic.isSelected() || setupC2Logic.isSelected()) { 3309 if (xoverType == LayoutTurnout.TurnoutType.LH_XOVER) { 3310 setLogicXoverContinuing(c1Head, (TrackSegment) layoutTurnout.getConnectD()); 3311 } else { 3312 setLogicXover(c1Head, (TrackSegment) layoutTurnout.getConnectD(), c2Head, 3313 (TrackSegment) layoutTurnout.getConnectA(), setupC1Logic.isSelected(), 3314 setupC2Logic.isSelected()); 3315 } 3316 } 3317 if (setupD1Logic.isSelected() || setupD2Logic.isSelected()) { 3318 if (xoverType == LayoutTurnout.TurnoutType.RH_XOVER) { 3319 setLogicXoverContinuing(d1Head, (TrackSegment) layoutTurnout.getConnectC()); 3320 } else { 3321 setLogicXover(d1Head, (TrackSegment) layoutTurnout.getConnectC(), d2Head, 3322 (TrackSegment) layoutTurnout.getConnectB(), setupD1Logic.isSelected(), 3323 setupD2Logic.isSelected()); 3324 } 3325 } 3326 //make sure this layout turnout is not linked to another 3327 layoutTurnout.setLinkType(LayoutTurnout.LinkType.NO_LINK); 3328 layoutTurnout.setLinkedTurnoutName(""); 3329 //finish up 3330 setSignalsAtXoverTurnoutOpenFlag = false; 3331 setSignalsAtXoverTurnoutFrame.setVisible(false); 3332 if (needRedraw) { 3333 layoutEditor.redrawPanel(); 3334 needRedraw = false; 3335 layoutEditor.setDirty(); 3336 } 3337 } //setXoverSignalsDonePressed 3338 3339 private boolean getXoverSignalHeadInformation() { 3340 a1Head = getSignalHeadFromEntry(a1SignalHeadComboBox, true, setSignalsAtXoverTurnoutFrame); 3341 if (a1Head == null) { 3342 return false; 3343 } 3344 if (!(xoverType == LayoutTurnout.TurnoutType.LH_XOVER)) { 3345 a2Head = getSignalHeadFromEntry(a2SignalHeadComboBox, false, setSignalsAtXoverTurnoutFrame); 3346 } else { 3347 a2Head = null; 3348 } 3349 b1Head = getSignalHeadFromEntry(b1SignalHeadComboBox, true, setSignalsAtXoverTurnoutFrame); 3350 if (b1Head == null) { 3351 return false; 3352 } 3353 if (!(xoverType == LayoutTurnout.TurnoutType.RH_XOVER)) { 3354 b2Head = getSignalHeadFromEntry(b2SignalHeadComboBox, false, setSignalsAtXoverTurnoutFrame); 3355 } else { 3356 b2Head = null; 3357 } 3358 c1Head = getSignalHeadFromEntry(c1SignalHeadComboBox, true, setSignalsAtXoverTurnoutFrame); 3359 if (c1Head == null) { 3360 return false; 3361 } 3362 if (!(xoverType == LayoutTurnout.TurnoutType.LH_XOVER)) { 3363 c2Head = getSignalHeadFromEntry(c2SignalHeadComboBox, false, setSignalsAtXoverTurnoutFrame); 3364 } else { 3365 c2Head = null; 3366 } 3367 d1Head = getSignalHeadFromEntry(d1SignalHeadComboBox, true, setSignalsAtXoverTurnoutFrame); 3368 if (d1Head == null) { 3369 return false; 3370 } 3371 if (!(xoverType == LayoutTurnout.TurnoutType.RH_XOVER)) { 3372 d2Head = getSignalHeadFromEntry(d2SignalHeadComboBox, false, setSignalsAtXoverTurnoutFrame); 3373 } else { 3374 d2Head = null; 3375 } 3376 return true; 3377 } 3378 3379 private void placeA1() { 3380 if (testIcon == null) { 3381 testIcon = signalIconEditor.getIcon(0); 3382 } 3383 String signalHeadName = a1SignalHeadComboBox.getSelectedItemDisplayName(); 3384 if (signalHeadName == null) { 3385 signalHeadName = ""; 3386 } 3387 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 3388 3389 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 3390 3391 Point2D coordsA = layoutTurnoutView.getCoordsA(); 3392 Point2D delta = new Point2D.Double(0.0, +shift); 3393 3394 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 3395 Point2D where = MathUtil.add(coordsA, delta); 3396 setSignalHeadOnPanel(placeSignalDirectionDEG + 180.0, signalHeadName, where); 3397 } 3398 3399 private void placeA2() { 3400 if (testIcon == null) { 3401 testIcon = signalIconEditor.getIcon(0); 3402 } 3403 String signalHeadName = a2SignalHeadComboBox.getSelectedItemDisplayName(); 3404 if (signalHeadName == null) { 3405 signalHeadName = ""; 3406 } 3407 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 3408 3409 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 3410 3411 Point2D coordsA = layoutTurnoutView.getCoordsA(); 3412 Point2D delta = new Point2D.Double(-2.0 * shift, +shift); 3413 3414 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 3415 Point2D where = MathUtil.add(coordsA, delta); 3416 setSignalHeadOnPanel(placeSignalDirectionDEG + 180.0, signalHeadName, where); 3417 } 3418 3419 private void placeB1() { 3420 if (testIcon == null) { 3421 testIcon = signalIconEditor.getIcon(0); 3422 } 3423 String signalHeadName = b1SignalHeadComboBox.getSelectedItemDisplayName(); 3424 if (signalHeadName == null) { 3425 signalHeadName = ""; 3426 } 3427 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 3428 3429 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 3430 3431 Point2D coordsB = layoutTurnoutView.getCoordsB(); 3432 Point2D delta = new Point2D.Double(-shift, -shift); 3433 3434 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 3435 Point2D where = MathUtil.add(coordsB, delta); 3436 setSignalHeadOnPanel(placeSignalDirectionDEG, signalHeadName, where); 3437 } 3438 3439 private void placeB2() { 3440 if (testIcon == null) { 3441 testIcon = signalIconEditor.getIcon(0); 3442 } 3443 String signalHeadName = b2SignalHeadComboBox.getSelectedItemDisplayName(); 3444 if (signalHeadName == null) { 3445 signalHeadName = ""; 3446 } 3447 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 3448 3449 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 3450 3451 Point2D coordsB = layoutTurnoutView.getCoordsB(); 3452 Point2D delta = new Point2D.Double(+shift, -shift); 3453 3454 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 3455 Point2D where = MathUtil.add(coordsB, delta); 3456 setSignalHeadOnPanel(placeSignalDirectionDEG, signalHeadName, where); 3457 } 3458 3459 private void placeC1() { 3460 if (testIcon == null) { 3461 testIcon = signalIconEditor.getIcon(0); 3462 } 3463 String signalHeadName = c1SignalHeadComboBox.getSelectedItemDisplayName(); 3464 if (signalHeadName == null) { 3465 signalHeadName = ""; 3466 } 3467 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 3468 3469 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 3470 3471 Point2D coordsC = layoutTurnoutView.getCoordsC(); 3472 Point2D delta = new Point2D.Double(0.0, -shift); 3473 3474 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 3475 Point2D where = MathUtil.add(coordsC, delta); 3476 setSignalHeadOnPanel(placeSignalDirectionDEG, signalHeadName, where); 3477 } 3478 3479 private void placeC2() { 3480 if (testIcon == null) { 3481 testIcon = signalIconEditor.getIcon(0); 3482 } 3483 String signalHeadName = c2SignalHeadComboBox.getSelectedItemDisplayName(); 3484 if (signalHeadName == null) { 3485 signalHeadName = ""; 3486 } 3487 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 3488 3489 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 3490 3491 Point2D coordsC = layoutTurnoutView.getCoordsC(); 3492 Point2D delta = new Point2D.Double(+2.0 * shift, -shift); 3493 3494 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 3495 Point2D where = MathUtil.add(coordsC, delta); 3496 setSignalHeadOnPanel(placeSignalDirectionDEG, signalHeadName, where); 3497 } 3498 3499 private void placeD1() { 3500 if (testIcon == null) { 3501 testIcon = signalIconEditor.getIcon(0); 3502 } 3503 String signalHeadName = d1SignalHeadComboBox.getSelectedItemDisplayName(); 3504 if (signalHeadName == null) { 3505 signalHeadName = ""; 3506 } 3507 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 3508 3509 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 3510 3511 Point2D coordsD = layoutTurnoutView.getCoordsD(); 3512 Point2D delta = new Point2D.Double(+shift, +shift); 3513 3514 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 3515 Point2D where = MathUtil.add(coordsD, delta); 3516 setSignalHeadOnPanel(placeSignalDirectionDEG + 180.0, signalHeadName, where); 3517 } 3518 3519 private void placeD2() { 3520 if (testIcon == null) { 3521 testIcon = signalIconEditor.getIcon(0); 3522 } 3523 String signalHeadName = d2SignalHeadComboBox.getSelectedItemDisplayName(); 3524 if (signalHeadName == null) { 3525 signalHeadName = ""; 3526 } 3527 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 3528 3529 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 3530 3531 Point2D coordsD = layoutTurnoutView.getCoordsD(); 3532 Point2D delta = new Point2D.Double(-shift, +shift); 3533 3534 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 3535 Point2D where = MathUtil.add(coordsD, delta); 3536 setSignalHeadOnPanel(placeSignalDirectionDEG + 180.0, signalHeadName, where); 3537 } 3538 3539 @SuppressWarnings("null") 3540 private void setLogicXover(SignalHead head, TrackSegment track, SignalHead secondHead, TrackSegment track2, 3541 boolean setup1, boolean setup2) { 3542 if ((track == null) && setup1) { 3543 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3544 Bundle.getMessage("InfoMessage7"), 3545 Bundle.getMessage("MessageTitle"), 3546 JmriJOptionPane.INFORMATION_MESSAGE); 3547 return; 3548 } 3549 Sensor occupancy = null; 3550 SignalHead nextHead = null; 3551 if ((track != null) && setup1) { 3552 LayoutBlock block = track.getLayoutBlock(); 3553 if (block == null) { 3554 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3555 Bundle.getMessage("InfoMessage6"), 3556 Bundle.getMessage("MessageTitle"), 3557 JmriJOptionPane.INFORMATION_MESSAGE); 3558 return; 3559 } 3560 occupancy = block.getOccupancySensor(); 3561 if (occupancy == null) { 3562 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3563 Bundle.getMessage("InfoMessage4", 3564 new Object[]{block.getUserName()}), 3565 Bundle.getMessage("MessageTitle"), 3566 JmriJOptionPane.INFORMATION_MESSAGE); 3567 return; 3568 } 3569 nextHead = getNextSignalFromObject(track, 3570 layoutTurnout, head.getSystemName(), setSignalsAtXoverTurnoutFrame); 3571 if ((nextHead == null) && (!reachedEndBumper())) { 3572 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3573 Bundle.getMessage("InfoMessage5", 3574 new Object[]{block.getUserName()}), 3575 Bundle.getMessage("MessageTitle"), 3576 JmriJOptionPane.INFORMATION_MESSAGE); 3577 return; 3578 } 3579 if (secondHead != null) { 3580 if (!initializeBlockBossLogic(head.getDisplayName())) { 3581 return; 3582 } 3583 logic.setMode(BlockBossLogic.TRAILINGMAIN); 3584 logic.setTurnout(turnout.getDisplayName()); 3585 logic.setSensor1(occupancy.getDisplayName()); 3586 if (nextHead != null) { 3587 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 3588 } 3589 if (auxSignal != null) { 3590 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 3591 } 3592 finalizeBlockBossLogic(); 3593 } 3594 } 3595 if ((secondHead != null) && !setup2) { 3596 return; 3597 } 3598 SignalHead savedAuxSignal = auxSignal; 3599 if (track2 == null) { 3600 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3601 Bundle.getMessage("InfoMessage7"), 3602 Bundle.getMessage("MessageTitle"), 3603 JmriJOptionPane.INFORMATION_MESSAGE); 3604 return; 3605 } 3606 LayoutBlock block2 = track2.getLayoutBlock(); 3607 if (block2 == null) { 3608 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3609 Bundle.getMessage("InfoMessage6"), 3610 Bundle.getMessage("MessageTitle"), 3611 JmriJOptionPane.INFORMATION_MESSAGE); 3612 return; 3613 } 3614 Sensor occupancy2 = block2.getOccupancySensor(); 3615 if (occupancy2 == null) { 3616 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3617 Bundle.getMessage("InfoMessage4", 3618 new Object[]{block2.getUserName()}), 3619 Bundle.getMessage("MessageTitle"), 3620 JmriJOptionPane.INFORMATION_MESSAGE); 3621 return; 3622 } 3623 String signalHeadName = head.getSystemName(); 3624 if (secondHead != null) { 3625 signalHeadName = secondHead.getSystemName(); 3626 } 3627 SignalHead nextHead2 = getNextSignalFromObject(track2, 3628 layoutTurnout, signalHeadName, setSignalsAtXoverTurnoutFrame); 3629 if ((nextHead2 == null) && (!reachedEndBumper())) { 3630 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3631 Bundle.getMessage("InfoMessage5", 3632 new Object[]{block2.getUserName()}), 3633 Bundle.getMessage("MessageTitle"), 3634 JmriJOptionPane.INFORMATION_MESSAGE); 3635 return; 3636 } 3637 if ((secondHead == null) && (track != null) && setup1) { 3638 if (!initializeBlockBossLogic(head.getDisplayName())) { 3639 return; 3640 } 3641 logic.setMode(BlockBossLogic.FACING); 3642 logic.setTurnout(turnout.getDisplayName()); 3643 logic.setWatchedSensor1(occupancy.getDisplayName()); 3644 logic.setWatchedSensor2(occupancy2.getDisplayName()); 3645 if (nextHead != null) { 3646 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 3647 } 3648 if (savedAuxSignal != null) { 3649 logic.setWatchedSignal1Alt(savedAuxSignal.getDisplayName()); 3650 } 3651 if (nextHead2 != null) { 3652 logic.setWatchedSignal2(nextHead2.getDisplayName()); 3653 } 3654 if (auxSignal != null) { 3655 logic.setWatchedSignal2Alt(auxSignal.getDisplayName()); 3656 } 3657 logic.setLimitSpeed2(true); 3658 finalizeBlockBossLogic(); 3659 } else if ((secondHead != null) && setup2) { 3660 if (!initializeBlockBossLogic(secondHead.getDisplayName())) { 3661 return; 3662 } 3663 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 3664 logic.setTurnout(turnout.getDisplayName()); 3665 logic.setSensor1(occupancy2.getDisplayName()); 3666 if (nextHead2 != null) { 3667 logic.setWatchedSignal1(nextHead2.getDisplayName(), false); 3668 } 3669 if (auxSignal != null) { 3670 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 3671 } 3672 logic.setLimitSpeed2(true); 3673 finalizeBlockBossLogic(); 3674 } 3675 } //setLogicXover 3676 3677 private void setLogicXoverContinuing(SignalHead head, TrackSegment track) { 3678 if (track == null) { 3679 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3680 Bundle.getMessage("InfoMessage7"), 3681 Bundle.getMessage("MessageTitle"), 3682 JmriJOptionPane.INFORMATION_MESSAGE); 3683 return; 3684 } 3685 LayoutBlock block = track.getLayoutBlock(); 3686 if (block == null) { 3687 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3688 Bundle.getMessage("InfoMessage6"), 3689 Bundle.getMessage("MessageTitle"), 3690 JmriJOptionPane.INFORMATION_MESSAGE); 3691 return; 3692 } 3693 Sensor occupancy = block.getOccupancySensor(); 3694 if (occupancy == null) { 3695 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3696 Bundle.getMessage("InfoMessage4", 3697 new Object[]{block.getUserName()}), 3698 Bundle.getMessage("MessageTitle"), 3699 JmriJOptionPane.INFORMATION_MESSAGE); 3700 return; 3701 } 3702 SignalHead nextHead = getNextSignalFromObject(track, 3703 layoutTurnout, head.getSystemName(), setSignalsAtXoverTurnoutFrame); 3704 if ((nextHead == null) && (!reachedEndBumper())) { 3705 JmriJOptionPane.showMessageDialog(setSignalsAtXoverTurnoutFrame, 3706 Bundle.getMessage("InfoMessage5", 3707 new Object[]{block.getUserName()}), 3708 Bundle.getMessage("MessageTitle"), 3709 JmriJOptionPane.INFORMATION_MESSAGE); 3710 return; 3711 } 3712 if (!initializeBlockBossLogic(head.getDisplayName())) { 3713 return; 3714 } 3715 logic.setMode(BlockBossLogic.TRAILINGMAIN); 3716 logic.setTurnout(turnout.getDisplayName()); 3717 logic.setSensor1(occupancy.getDisplayName()); 3718 if (nextHead != null) { 3719 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 3720 } 3721 if (auxSignal != null) { 3722 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 3723 } 3724 finalizeBlockBossLogic(); 3725 } //setLogicXoverContinuing 3726 3727 /*=======================*\ 3728 |* setSignalsAtLevelXing *| 3729 \*=======================*/ 3730 /** 3731 * Tool to set signals at a level crossing, including placing the signal 3732 * icons and setup of Simple Signal Logic for each signal head 3733 * <p> 3734 * This tool assumes left facing signal head icons have been selected, and 3735 * will rotate the signal head icons accordingly. 3736 * <p> 3737 * This tool will place icons on the right side of each track. 3738 * <p> 3739 * Both tracks do not need to be signalled. If one signal for a track, A-C 3740 * or B-D, the other must also be present. 3741 * <p> 3742 * Some user adjustment of turnout positions may be needed. 3743 */ 3744 //operational variables for Set Signals at Level Crossing tool 3745 private JmriJFrame setSignalsAtLevelXingFrame = null; 3746 private boolean setSignalsAtLevelXingOpenFlag = false; 3747 private boolean setSignalsAtLevelXingFromMenuFlag = false; 3748 3749 private JLabel blockACNameLabel = null; 3750 private JLabel blockBDNameLabel = null; 3751 3752 private final NamedBeanComboBox<Block> blockACComboBox = new NamedBeanComboBox<>( 3753 InstanceManager.getDefault(BlockManager.class), 3754 null, DisplayOptions.DISPLAYNAME); 3755 private final NamedBeanComboBox<Block> blockBDComboBox = new NamedBeanComboBox<>( 3756 InstanceManager.getDefault(BlockManager.class), 3757 null, DisplayOptions.DISPLAYNAME); 3758 3759 private final NamedBeanComboBox<SignalHead> aSignalHeadComboBox = new NamedBeanComboBox<>( 3760 InstanceManager.getDefault(SignalHeadManager.class), 3761 null, DisplayOptions.DISPLAYNAME); 3762 private final NamedBeanComboBox<SignalHead> bSignalHeadComboBox = new NamedBeanComboBox<>( 3763 InstanceManager.getDefault(SignalHeadManager.class), 3764 null, DisplayOptions.DISPLAYNAME); 3765 private final NamedBeanComboBox<SignalHead> cSignalHeadComboBox = new NamedBeanComboBox<>( 3766 InstanceManager.getDefault(SignalHeadManager.class), 3767 null, DisplayOptions.DISPLAYNAME); 3768 private final NamedBeanComboBox<SignalHead> dSignalHeadComboBox = new NamedBeanComboBox<>( 3769 InstanceManager.getDefault(SignalHeadManager.class), 3770 null, DisplayOptions.DISPLAYNAME); 3771 3772 private final JCheckBox setAHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 3773 private final JCheckBox setBHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 3774 private final JCheckBox setCHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 3775 private final JCheckBox setDHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 3776 3777 private final JCheckBox setupALogic = new JCheckBox(Bundle.getMessage("SetLogic")); 3778 private final JCheckBox setupBLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 3779 private final JCheckBox setupCLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 3780 private final JCheckBox setupDLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 3781 3782 private JButton getSavedXingSignalHeads = null; 3783 private JButton changeXingSignalIcon = null; 3784 private JButton setXingSignalsDone = null; 3785 private JButton setXingSignalsCancel = null; 3786 3787 private LevelXing levelXing = null; 3788 3789 private SignalHead aHead = null; 3790 private SignalHead bHead = null; 3791 private SignalHead cHead = null; 3792 private SignalHead dHead = null; 3793 3794 //display dialog for Set Signals at Level Crossing tool 3795 public void setSignalsAtLevelXingFromMenu(@Nonnull LevelXing xing, 3796 @Nonnull MultiIconEditor theEditor, 3797 @Nonnull JFrame theFrame) { 3798 levelXing = xing; 3799 blockACComboBox.setSelectedItem(levelXing.getLayoutBlockAC().getBlock()); 3800 blockBDComboBox.setSelectedItem(levelXing.getLayoutBlockBD().getBlock()); 3801 setSignalsAtLevelXingFromMenuFlag = true; 3802 setSignalsAtLevelXing(theEditor, theFrame); 3803 setSignalsAtLevelXingFromMenuFlag = false; 3804 } 3805 3806 public void setSignalsAtLevelXing(@Nonnull MultiIconEditor theEditor, 3807 @Nonnull JFrame theFrame) { 3808 signalIconEditor = theEditor; 3809 signalFrame = theFrame; 3810 3811 //Initialize if needed 3812 if (setSignalsAtLevelXingFrame == null) { 3813 setSignalsAtLevelXingOpenFlag = false; 3814 setSignalsAtLevelXingFrame = new JmriJFrame(Bundle.getMessage("SignalsAtLevelXing"), false, true); 3815 oneFrameToRuleThemAll(setSignalsAtLevelXingFrame); 3816 setSignalsAtLevelXingFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 3817 setSignalsAtLevelXingFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtLevelXing", true); 3818 setSignalsAtLevelXingFrame.setLocation(70, 30); 3819 Container theContentPane = setSignalsAtLevelXingFrame.getContentPane(); 3820 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 3821 3822 JPanel panel11 = new JPanel(new FlowLayout()); 3823 blockACNameLabel = new JLabel(Bundle.getMessage("MakeLabel", (Bundle.getMessage("BeanNameBlock") + " AC"))); 3824 panel11.add(blockACNameLabel); 3825 panel11.add(blockACComboBox); 3826 blockACComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 3827 theContentPane.add(panel11); 3828 3829 JPanel panel12 = new JPanel(new FlowLayout()); 3830 blockBDNameLabel = new JLabel(Bundle.getMessage("MakeLabel", (Bundle.getMessage("BeanNameBlock") + " BD"))); 3831 panel12.add(blockBDNameLabel); 3832 panel12.add(blockBDComboBox); 3833 blockBDComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 3834 3835 theContentPane.add(panel12); 3836 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 3837 3838 JPanel panel2 = new JPanel(new FlowLayout()); 3839 JLabel shTitle = new JLabel(Bundle.getMessage("SignalHeads")); 3840 panel2.add(shTitle); 3841 panel2.add(new JLabel(" ")); 3842 panel2.add(getSavedXingSignalHeads = new JButton(Bundle.getMessage("GetSaved"))); 3843 getSavedXingSignalHeads.addActionListener(this::xingSignalsGetSaved); 3844 getSavedXingSignalHeads.setToolTipText(Bundle.getMessage("GetSavedHint")); 3845 theContentPane.add(panel2); 3846 3847 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 3848 JPanel panel2a = new JPanel(new FlowLayout()); 3849 panel2a.add(new JLabel(" ")); 3850 panel2a.add(setPlaceAllHeads); 3851 setPlaceAllHeads.setToolTipText(Bundle.getMessage("PlaceAllHeadsHint")); 3852 setPlaceAllHeads.addActionListener((ActionEvent e) -> { 3853 boolean isSelected = setPlaceAllHeads.isSelected(); 3854 //(de)select all checkboxes 3855 setAHead.setSelected(isSelected); 3856 setBHead.setSelected(isSelected); 3857 setCHead.setSelected(isSelected); 3858 setDHead.setSelected(isSelected); 3859 }); 3860 panel2a.add(new JLabel(" ")); 3861 panel2a.add(setupAllLogic); 3862 setupAllLogic.setToolTipText(Bundle.getMessage("SetAllLogicHint")); 3863 setupAllLogic.addActionListener((ActionEvent e) -> { 3864 boolean isSelected = setupAllLogic.isSelected(); 3865 //(de)select all checkboxes 3866 setupALogic.setSelected(isSelected); 3867 setupBLogic.setSelected(isSelected); 3868 setupCLogic.setSelected(isSelected); 3869 setupDLogic.setSelected(isSelected); 3870 }); 3871 theContentPane.add(panel2a); 3872 3873 JPanel panel21 = new JPanel(new FlowLayout()); 3874 JLabel aLabel = new JLabel(Bundle.getMessage("MakeLabel", 3875 Bundle.getMessage("TrackXConnect", "A"))); 3876 panel21.add(aLabel); 3877 panel21.add(aSignalHeadComboBox); 3878 theContentPane.add(panel21); 3879 aSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 3880 3881 JPanel panel22 = new JPanel(new FlowLayout()); 3882 panel22.add(new JLabel(" ")); 3883 panel22.add(setAHead); 3884 setAHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 3885 panel22.add(new JLabel(" ")); 3886 panel22.add(setupALogic); 3887 setupALogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 3888 theContentPane.add(panel22); 3889 3890 JPanel panel31 = new JPanel(new FlowLayout()); 3891 JLabel bLabel = new JLabel(Bundle.getMessage("MakeLabel", 3892 Bundle.getMessage("TrackXConnect", "B"))); 3893 panel31.add(bLabel); 3894 panel31.add(bSignalHeadComboBox); 3895 theContentPane.add(panel31); 3896 bSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 3897 3898 JPanel panel32 = new JPanel(new FlowLayout()); 3899 panel32.add(new JLabel(" ")); 3900 panel32.add(setBHead); 3901 setBHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 3902 panel32.add(new JLabel(" ")); 3903 panel32.add(setupBLogic); 3904 setupBLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 3905 theContentPane.add(panel32); 3906 3907 JPanel panel41 = new JPanel(new FlowLayout()); 3908 JLabel cLabel = new JLabel(Bundle.getMessage("MakeLabel", 3909 Bundle.getMessage("TrackXConnect", "C"))); 3910 panel41.add(cLabel); 3911 panel41.add(cSignalHeadComboBox); 3912 theContentPane.add(panel41); 3913 cSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 3914 3915 JPanel panel42 = new JPanel(new FlowLayout()); 3916 panel42.add(new JLabel(" ")); 3917 panel42.add(setCHead); 3918 setCHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 3919 panel42.add(new JLabel(" ")); 3920 panel42.add(setupCLogic); 3921 setupCLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 3922 theContentPane.add(panel42); 3923 3924 JPanel panel51 = new JPanel(new FlowLayout()); 3925 JLabel dLabel = new JLabel(Bundle.getMessage("MakeLabel", 3926 Bundle.getMessage("TrackXConnect", "D"))); 3927 panel51.add(dLabel); 3928 panel51.add(dSignalHeadComboBox); 3929 theContentPane.add(panel51); 3930 dSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 3931 3932 JPanel panel52 = new JPanel(new FlowLayout()); 3933 panel52.add(new JLabel(" ")); 3934 panel52.add(setDHead); 3935 setDHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 3936 panel52.add(new JLabel(" ")); 3937 panel52.add(setupDLogic); 3938 setupDLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 3939 theContentPane.add(panel52); 3940 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 3941 3942 JPanel panel6 = new JPanel(new FlowLayout()); 3943 panel6.add(changeXingSignalIcon = new JButton(Bundle.getMessage("ChangeSignalIcon"))); 3944 changeXingSignalIcon.addActionListener((ActionEvent e) -> signalFrame.setVisible(true)); 3945 changeXingSignalIcon.setToolTipText(Bundle.getMessage("ChangeSignalIconHint")); 3946 panel6.add(new JLabel(" ")); 3947 panel6.add(setXingSignalsDone = new JButton(Bundle.getMessage("ButtonDone"))); 3948 setXingSignalsDone.addActionListener(this::setXingSignalsDonePressed); 3949 setXingSignalsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 3950 3951 panel6.add(setXingSignalsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 3952 setXingSignalsCancel.addActionListener(this::setXingSignalsCancelPressed); 3953 setXingSignalsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 3954 theContentPane.add(panel6); 3955 3956 //make this button the default button (return or enter activates) 3957 JRootPane rootPane = SwingUtilities.getRootPane(setXingSignalsDone); 3958 if (rootPane != null) { 3959 rootPane.setDefaultButton(setXingSignalsDone); 3960 } 3961 3962 setSignalsAtLevelXingFrame.addWindowListener(new WindowAdapter() { 3963 @Override 3964 public void windowClosing(WindowEvent e) { 3965 setXingSignalsCancelPressed(null); 3966 } 3967 }); 3968 } 3969 3970 aSignalHeadComboBox.setSelectedItem(null); 3971 bSignalHeadComboBox.setSelectedItem(null); 3972 cSignalHeadComboBox.setSelectedItem(null); 3973 dSignalHeadComboBox.setSelectedItem(null); 3974 3975 setPlaceAllHeads.setSelected(false); 3976 setupAllLogic.setSelected(false); 3977 3978 blockACComboBox.setVisible(!setSignalsAtLevelXingFromMenuFlag); 3979 blockBDComboBox.setVisible(!setSignalsAtLevelXingFromMenuFlag); 3980 3981 if (setSignalsAtLevelXingFromMenuFlag) { 3982 blockACNameLabel.setText(Bundle.getMessage("MakeLabel", 3983 (Bundle.getMessage("BeanNameBlock") + " AC")) 3984 + levelXing.getBlockNameAC()); 3985 blockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 3986 (Bundle.getMessage("BeanNameBlock") + " BD")) 3987 + levelXing.getBlockNameBD()); 3988 xingSignalsGetSaved(null); 3989 } else { 3990 blockACNameLabel.setText(Bundle.getMessage("MakeLabel", (Bundle.getMessage("BeanNameBlock") + " AC"))); 3991 blockBDNameLabel.setText(Bundle.getMessage("MakeLabel", (Bundle.getMessage("BeanNameBlock") + " BD"))); 3992 } 3993 3994 if (!setSignalsAtLevelXingOpenFlag) { 3995 setSignalsAtLevelXingFrame.setPreferredSize(null); 3996 setSignalsAtLevelXingFrame.pack(); 3997 setSignalsAtLevelXingOpenFlag = true; 3998 } 3999 4000 setSignalsAtLevelXingFrame.setVisible(true); 4001 } //setSignalsAtLevelXing 4002 4003 private void xingSignalsGetSaved(ActionEvent a) { 4004 if (!getLevelCrossingInformation()) { 4005 return; 4006 } 4007 aSignalHeadComboBox.setSelectedItem(levelXing.getSignalHead(LevelXing.Geometry.POINTA)); 4008 bSignalHeadComboBox.setSelectedItem(levelXing.getSignalHead(LevelXing.Geometry.POINTB)); 4009 cSignalHeadComboBox.setSelectedItem(levelXing.getSignalHead(LevelXing.Geometry.POINTC)); 4010 dSignalHeadComboBox.setSelectedItem(levelXing.getSignalHead(LevelXing.Geometry.POINTD)); 4011 } 4012 4013 private void setXingSignalsCancelPressed(ActionEvent a) { 4014 setSignalsAtLevelXingOpenFlag = false; 4015 setSignalsAtLevelXingFrame.setVisible(false); 4016 } 4017 4018 private void setXingSignalsDonePressed(ActionEvent a) { 4019 if (!getLevelCrossingInformation()) { 4020 return; 4021 } 4022 if (!getXingSignalHeadInformation()) { 4023 return; 4024 } 4025 4026 //place or update signals as requested 4027 String signalName = aSignalHeadComboBox.getSelectedItemDisplayName(); 4028 if (signalName == null) { 4029 signalName = ""; 4030 } 4031 if ((aHead != null) && setAHead.isSelected()) { 4032 if (isHeadOnPanel(aHead) 4033 && (aHead != getHeadFromName(levelXing.getSignalAName()))) { 4034 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4035 Bundle.getMessage("SignalsError6", 4036 new Object[]{signalName}), 4037 Bundle.getMessage("ErrorTitle"), 4038 JmriJOptionPane.ERROR_MESSAGE); 4039 return; 4040 } else { 4041 removeSignalHeadFromPanel(levelXing.getSignalAName()); 4042 placeXingA(); 4043 removeAssignment(aHead); 4044 levelXing.setSignalAName(signalName); 4045 needRedraw = true; 4046 } 4047 } else if ((aHead != null) 4048 && (aHead != getHeadFromName(levelXing.getSignalAName())) 4049 && (aHead != getHeadFromName(levelXing.getSignalBName())) 4050 && (aHead != getHeadFromName(levelXing.getSignalCName())) 4051 && (aHead != getHeadFromName(levelXing.getSignalDName()))) { 4052 if (isHeadOnPanel(aHead)) { 4053 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4054 Bundle.getMessage("SignalsError13", 4055 new Object[]{signalName}), 4056 Bundle.getMessage("ErrorTitle"), 4057 JmriJOptionPane.ERROR_MESSAGE); 4058 return; 4059 } else { 4060 removeSignalHeadFromPanel(levelXing.getSignalAName()); 4061 removeAssignment(aHead); 4062 levelXing.setSignalAName(signalName); 4063 } 4064 } else if ((aHead != null) 4065 && ((aHead == getHeadFromName(levelXing.getSignalBName())) 4066 || (aHead == getHeadFromName(levelXing.getSignalCName())) 4067 || (aHead == getHeadFromName(levelXing.getSignalDName())))) { 4068 //need to figure out what to do in this case. 4069 log.trace("need to figure out what to do in this case."); 4070 } else if (aHead == null) { 4071 removeSignalHeadFromPanel(levelXing.getSignalAName()); 4072 levelXing.setSignalAName(""); 4073 } 4074 signalName = bSignalHeadComboBox.getSelectedItemDisplayName(); 4075 if (signalName == null) { 4076 signalName = ""; 4077 } 4078 if ((bHead != null) && setBHead.isSelected()) { 4079 if (isHeadOnPanel(bHead) 4080 && (bHead != getHeadFromName(levelXing.getSignalBName()))) { 4081 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4082 Bundle.getMessage("SignalsError6", 4083 new Object[]{signalName}), 4084 Bundle.getMessage("ErrorTitle"), 4085 JmriJOptionPane.ERROR_MESSAGE); 4086 return; 4087 } else { 4088 removeSignalHeadFromPanel(levelXing.getSignalBName()); 4089 placeXingB(); 4090 removeAssignment(bHead); 4091 levelXing.setSignalBName(signalName); 4092 needRedraw = true; 4093 } 4094 } else if ((bHead != null) 4095 && (bHead != getHeadFromName(levelXing.getSignalAName())) 4096 && (bHead != getHeadFromName(levelXing.getSignalBName())) 4097 && (bHead != getHeadFromName(levelXing.getSignalCName())) 4098 && (bHead != getHeadFromName(levelXing.getSignalDName()))) { 4099 if (isHeadOnPanel(bHead)) { 4100 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4101 Bundle.getMessage("SignalsError13", 4102 new Object[]{signalName}), 4103 Bundle.getMessage("ErrorTitle"), 4104 JmriJOptionPane.ERROR_MESSAGE); 4105 return; 4106 } else { 4107 removeSignalHeadFromPanel(levelXing.getSignalBName()); 4108 removeAssignment(bHead); 4109 levelXing.setSignalBName(signalName); 4110 } 4111 } else if ((bHead != null) 4112 && ((bHead == getHeadFromName(levelXing.getSignalAName())) 4113 || (bHead == getHeadFromName(levelXing.getSignalCName())) 4114 || (bHead == getHeadFromName(levelXing.getSignalDName())))) { 4115 //need to figure out what to do in this case. 4116 log.trace("need to figure out what to do in this case."); 4117 } else if (bHead == null) { 4118 removeSignalHeadFromPanel(levelXing.getSignalBName()); 4119 levelXing.setSignalBName(""); 4120 } 4121 signalName = cSignalHeadComboBox.getSelectedItemDisplayName(); 4122 if (signalName == null) { 4123 signalName = ""; 4124 } 4125 if ((cHead != null) && setCHead.isSelected()) { 4126 if (isHeadOnPanel(cHead) 4127 && (cHead != getHeadFromName(levelXing.getSignalCName()))) { 4128 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4129 Bundle.getMessage("SignalsError6", 4130 new Object[]{signalName}), 4131 Bundle.getMessage("ErrorTitle"), 4132 JmriJOptionPane.ERROR_MESSAGE); 4133 return; 4134 } else { 4135 removeSignalHeadFromPanel(levelXing.getSignalCName()); 4136 placeXingC(); 4137 removeAssignment(cHead); 4138 levelXing.setSignalCName(signalName); 4139 needRedraw = true; 4140 } 4141 } else if ((cHead != null) 4142 && (cHead != getHeadFromName(levelXing.getSignalAName())) 4143 && (cHead != getHeadFromName(levelXing.getSignalBName())) 4144 && (cHead != getHeadFromName(levelXing.getSignalCName())) 4145 && (cHead != getHeadFromName(levelXing.getSignalDName()))) { 4146 if (isHeadOnPanel(cHead)) { 4147 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4148 Bundle.getMessage("SignalsError13", 4149 new Object[]{signalName}), 4150 Bundle.getMessage("ErrorTitle"), 4151 JmriJOptionPane.ERROR_MESSAGE); 4152 return; 4153 } else { 4154 removeSignalHeadFromPanel(levelXing.getSignalCName()); 4155 removeAssignment(cHead); 4156 levelXing.setSignalCName(signalName); 4157 } 4158 } else if ((cHead != null) 4159 && ((cHead == getHeadFromName(levelXing.getSignalBName())) 4160 || (cHead == getHeadFromName(levelXing.getSignalAName())) 4161 || (cHead == getHeadFromName(levelXing.getSignalDName())))) { 4162 //need to figure out what to do in this case. 4163 log.trace("need to figure out what to do in this case."); 4164 } else if (cHead == null) { 4165 removeSignalHeadFromPanel(levelXing.getSignalCName()); 4166 levelXing.setSignalCName(""); 4167 } 4168 signalName = dSignalHeadComboBox.getSelectedItemDisplayName(); 4169 if (signalName == null) { 4170 signalName = ""; 4171 } 4172 if ((dHead != null) && setDHead.isSelected()) { 4173 if (isHeadOnPanel(dHead) 4174 && (dHead != getHeadFromName(levelXing.getSignalDName()))) { 4175 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4176 Bundle.getMessage("SignalsError6", 4177 new Object[]{signalName}), 4178 Bundle.getMessage("ErrorTitle"), 4179 JmriJOptionPane.ERROR_MESSAGE); 4180 return; 4181 } else { 4182 removeSignalHeadFromPanel(levelXing.getSignalDName()); 4183 placeXingD(); 4184 removeAssignment(dHead); 4185 levelXing.setSignalDName(signalName); 4186 needRedraw = true; 4187 } 4188 } else if ((dHead != null) 4189 && (dHead != getHeadFromName(levelXing.getSignalAName())) 4190 && (dHead != getHeadFromName(levelXing.getSignalBName())) 4191 && (dHead != getHeadFromName(levelXing.getSignalCName())) 4192 && (dHead != getHeadFromName(levelXing.getSignalDName()))) { 4193 if (isHeadOnPanel(dHead)) { 4194 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4195 Bundle.getMessage("SignalsError13", 4196 new Object[]{signalName}), 4197 Bundle.getMessage("ErrorTitle"), 4198 JmriJOptionPane.ERROR_MESSAGE); 4199 return; 4200 } else { 4201 removeSignalHeadFromPanel(levelXing.getSignalDName()); 4202 removeAssignment(dHead); 4203 levelXing.setSignalDName(signalName); 4204 } 4205 } else if ((dHead != null) 4206 && ((dHead == getHeadFromName(levelXing.getSignalBName())) 4207 || (dHead == getHeadFromName(levelXing.getSignalCName())) 4208 || (dHead == getHeadFromName(levelXing.getSignalAName())))) { 4209 //need to figure out what to do in this case. 4210 log.trace("need to figure out what to do in this case."); 4211 } else if (dHead == null) { 4212 removeSignalHeadFromPanel(levelXing.getSignalDName()); 4213 levelXing.setSignalDName(""); 4214 } 4215 //setup logic if requested 4216 if (setupALogic.isSelected() && (aHead != null)) { 4217 setLogicXing(aHead, (TrackSegment) levelXing.getConnectC(), 4218 levelXing.getLayoutBlockBD(), (TrackSegment) levelXing.getConnectB(), 4219 (TrackSegment) levelXing.getConnectD(), aSignalHeadComboBox.getSelectedItemDisplayName()); 4220 } 4221 if (setupBLogic.isSelected() && (bHead != null)) { 4222 setLogicXing(bHead, (TrackSegment) levelXing.getConnectD(), 4223 levelXing.getLayoutBlockAC(), (TrackSegment) levelXing.getConnectA(), 4224 (TrackSegment) levelXing.getConnectC(), bSignalHeadComboBox.getSelectedItemDisplayName()); 4225 } 4226 if (setupCLogic.isSelected() && (cHead != null)) { 4227 setLogicXing(cHead, (TrackSegment) levelXing.getConnectA(), 4228 levelXing.getLayoutBlockBD(), (TrackSegment) levelXing.getConnectB(), 4229 (TrackSegment) levelXing.getConnectD(), cSignalHeadComboBox.getSelectedItemDisplayName()); 4230 } 4231 if (setupDLogic.isSelected() && (dHead != null)) { 4232 setLogicXing(dHead, (TrackSegment) levelXing.getConnectB(), 4233 levelXing.getLayoutBlockAC(), (TrackSegment) levelXing.getConnectA(), 4234 (TrackSegment) levelXing.getConnectC(), dSignalHeadComboBox.getSelectedItemDisplayName()); 4235 } 4236 //finish up 4237 setSignalsAtLevelXingOpenFlag = false; 4238 setSignalsAtLevelXingFrame.setVisible(false); 4239 if (needRedraw) { 4240 layoutEditor.redrawPanel(); 4241 needRedraw = false; 4242 layoutEditor.setDirty(); 4243 } 4244 } //setXingSignalsDonePressed 4245 4246 private boolean getLevelCrossingInformation() { 4247 if (!setSignalsAtLevelXingFromMenuFlag) { 4248 levelXing = null; 4249 List<LevelXing> levelXings = layoutEditor.getLevelXings(); 4250 if (levelXings.size() <= 0) { 4251 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4252 Bundle.getMessage("SignalsError15"), 4253 Bundle.getMessage("ErrorTitle"), 4254 JmriJOptionPane.ERROR_MESSAGE); 4255 return false; 4256 } else if (levelXings.size() == 1) { 4257 levelXing = levelXings.get(0); 4258 } else { 4259 LayoutBlock xingBlockA = null; 4260 xingBlockA = getBlockFromEntry(blockACComboBox); 4261 if (xingBlockA == null) { 4262 return false; 4263 } 4264 4265 LayoutBlock xingBlockC = getBlockFromEntry(blockBDComboBox); 4266 if (xingBlockC == null) { 4267 return false; 4268 } 4269 4270 int foundCount = 0; 4271 //make two block tests first 4272 for (LevelXing x : layoutEditor.getLevelXings()) { 4273 LayoutBlock xA = null; 4274 LayoutBlock xB = null; 4275 LayoutBlock xC = null; 4276 LayoutBlock xD = null; 4277 LayoutBlock xAC = x.getLayoutBlockAC(); 4278 LayoutBlock xBD = x.getLayoutBlockBD(); 4279 if (x.getConnectA() != null) { 4280 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 4281 } 4282 if (x.getConnectB() != null) { 4283 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 4284 } 4285 if (x.getConnectC() != null) { 4286 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 4287 } 4288 if (x.getConnectD() != null) { 4289 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 4290 } 4291 if (((xA != null) && (xC != null) && (((xA == xingBlockA) && (xC == xingBlockC)) 4292 || ((xA == xingBlockC) && (xC == xingBlockA)))) 4293 || ((xB != null) && (xD != null) && (((xB == xingBlockA) && (xD == xingBlockC)) 4294 || ((xB == xingBlockC) && (xD == xingBlockA))))) { 4295 levelXing = x; 4296 foundCount++; 4297 } else if ((xAC != null) && (xBD != null) && (((xAC == xingBlockA) && (xBD == xingBlockC)) 4298 || ((xAC == xingBlockC) && (xBD == xingBlockA)))) { 4299 levelXing = x; 4300 foundCount++; 4301 } 4302 } 4303 if (foundCount == 0) { 4304 //try one block test 4305 for (LevelXing x : layoutEditor.getLevelXings()) { 4306 if ((xingBlockA == x.getLayoutBlockAC()) || (xingBlockA == x.getLayoutBlockBD())) { 4307 levelXing = x; 4308 foundCount++; 4309 } 4310 } 4311 } 4312 if (foundCount > 1) { 4313 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4314 Bundle.getMessage("SignalsError16", 4315 new Object[]{" " + foundCount + " "}), 4316 Bundle.getMessage("ErrorTitle"), 4317 JmriJOptionPane.ERROR_MESSAGE); 4318 return false; 4319 } 4320 if (levelXing == null) { 4321 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4322 Bundle.getMessage("SignalsError17"), 4323 Bundle.getMessage("ErrorTitle"), 4324 JmriJOptionPane.ERROR_MESSAGE); 4325 return false; 4326 } 4327 } 4328 } 4329 4330 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 4331 4332 Point2D coordsA = levelXingView.getCoordsA(); 4333 Point2D coordsC = levelXingView.getCoordsC(); 4334 placeSignalDirectionDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsA)); 4335 4336 return true; 4337 } //getLevelCrossingInformation 4338 4339 private boolean getXingSignalHeadInformation() { 4340 //note that all heads are optional, but pairs must be present 4341 aHead = getSignalHeadFromEntry(aSignalHeadComboBox, false, setSignalsAtLevelXingFrame); 4342 bHead = getSignalHeadFromEntry(bSignalHeadComboBox, false, setSignalsAtLevelXingFrame); 4343 cHead = getSignalHeadFromEntry(cSignalHeadComboBox, false, setSignalsAtLevelXingFrame); 4344 dHead = getSignalHeadFromEntry(dSignalHeadComboBox, false, setSignalsAtLevelXingFrame); 4345 if (((aHead != null) && (cHead == null)) || ((aHead == null) && (cHead != null)) 4346 || ((bHead != null) && (dHead == null)) || ((bHead == null) && (dHead != null))) { 4347 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4348 Bundle.getMessage("SignalsError14"), 4349 Bundle.getMessage("ErrorTitle"), 4350 JmriJOptionPane.ERROR_MESSAGE); 4351 return false; 4352 } 4353 if ((aHead == null) && (bHead == null) && (cHead == null) && (dHead == null)) { 4354 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4355 Bundle.getMessage("SignalsError12"), 4356 Bundle.getMessage("ErrorTitle"), 4357 JmriJOptionPane.ERROR_MESSAGE); 4358 return false; 4359 } 4360 return true; 4361 } 4362 4363 private void placeXingA() { 4364 if (testIcon == null) { 4365 testIcon = signalIconEditor.getIcon(0); 4366 } 4367 String signalHeadName = aSignalHeadComboBox.getSelectedItemDisplayName(); 4368 if (signalHeadName == null) { 4369 signalHeadName = ""; 4370 } 4371 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 4372 4373 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 4374 4375 Point2D coordsA = levelXingView.getCoordsA(); 4376 Point2D delta = new Point2D.Double(0.0, +shift); 4377 4378 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 4379 Point2D where = MathUtil.add(coordsA, delta); 4380 setSignalHeadOnPanel(placeSignalDirectionDEG + 180.0, signalHeadName, where); 4381 } 4382 4383 private void placeXingB() { 4384 if (testIcon == null) { 4385 testIcon = signalIconEditor.getIcon(0); 4386 } 4387 String signalHeadName = bSignalHeadComboBox.getSelectedItemDisplayName(); 4388 if (signalHeadName == null) { 4389 signalHeadName = ""; 4390 } 4391 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 4392 4393 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 4394 4395 Point2D coordsB = levelXingView.getCoordsB(); 4396 Point2D coordsD = levelXingView.getCoordsD(); 4397 4398 double directionDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsD)); 4399 Point2D delta = new Point2D.Double(0.0, -shift); 4400 4401 delta = MathUtil.rotateDEG(delta, directionDEG); 4402 Point2D where = MathUtil.add(coordsB, delta); 4403 setSignalHeadOnPanel(directionDEG, signalHeadName, where); 4404 } 4405 4406 private void placeXingC() { 4407 if (testIcon == null) { 4408 testIcon = signalIconEditor.getIcon(0); 4409 } 4410 String signalHeadName = cSignalHeadComboBox.getSelectedItemDisplayName(); 4411 if (signalHeadName == null) { 4412 signalHeadName = ""; 4413 } 4414 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 4415 4416 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 4417 4418 Point2D coordsC = levelXingView.getCoordsC(); 4419 Point2D delta = new Point2D.Double(0.0, -shift); 4420 4421 delta = MathUtil.rotateDEG(delta, placeSignalDirectionDEG); 4422 Point2D where = MathUtil.add(coordsC, delta); 4423 setSignalHeadOnPanel(placeSignalDirectionDEG, signalHeadName, where); 4424 } 4425 4426 private void placeXingD() { 4427 if (testIcon == null) { 4428 testIcon = signalIconEditor.getIcon(0); 4429 } 4430 String signalHeadName = dSignalHeadComboBox.getSelectedItemDisplayName(); 4431 if (signalHeadName == null) { 4432 signalHeadName = ""; 4433 } 4434 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 4435 4436 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 4437 4438 Point2D coordsB = levelXingView.getCoordsB(); 4439 Point2D coordsD = levelXingView.getCoordsD(); 4440 4441 double directionDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsB)); 4442 double diffDirDEG = MathUtil.diffAngleDEG(placeSignalDirectionDEG, directionDEG + 180.0); 4443 Point2D delta = new Point2D.Double(-shift * Math.cos(Math.toRadians(diffDirDEG)), -shift); 4444 4445 delta = MathUtil.rotateDEG(delta, directionDEG); 4446 Point2D where = MathUtil.add(coordsD, delta); 4447 setSignalHeadOnPanel(directionDEG, signalHeadName, where); 4448 } 4449 4450 @SuppressWarnings("null") 4451 private void setLogicXing(SignalHead head, TrackSegment track, LayoutBlock crossBlock, 4452 TrackSegment crossTrack1, TrackSegment crossTrack2, String signalHeadName) { 4453 if (track == null) { 4454 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4455 Bundle.getMessage("InfoMessage7"), 4456 Bundle.getMessage("MessageTitle"), 4457 JmriJOptionPane.INFORMATION_MESSAGE); 4458 return; 4459 } 4460 Sensor occupancy = null; 4461 Sensor crossOccupancy = null; 4462 Sensor track1Occupancy = null; 4463 Sensor track2Occupancy = null; 4464 SignalHead nextHead = null; 4465 LayoutBlock block = track.getLayoutBlock(); 4466 if (block == null) { 4467 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4468 Bundle.getMessage("InfoMessage6"), 4469 Bundle.getMessage("MessageTitle"), 4470 JmriJOptionPane.INFORMATION_MESSAGE); 4471 return; 4472 } 4473 occupancy = block.getOccupancySensor(); 4474 if (occupancy == null) { 4475 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4476 Bundle.getMessage("InfoMessage4", 4477 new Object[]{block.getUserName()}), 4478 Bundle.getMessage("MessageTitle"), 4479 JmriJOptionPane.INFORMATION_MESSAGE); 4480 return; 4481 } 4482 if (crossBlock != null) { 4483 crossOccupancy = crossBlock.getOccupancySensor(); 4484 } 4485 if (crossTrack1 != null) { 4486 block = crossTrack1.getLayoutBlock(); 4487 if (block != null) { 4488 track1Occupancy = block.getOccupancySensor(); 4489 if (track1Occupancy == crossOccupancy) { 4490 track1Occupancy = null; 4491 } 4492 } 4493 } 4494 if (crossTrack2 != null) { 4495 block = crossTrack2.getLayoutBlock(); 4496 if (block != null) { 4497 track2Occupancy = block.getOccupancySensor(); 4498 if ((track2Occupancy == crossOccupancy) 4499 || (track2Occupancy == track1Occupancy)) { 4500 track2Occupancy = null; 4501 } 4502 } 4503 } 4504 nextHead = getNextSignalFromObject(track, levelXing, 4505 head.getSystemName(), setSignalsAtXoverTurnoutFrame); 4506 if ((nextHead == null) && (!reachedEndBumper())) { 4507 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4508 Bundle.getMessage("InfoMessage5", 4509 new Object[]{block.getUserName()}), 4510 Bundle.getMessage("MessageTitle"), 4511 JmriJOptionPane.INFORMATION_MESSAGE); 4512 return; 4513 } 4514 if ((crossOccupancy == null) && (track1Occupancy == null) && (track2Occupancy == null)) { 4515 JmriJOptionPane.showMessageDialog(setSignalsAtLevelXingFrame, 4516 Bundle.getMessage("SignalsWarn1", 4517 new Object[]{signalHeadName}), 4518 Bundle.getMessage("WarningTitle"), 4519 JmriJOptionPane.WARNING_MESSAGE); 4520 } 4521 if (!initializeBlockBossLogic(head.getDisplayName())) { 4522 return; 4523 } 4524 logic.setMode(BlockBossLogic.SINGLEBLOCK); 4525 logic.setSensor1(occupancy.getDisplayName()); 4526 if (nextHead != null) { 4527 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 4528 } 4529 if (auxSignal != null) { 4530 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 4531 } 4532 if (crossOccupancy != null) { 4533 logic.setSensor2(crossOccupancy.getDisplayName()); 4534 if (track1Occupancy != null) { 4535 logic.setSensor3(track1Occupancy.getDisplayName()); 4536 if (track2Occupancy != null) { 4537 logic.setSensor4(track2Occupancy.getDisplayName()); 4538 } 4539 } else if (track2Occupancy != null) { 4540 logic.setSensor3(track2Occupancy.getDisplayName()); 4541 } 4542 } else if (track1Occupancy != null) { 4543 logic.setSensor2(track1Occupancy.getDisplayName()); 4544 if (track2Occupancy != null) { 4545 logic.setSensor3(track2Occupancy.getDisplayName()); 4546 } 4547 } else if (track2Occupancy != null) { 4548 logic.setSensor2(track2Occupancy.getDisplayName()); 4549 } 4550 finalizeBlockBossLogic(); 4551 } 4552 4553 /*====================================*\ 4554 |* setSignalsAtThroatToThroatTurnouts *| 4555 \*====================================*/ 4556 /** 4557 * Tool to set signals at throat-to-throat turnouts, including placing the 4558 * signal icons and setup of signal logic for each signal head 4559 * <p> 4560 * This tool can only be accessed from the Tools menu. There is no access 4561 * from a turnout pop-up menu. 4562 * <p> 4563 * This tool requires a situation where two turnouts are connected throat- 4564 * to-throat by a single "short" track segment. The actual length of the 4565 * track segment is not tested. If this situation is not found, and error 4566 * message is sent to the user. To get started with this the user needs to 4567 * enter at least one of the two connected turnouts. 4568 * <p> 4569 * This tool assumes two turnouts connected throat-to-throat, as would be 4570 * used to represent a double slip turnout. The turnouts may be either 4571 * left-handed, right-handed, wye, or any pair of these. This tool also 4572 * assumes that there are no signals at the throat junction. The signal 4573 * heads will be rotated to face outward--away from the throats. Four sets 4574 * of one or two signal heads will be placed, one at each of the converging 4575 * and diverging for each turnout. 4576 * <p> 4577 * This tool assumes that each of the four tracks is contained in a 4578 * different block. Things work best if the two throat-to-throat turnouts 4579 * are in their own separate block, but this is not necessary. 4580 * <p> 4581 * This tool will place icons on the outside edges of each turnout. 4582 * <p> 4583 * At least one signal at each of the four connection points is required. A 4584 * second signal at each is optional. 4585 */ 4586 //operational variables for Set Signals at Double Crossover Turnout tool 4587 private JmriJFrame setSignalsAtThroatToThroatTurnoutsFrame = null; 4588 private boolean setSignalsAtThroatToThroatTurnoutsOpenFlag = false; 4589 private boolean setSignalsAtThroatToThroatTurnoutsFromMenuFlag = false; 4590 4591 private JLabel ttotTurnoutName1Label = null; 4592 private JLabel ttotTurnoutName2Label = null; 4593 4594 private final NamedBeanComboBox<Turnout> turnout1ComboBox = new NamedBeanComboBox<>( 4595 InstanceManager.turnoutManagerInstance(), 4596 null, DisplayOptions.DISPLAYNAME); 4597 private final NamedBeanComboBox<Turnout> turnout2ComboBox = new NamedBeanComboBox<>( 4598 InstanceManager.turnoutManagerInstance(), 4599 null, DisplayOptions.DISPLAYNAME); 4600 4601 private final NamedBeanComboBox<SignalHead> a1TToTSignalHeadComboBox = new NamedBeanComboBox<>( 4602 InstanceManager.getDefault(SignalHeadManager.class 4603 ), 4604 null, DisplayOptions.DISPLAYNAME); 4605 private final NamedBeanComboBox<SignalHead> a2TToTSignalHeadComboBox = new NamedBeanComboBox<>( 4606 InstanceManager.getDefault(SignalHeadManager.class 4607 ), 4608 null, DisplayOptions.DISPLAYNAME); 4609 private final NamedBeanComboBox<SignalHead> b1TToTSignalHeadComboBox = new NamedBeanComboBox<>( 4610 InstanceManager.getDefault(SignalHeadManager.class 4611 ), 4612 null, DisplayOptions.DISPLAYNAME); 4613 private final NamedBeanComboBox<SignalHead> b2TToTSignalHeadComboBox = new NamedBeanComboBox<>( 4614 InstanceManager.getDefault(SignalHeadManager.class 4615 ), 4616 null, DisplayOptions.DISPLAYNAME); 4617 private final NamedBeanComboBox<SignalHead> c1TToTSignalHeadComboBox = new NamedBeanComboBox<>( 4618 InstanceManager.getDefault(SignalHeadManager.class 4619 ), 4620 null, DisplayOptions.DISPLAYNAME); 4621 private final NamedBeanComboBox<SignalHead> c2TToTSignalHeadComboBox = new NamedBeanComboBox<>( 4622 InstanceManager.getDefault(SignalHeadManager.class 4623 ), 4624 null, DisplayOptions.DISPLAYNAME); 4625 private final NamedBeanComboBox<SignalHead> d1TToTSignalHeadComboBox = new NamedBeanComboBox<>( 4626 InstanceManager.getDefault(SignalHeadManager.class 4627 ), 4628 null, DisplayOptions.DISPLAYNAME); 4629 private final NamedBeanComboBox<SignalHead> d2TToTSignalHeadComboBox = new NamedBeanComboBox<>( 4630 InstanceManager.getDefault(SignalHeadManager.class 4631 ), 4632 null, DisplayOptions.DISPLAYNAME); 4633 4634 private final JCheckBox setA1TToTHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 4635 private final JCheckBox setA2TToTHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 4636 private final JCheckBox setB1TToTHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 4637 private final JCheckBox setB2TToTHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 4638 private final JCheckBox setC1TToTHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 4639 private final JCheckBox setC2TToTHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 4640 private final JCheckBox setD1TToTHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 4641 private final JCheckBox setD2TToTHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 4642 4643 private final JCheckBox setupA1TToTLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 4644 private final JCheckBox setupA2TToTLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 4645 private final JCheckBox setupB1TToTLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 4646 private final JCheckBox setupB2TToTLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 4647 private final JCheckBox setupC1TToTLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 4648 private final JCheckBox setupC2TToTLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 4649 private final JCheckBox setupD1TToTLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 4650 private final JCheckBox setupD2TToTLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 4651 4652 private JButton getSavedTToTSignalHeads = null; 4653 private JButton changeTToTSignalIcon = null; 4654 private JButton setTToTSignalsDone = null; 4655 private JButton setTToTSignalsCancel = null; 4656 4657 private LayoutTurnout layoutTurnout1 = null; 4658 private LayoutTurnout layoutTurnout2 = null; 4659 4660 private Turnout turnout1 = null; 4661 private Turnout turnout2 = null; 4662 4663 private TrackSegment connectorTrack = null; 4664 4665 private String ttotTurnoutName1 = null; 4666 private String ttotTurnoutName2 = null; 4667 4668 private SignalHead a1TToTHead = null; 4669 private SignalHead a2TToTHead = null; 4670 private SignalHead b1TToTHead = null; 4671 private SignalHead b2TToTHead = null; 4672 private SignalHead c1TToTHead = null; 4673 private SignalHead c2TToTHead = null; 4674 private SignalHead d1TToTHead = null; 4675 private SignalHead d2TToTHead = null; 4676 4677 public void setSignalsAtThroatToThroatTurnoutsFromMenu( 4678 @Nonnull LayoutTurnout to, @Nonnull String linkedTurnoutName, 4679 @Nonnull MultiIconEditor theEditor, @Nonnull JFrame theFrame) { 4680 ttotTurnoutName1 = to.getTurnoutName(); 4681 ttotTurnoutName2 = linkedTurnoutName; 4682 4683 turnout1ComboBox.setSelectedItem(to.getTurnout()); 4684 turnout2ComboBox.setSelectedItem(to.getSecondTurnout()); 4685 4686 a1TToTSignalHeadComboBox.setSelectedItem(null); 4687 a2TToTSignalHeadComboBox.setSelectedItem(null); 4688 b1TToTSignalHeadComboBox.setSelectedItem(null); 4689 b2TToTSignalHeadComboBox.setSelectedItem(null); 4690 c1TToTSignalHeadComboBox.setSelectedItem(null); 4691 c2TToTSignalHeadComboBox.setSelectedItem(null); 4692 d1TToTSignalHeadComboBox.setSelectedItem(null); 4693 d2TToTSignalHeadComboBox.setSelectedItem(null); 4694 4695 setSignalsAtThroatToThroatTurnoutsFromMenuFlag = true; 4696 setSignalsAtThroatToThroatTurnouts(theEditor, theFrame); 4697 setSignalsAtThroatToThroatTurnoutsFromMenuFlag = false; 4698 } 4699 4700 public void setSignalsAtThroatToThroatTurnouts( 4701 @Nonnull MultiIconEditor theEditor, @Nonnull JFrame theFrame) { 4702 signalIconEditor = theEditor; 4703 signalFrame = theFrame; 4704 4705 //Initialize if needed 4706 if (setSignalsAtThroatToThroatTurnoutsFrame == null) { 4707 setSignalsAtThroatToThroatTurnoutsOpenFlag = false; 4708 setSignalsAtThroatToThroatTurnoutsFrame = new JmriJFrame(Bundle.getMessage("SignalsAtTToTTurnout"), false, true); 4709 oneFrameToRuleThemAll(setSignalsAtThroatToThroatTurnoutsFrame); 4710 setSignalsAtThroatToThroatTurnoutsFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 4711 setSignalsAtThroatToThroatTurnoutsFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtTToTTurnout", true); 4712 setSignalsAtThroatToThroatTurnoutsFrame.setLocation(70, 30); 4713 Container theContentPane = setSignalsAtThroatToThroatTurnoutsFrame.getContentPane(); 4714 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 4715 4716 JPanel panel1a = new JPanel(new FlowLayout()); 4717 ttotTurnoutName1Label = new JLabel(Bundle.getMessage("BeanNameTurnout") + " 1 " 4718 + Bundle.getMessage("Name")); 4719 panel1a.add(ttotTurnoutName1Label); 4720 panel1a.add(turnout1ComboBox); 4721 turnout1ComboBox.setToolTipText(Bundle.getMessage("SignalsTurnoutNameHint")); 4722 theContentPane.add(panel1a); 4723 4724 JPanel panel1b = new JPanel(new FlowLayout()); 4725 ttotTurnoutName2Label = new JLabel(Bundle.getMessage("BeanNameTurnout") + " 2 " 4726 + Bundle.getMessage("Name")); 4727 panel1b.add(ttotTurnoutName2Label); 4728 panel1b.add(turnout2ComboBox); 4729 turnout2ComboBox.setToolTipText(Bundle.getMessage("SignalsTurnoutNameHint")); 4730 theContentPane.add(panel1b); 4731 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 4732 //Provide for retrieval of names of previously saved signal heads 4733 4734 JPanel panel20 = new JPanel(new FlowLayout()); 4735 JLabel shTitle = new JLabel(Bundle.getMessage("SignalHeads")); 4736 panel20.add(shTitle); 4737 panel20.add(new JLabel(" ")); 4738 panel20.add(getSavedTToTSignalHeads = new JButton(Bundle.getMessage("GetSaved"))); 4739 getSavedTToTSignalHeads.addActionListener(this::setSignalsAtTToTTurnoutsGetSaved); 4740 getSavedTToTSignalHeads.setToolTipText(Bundle.getMessage("GetSavedHint")); 4741 theContentPane.add(panel20); 4742 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 4743 4744 JPanel panel2a = new JPanel(new FlowLayout()); 4745 panel2a.add(new JLabel(" ")); 4746 panel2a.add(setPlaceAllHeads); 4747 setPlaceAllHeads.setToolTipText(Bundle.getMessage("PlaceAllHeadsHint")); 4748 setPlaceAllHeads.addActionListener((ActionEvent e) -> { 4749 boolean isSelected = setPlaceAllHeads.isSelected(); 4750 //(de)select all checkboxes 4751 setA1TToTHead.setSelected(isSelected); 4752 setA2TToTHead.setSelected(isSelected); 4753 setB1TToTHead.setSelected(isSelected); 4754 setB2TToTHead.setSelected(isSelected); 4755 setC1TToTHead.setSelected(isSelected); 4756 setC2TToTHead.setSelected(isSelected); 4757 setD1TToTHead.setSelected(isSelected); 4758 setD2TToTHead.setSelected(isSelected); 4759 }); 4760 panel2a.add(new JLabel(" ")); 4761 panel2a.add(setupAllLogic); 4762 setupAllLogic.setToolTipText(Bundle.getMessage("SetAllLogicHint")); 4763 setupAllLogic.addActionListener((ActionEvent e) -> { 4764 boolean isSelected = setupAllLogic.isSelected(); 4765 //(de)select all checkboxes 4766 setupA1TToTLogic.setSelected(isSelected); 4767 setupA2TToTLogic.setSelected(isSelected); 4768 setupB1TToTLogic.setSelected(isSelected); 4769 setupB2TToTLogic.setSelected(isSelected); 4770 setupC1TToTLogic.setSelected(isSelected); 4771 setupC2TToTLogic.setSelected(isSelected); 4772 setupD1TToTLogic.setSelected(isSelected); 4773 setupD2TToTLogic.setSelected(isSelected); 4774 }); 4775 theContentPane.add(panel2a); 4776 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 4777 4778 //Signal heads located at turnout 1 4779 JPanel panel20a = new JPanel(new FlowLayout()); 4780 panel20a.add(new JLabel(Bundle.getMessage("SignalLocated") 4781 + " " + Bundle.getMessage("BeanNameTurnout") + " 1 - " 4782 + Bundle.getMessage("ContinuingTrack"))); 4783 theContentPane.add(panel20a); 4784 4785 JPanel panel21 = new JPanel(new FlowLayout()); 4786 panel21.add(new JLabel(Bundle.getMessage("MakeLabel", 4787 Bundle.getMessage("ProtectsTurnout") + " 2 - " 4788 + Bundle.getMessage("ContinuingTrack")))); 4789 panel21.add(a1TToTSignalHeadComboBox); 4790 theContentPane.add(panel21); 4791 a1TToTSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 4792 4793 JPanel panel22 = new JPanel(new FlowLayout()); 4794 panel22.add(new JLabel(Bundle.getMessage("OrBoth") + " 2 " + Bundle.getMessage("Tracks)") + " ")); 4795 panel22.add(setA1TToTHead); 4796 setA1TToTHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 4797 panel22.add(new JLabel(" ")); 4798 panel22.add(setupA1TToTLogic); 4799 setupA1TToTLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 4800 theContentPane.add(panel22); 4801 4802 JPanel panel23 = new JPanel(new FlowLayout()); 4803 panel23.add(new JLabel(Bundle.getMessage("MakeLabel", 4804 Bundle.getMessage("ProtectsTurnout") + " 2 - " 4805 + Bundle.getMessage("DivergingTrack")))); 4806 panel23.add(a2TToTSignalHeadComboBox); 4807 theContentPane.add(panel23); 4808 a2TToTSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 4809 4810 JPanel panel24 = new JPanel(new FlowLayout()); 4811 panel24.add(new JLabel(" ")); 4812 panel24.add(setA2TToTHead); 4813 setA2TToTHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 4814 panel24.add(new JLabel(" ")); 4815 panel24.add(setupA2TToTLogic); 4816 setupA2TToTLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 4817 theContentPane.add(panel24); 4818 4819 JPanel panel31x = new JPanel(new FlowLayout()); 4820 panel31x.add(new JLabel(Bundle.getMessage("SignalLocated") 4821 + " " + Bundle.getMessage("BeanNameTurnout") + " 1 - " 4822 + Bundle.getMessage("DivergingTrack"))); 4823 theContentPane.add(panel31x); 4824 4825 JPanel panel31 = new JPanel(new FlowLayout()); 4826 panel31.add(new JLabel(Bundle.getMessage("MakeLabel", 4827 Bundle.getMessage("ProtectsTurnout") + " 2 - " 4828 + Bundle.getMessage("ContinuingTrack")))); 4829 panel31.add(b1TToTSignalHeadComboBox); 4830 theContentPane.add(panel31); 4831 b1TToTSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 4832 4833 JPanel panel32 = new JPanel(new FlowLayout()); 4834 panel32.add(new JLabel(Bundle.getMessage("OrBoth") + " 2 " + Bundle.getMessage("Tracks)") + " ")); 4835 panel32.add(setB1TToTHead); 4836 setB1TToTHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 4837 panel32.add(new JLabel(" ")); 4838 panel32.add(setupB1TToTLogic); 4839 setupB1TToTLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 4840 theContentPane.add(panel32); 4841 4842 JPanel panel33 = new JPanel(new FlowLayout()); 4843 panel33.add(new JLabel(Bundle.getMessage("MakeLabel", 4844 Bundle.getMessage("ProtectsTurnout") + " 2 - " 4845 + Bundle.getMessage("DivergingTrack")))); 4846 panel33.add(b2TToTSignalHeadComboBox); 4847 theContentPane.add(panel33); 4848 b2TToTSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 4849 4850 JPanel panel34 = new JPanel(new FlowLayout()); 4851 panel34.add(new JLabel(" ")); 4852 panel34.add(setB2TToTHead); 4853 setB2TToTHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 4854 panel34.add(new JLabel(" ")); 4855 panel34.add(setupB2TToTLogic); 4856 setupB2TToTLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 4857 theContentPane.add(panel34); 4858 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 4859 //Signal heads located at turnout 2 4860 4861 JPanel panel41x = new JPanel(new FlowLayout()); 4862 panel41x.add(new JLabel(Bundle.getMessage("SignalLocated") 4863 + " " + Bundle.getMessage("BeanNameTurnout") + " 2 - " 4864 + Bundle.getMessage("ContinuingTrack"))); 4865 theContentPane.add(panel41x); 4866 4867 JPanel panel41 = new JPanel(new FlowLayout()); 4868 panel33.add(new JLabel(Bundle.getMessage("MakeLabel", 4869 Bundle.getMessage("ProtectsTurnout") + " 1 - " 4870 + Bundle.getMessage("ContinuingTrack")))); 4871 panel41.add(c1TToTSignalHeadComboBox); 4872 theContentPane.add(panel41); 4873 c1TToTSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 4874 4875 JPanel panel42 = new JPanel(new FlowLayout()); 4876 panel42.add(new JLabel(Bundle.getMessage("OrBoth") + " 1 " + Bundle.getMessage("Tracks)") + " ")); 4877 panel42.add(setC1TToTHead); 4878 setC1TToTHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 4879 panel42.add(new JLabel(" ")); 4880 panel42.add(setupC1TToTLogic); 4881 setupC1TToTLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 4882 theContentPane.add(panel42); 4883 4884 JPanel panel43 = new JPanel(new FlowLayout()); 4885 panel43.add(new JLabel(Bundle.getMessage("MakeLabel", 4886 Bundle.getMessage("ProtectsTurnout") + " 1 - " 4887 + Bundle.getMessage("DivergingTrack")))); 4888 panel43.add(c2TToTSignalHeadComboBox); 4889 theContentPane.add(panel43); 4890 c2TToTSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 4891 4892 JPanel panel44 = new JPanel(new FlowLayout()); 4893 panel44.add(new JLabel(" ")); 4894 panel44.add(setC2TToTHead); 4895 setC2TToTHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 4896 panel44.add(new JLabel(" ")); 4897 panel44.add(setupC2TToTLogic); 4898 setupC2TToTLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 4899 theContentPane.add(panel44); 4900 4901 JPanel panel51x = new JPanel(new FlowLayout()); 4902 panel51x.add(new JLabel(Bundle.getMessage("SignalLocated") 4903 + " " + Bundle.getMessage("BeanNameTurnout") + " 2 - " 4904 + Bundle.getMessage("DivergingTrack"))); 4905 theContentPane.add(panel51x); 4906 4907 JPanel panel51 = new JPanel(new FlowLayout()); 4908 panel51.add(new JLabel(Bundle.getMessage("MakeLabel", 4909 Bundle.getMessage("ProtectsTurnout") + " 1 - " 4910 + Bundle.getMessage("ContinuingTrack")))); 4911 panel51.add(d1TToTSignalHeadComboBox); 4912 theContentPane.add(panel51); 4913 d1TToTSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 4914 4915 JPanel panel52 = new JPanel(new FlowLayout()); 4916 panel52.add(new JLabel(Bundle.getMessage("OrBoth") + " 1 " + Bundle.getMessage("Tracks)") + " ")); 4917 panel52.add(setD1TToTHead); 4918 setD1TToTHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 4919 panel52.add(new JLabel(" ")); 4920 panel52.add(setupD1TToTLogic); 4921 setupD1TToTLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 4922 theContentPane.add(panel52); 4923 4924 JPanel panel53 = new JPanel(new FlowLayout()); 4925 panel53.add(new JLabel(Bundle.getMessage("MakeLabel", 4926 Bundle.getMessage("ProtectsTurnout") + " 1 - " 4927 + Bundle.getMessage("DivergingTrack")))); 4928 panel53.add(d2TToTSignalHeadComboBox); 4929 theContentPane.add(panel53); 4930 d2TToTSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 4931 4932 JPanel panel54 = new JPanel(new FlowLayout()); 4933 panel54.add(new JLabel(" ")); 4934 panel54.add(setD2TToTHead); 4935 setD2TToTHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 4936 panel54.add(new JLabel(" ")); 4937 panel54.add(setupD2TToTLogic); 4938 setupD2TToTLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 4939 theContentPane.add(panel54); 4940 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 4941 4942 JPanel panel6 = new JPanel(new FlowLayout()); 4943 panel6.add(changeTToTSignalIcon = new JButton(Bundle.getMessage("ChangeSignalIcon"))); 4944 changeTToTSignalIcon.addActionListener((ActionEvent e) -> signalFrame.setVisible(true)); 4945 changeTToTSignalIcon.setToolTipText(Bundle.getMessage("ChangeSignalIconHint")); 4946 panel6.add(new JLabel(" ")); 4947 panel6.add(setTToTSignalsDone = new JButton(Bundle.getMessage("ButtonDone"))); 4948 setTToTSignalsDone.addActionListener(this::setTToTSignalsDonePressed); 4949 setTToTSignalsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 4950 4951 panel6.add(setTToTSignalsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 4952 setTToTSignalsCancel.addActionListener(this::setTToTSignalsCancelPressed); 4953 setTToTSignalsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 4954 theContentPane.add(panel6); 4955 4956 //make this button the default button (return or enter activates) 4957 JRootPane rootPane = SwingUtilities.getRootPane(setTToTSignalsDone); 4958 if (rootPane != null) { 4959 rootPane.setDefaultButton(setTToTSignalsDone); 4960 } 4961 4962 setSignalsAtThroatToThroatTurnoutsFrame.addWindowListener(new WindowAdapter() { 4963 @Override 4964 public void windowClosing(WindowEvent e) { 4965 setTToTSignalsCancelPressed(null); 4966 } 4967 }); 4968 } 4969 setPlaceAllHeads.setSelected(false); 4970 setupAllLogic.setSelected(false); 4971 4972 turnout1ComboBox.setVisible(!setSignalsAtThroatToThroatTurnoutsFromMenuFlag); 4973 turnout2ComboBox.setVisible(!setSignalsAtThroatToThroatTurnoutsFromMenuFlag); 4974 4975 if (setSignalsAtThroatToThroatTurnoutsFromMenuFlag) { 4976 ttotTurnoutName1Label.setText(Bundle.getMessage("MakeLabel", 4977 Bundle.getMessage("BeanNameTurnout") + " 1 " 4978 + Bundle.getMessage("Name")) + ttotTurnoutName1); 4979 ttotTurnoutName2Label.setText(Bundle.getMessage("MakeLabel", 4980 Bundle.getMessage("BeanNameTurnout") + " 2 " 4981 + Bundle.getMessage("Name")) + ttotTurnoutName2); 4982 4983 SwingUtilities.invokeLater(() -> setSignalsAtTToTTurnoutsGetSaved(null)); 4984 } else { 4985 ttotTurnoutName1Label.setText( 4986 Bundle.getMessage("BeanNameTurnout") + " 1 " 4987 + Bundle.getMessage("Name")); 4988 ttotTurnoutName2Label.setText( 4989 Bundle.getMessage("BeanNameTurnout") + " 2 " 4990 + Bundle.getMessage("Name")); 4991 } 4992 4993 if (!setSignalsAtThroatToThroatTurnoutsOpenFlag) { 4994 setSignalsAtThroatToThroatTurnoutsFrame.setPreferredSize(null); 4995 setSignalsAtThroatToThroatTurnoutsFrame.pack(); 4996 setSignalsAtThroatToThroatTurnoutsOpenFlag = true; 4997 } 4998 setSignalsAtThroatToThroatTurnoutsFrame.setVisible(true); 4999 } //setSignalsAtTToTTurnouts 5000 5001 private void setSignalsAtTToTTurnoutsGetSaved(ActionEvent a) { 5002 if (!getTToTTurnoutInformation()) { 5003 return; 5004 } 5005 a1TToTSignalHeadComboBox.setSelectedItem(layoutTurnout1.getSignalB1()); 5006 a2TToTSignalHeadComboBox.setSelectedItem(layoutTurnout1.getSignalB2()); 5007 b1TToTSignalHeadComboBox.setSelectedItem(layoutTurnout1.getSignalC1()); 5008 b2TToTSignalHeadComboBox.setSelectedItem(layoutTurnout1.getSignalC2()); 5009 c1TToTSignalHeadComboBox.setSelectedItem(layoutTurnout2.getSignalB1()); 5010 c2TToTSignalHeadComboBox.setSelectedItem(layoutTurnout2.getSignalB2()); 5011 d1TToTSignalHeadComboBox.setSelectedItem(layoutTurnout2.getSignalC1()); 5012 d2TToTSignalHeadComboBox.setSelectedItem(layoutTurnout2.getSignalC2()); 5013 } 5014 5015 private void setTToTSignalsCancelPressed(ActionEvent a) { 5016 setSignalsAtThroatToThroatTurnoutsOpenFlag = false; 5017 setSignalsAtThroatToThroatTurnoutsFrame.setVisible(false); 5018 } 5019 5020 private boolean getTToTTurnoutInformation() { 5021 HitPointType type = HitPointType.NONE; 5022 Object connect = null; 5023 5024 turnout1 = null; 5025 turnout2 = null; 5026 5027 layoutTurnout1 = null; 5028 layoutTurnout2 = null; 5029 5030 if (!setSignalsAtThroatToThroatTurnoutsFromMenuFlag) { 5031 ttotTurnoutName1 = turnout1ComboBox.getSelectedItemDisplayName(); 5032 if (ttotTurnoutName1 == null) { 5033 ttotTurnoutName1 = ""; 5034 } 5035 } 5036 if (ttotTurnoutName1.isEmpty()) { 5037 //turnout 1 not entered, test turnout 2 5038 ttotTurnoutName2 = turnout2ComboBox.getSelectedItemDisplayName(); 5039 if (ttotTurnoutName2 == null) { 5040 ttotTurnoutName2 = ""; 5041 } 5042 if (ttotTurnoutName2.isEmpty()) { 5043 //no entries in turnout fields 5044 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5045 Bundle.getMessage("SignalsError1"), 5046 Bundle.getMessage("ErrorTitle"), 5047 JmriJOptionPane.ERROR_MESSAGE); 5048 return false; 5049 } 5050 turnout2 = InstanceManager.turnoutManagerInstance().getTurnout(ttotTurnoutName2); 5051 if (turnout2 == null) { 5052 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5053 Bundle.getMessage("SignalsError2", 5054 new Object[]{ttotTurnoutName2}), Bundle.getMessage("ErrorTitle"), 5055 JmriJOptionPane.ERROR_MESSAGE); 5056 return false; 5057 } 5058 String uname = turnout2.getUserName(); 5059 if ((uname == null) || uname.isEmpty() 5060 || !uname.equals(ttotTurnoutName2)) { 5061 turnout2ComboBox.setSelectedItem(turnout2); 5062 } 5063 layoutTurnout2 = getLayoutTurnoutFromTurnout(turnout2, false, ttotTurnoutName2, setSignalsAtThroatToThroatTurnoutsFrame); 5064 if (layoutTurnout2 == null) { 5065 return false; 5066 } 5067 //have turnout 2 and layout turnout 2 - look for turnout 1 5068 connectorTrack = (TrackSegment) layoutTurnout2.getConnectA(); 5069 if (connectorTrack == null) { 5070 //Inform user of error, and terminate 5071 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5072 Bundle.getMessage("SignalsError18"), 5073 Bundle.getMessage("ErrorTitle"), 5074 JmriJOptionPane.ERROR_MESSAGE); 5075 return false; 5076 } 5077 type = connectorTrack.getType1(); 5078 connect = connectorTrack.getConnect1(); 5079 if (connect == layoutTurnout2) { 5080 type = connectorTrack.getType2(); 5081 connect = connectorTrack.getConnect2(); 5082 } 5083 if ((type != HitPointType.TURNOUT_A) || (connect == null)) { 5084 //Not two turnouts connected throat-to-throat by a single Track Segment 5085 //Inform user of error and terminate 5086 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5087 Bundle.getMessage("SignalsError18"), 5088 Bundle.getMessage("ErrorTitle"), 5089 JmriJOptionPane.ERROR_MESSAGE); 5090 return false; 5091 } 5092 layoutTurnout1 = (LayoutTurnout) connect; 5093 turnout1 = layoutTurnout1.getTurnout(); 5094 if (turnout1 == null) { 5095 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5096 Bundle.getMessage("SignalsError18"), 5097 Bundle.getMessage("ErrorTitle"), 5098 JmriJOptionPane.ERROR_MESSAGE); 5099 return false; 5100 } 5101 turnout1ComboBox.setSelectedItem(turnout1); 5102 } else { 5103 //something was entered in the turnout 1 field 5104 turnout1 = InstanceManager.turnoutManagerInstance().getTurnout(ttotTurnoutName1); 5105 if (turnout1 == null) { 5106 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5107 Bundle.getMessage("SignalsError2", 5108 new Object[]{ttotTurnoutName1}), Bundle.getMessage("ErrorTitle"), 5109 JmriJOptionPane.ERROR_MESSAGE); 5110 return false; 5111 } 5112 String uname = turnout1.getUserName(); 5113 if ((uname == null) || uname.isEmpty() || !uname.equals(ttotTurnoutName1)) { 5114 turnout1ComboBox.setSelectedItem(turnout1); 5115 } 5116 //have turnout 1 - get corresponding layoutTurnout 5117 layoutTurnout1 = getLayoutTurnoutFromTurnout(turnout1, false, ttotTurnoutName1, setSignalsAtThroatToThroatTurnoutsFrame); 5118 if (layoutTurnout1 == null) { 5119 return false; 5120 } 5121 turnout1ComboBox.setSelectedItem(layoutTurnout1.getTurnout()); 5122 //have turnout 1 and layout turnout 1 - was something entered for turnout 2 5123 ttotTurnoutName2 = turnout2ComboBox.getSelectedItemDisplayName(); 5124 if (ttotTurnoutName2 == null) { 5125 ttotTurnoutName2 = ""; 5126 } 5127 if (ttotTurnoutName2.isEmpty()) { 5128 //no entry for turnout 2 5129 connectorTrack = (TrackSegment) layoutTurnout1.getConnectA(); 5130 if (connectorTrack == null) { 5131 //Inform user of error, and terminate 5132 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5133 Bundle.getMessage("SignalsError18"), 5134 Bundle.getMessage("ErrorTitle"), 5135 JmriJOptionPane.ERROR_MESSAGE); 5136 return false; 5137 } 5138 type = connectorTrack.getType1(); 5139 connect = connectorTrack.getConnect1(); 5140 if (connect == layoutTurnout1) { 5141 type = connectorTrack.getType2(); 5142 connect = connectorTrack.getConnect2(); 5143 } 5144 if ((type != HitPointType.TURNOUT_A) || (connect == null)) { 5145 //Not two turnouts connected throat-to-throat by a single Track Segment 5146 //Inform user of error and terminate 5147 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5148 Bundle.getMessage("SignalsError18"), 5149 Bundle.getMessage("ErrorTitle"), 5150 JmriJOptionPane.ERROR_MESSAGE); 5151 return false; 5152 } 5153 layoutTurnout2 = (LayoutTurnout) connect; 5154 turnout2 = layoutTurnout2.getTurnout(); 5155 if (turnout2 == null) { 5156 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5157 Bundle.getMessage("SignalsError18"), 5158 Bundle.getMessage("ErrorTitle"), 5159 JmriJOptionPane.ERROR_MESSAGE); 5160 return false; 5161 } 5162 turnout2ComboBox.setSelectedItem(turnout2); 5163 } else { 5164 //turnout 2 entered also 5165 turnout2 = InstanceManager.turnoutManagerInstance().getTurnout(ttotTurnoutName2); 5166 if (turnout2 == null) { 5167 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5168 Bundle.getMessage("SignalsError2", 5169 new Object[]{ttotTurnoutName2}), Bundle.getMessage("ErrorTitle"), 5170 JmriJOptionPane.ERROR_MESSAGE); 5171 return false; 5172 } 5173 uname = turnout2.getUserName(); 5174 if ((uname == null) || uname.isEmpty() || !uname.equals(ttotTurnoutName2)) { 5175 turnout2ComboBox.setSelectedItem(turnout2); 5176 } 5177 layoutTurnout2 = getLayoutTurnoutFromTurnout(turnout2, false, ttotTurnoutName2, setSignalsAtThroatToThroatTurnoutsFrame); 5178 if (layoutTurnout2 == null) { 5179 return false; 5180 } 5181 turnout2ComboBox.setSelectedItem(layoutTurnout2.getTurnout()); 5182 //check that layout turnout 1 and layout turnout 2 are connected throat-to-throat 5183 if (layoutTurnout1.getConnectA() != layoutTurnout2.getConnectA()) { 5184 //Not two turnouts connected throat-to-throat by a single Track Segment 5185 //Inform user of error and terminate 5186 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5187 Bundle.getMessage("SignalsError18"), 5188 Bundle.getMessage("ErrorTitle"), 5189 JmriJOptionPane.ERROR_MESSAGE); 5190 return false; 5191 } 5192 connectorTrack = (TrackSegment) layoutTurnout1.getConnectA(); 5193 } 5194 } 5195 //have both turnouts, correctly connected - complete initialization 5196 LayoutTurnoutView layoutTurnout1View = layoutEditor.getLayoutTurnoutView(layoutTurnout1); 5197 Point2D coordsA = layoutTurnout1View.getCoordsA(); 5198 Point2D coordsCenter = layoutTurnout1View.getCoordsCenter(); 5199 placeSignalDirectionDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsCenter, coordsA)); 5200 return true; 5201 } //getTToTTurnoutInformation 5202 5203 private void setTToTSignalsDonePressed(ActionEvent a) { 5204 if (!getTToTTurnoutInformation()) { 5205 return; 5206 } 5207 if (!getTToTSignalHeadInformation()) { 5208 return; 5209 } 5210 5211 //place signal icons if requested, and assign signal heads to this turnout 5212 String signalHeadName = a1TToTSignalHeadComboBox.getSelectedItemDisplayName(); 5213 if (signalHeadName == null) { 5214 signalHeadName = ""; 5215 } 5216 if (setA1TToTHead.isSelected()) { 5217 if (isHeadOnPanel(a1TToTHead) 5218 && (a1TToTHead != getHeadFromName(layoutTurnout1.getSignalB1Name()))) { 5219 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5220 Bundle.getMessage("SignalsError6", 5221 new Object[]{signalHeadName}), 5222 Bundle.getMessage("ErrorTitle"), 5223 JmriJOptionPane.ERROR_MESSAGE); 5224 return; 5225 } else { 5226 removeSignalHeadFromPanel(layoutTurnout1.getSignalB1Name()); 5227 if (layoutTurnout1.getContinuingSense() == Turnout.CLOSED) { 5228 placeA1TToT(signalHeadName); 5229 } else { 5230 placeB1TToT(signalHeadName); 5231 } 5232 removeAssignment(a1TToTHead); 5233 layoutTurnout1.setSignalB1Name(signalHeadName); 5234 needRedraw = true; 5235 } 5236 } else { 5237 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a1TToTHead, layoutTurnout1); 5238 if (assigned == LayoutTurnout.Geometry.NONE) { 5239 if (isHeadOnPanel(a1TToTHead) 5240 && isHeadAssignedAnywhere(a1TToTHead)) { 5241 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5242 Bundle.getMessage("SignalsError8", 5243 new Object[]{signalHeadName}), 5244 Bundle.getMessage("ErrorTitle"), 5245 JmriJOptionPane.ERROR_MESSAGE); 5246 return; 5247 } else { 5248 removeSignalHeadFromPanel(layoutTurnout1.getSignalB1Name()); 5249 removeAssignment(a1TToTHead); 5250 layoutTurnout1.setSignalB1Name(signalHeadName); 5251 } 5252 //} else if (assigned != B1) { 5253 //need to figure out what to do in this case - assigned to a different position on the same turnout. 5254 } 5255 } 5256 5257 signalHeadName = a2TToTSignalHeadComboBox.getSelectedItemDisplayName(); 5258 if (signalHeadName == null) { 5259 signalHeadName = ""; 5260 } 5261 if ((a2TToTHead != null) && setA2TToTHead.isSelected()) { 5262 if (isHeadOnPanel(a2TToTHead) 5263 && (a2TToTHead != getHeadFromName(layoutTurnout1.getSignalB2Name()))) { 5264 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5265 Bundle.getMessage("SignalsError6", 5266 new Object[]{signalHeadName}), 5267 Bundle.getMessage("ErrorTitle"), 5268 JmriJOptionPane.ERROR_MESSAGE); 5269 return; 5270 } else { 5271 removeSignalHeadFromPanel(layoutTurnout1.getSignalB2Name()); 5272 if (layoutTurnout1.getContinuingSense() == Turnout.CLOSED) { 5273 placeA2TToT(signalHeadName); 5274 } else { 5275 placeB2TToT(signalHeadName); 5276 } 5277 removeAssignment(a2TToTHead); 5278 layoutTurnout1.setSignalB2Name(signalHeadName); 5279 needRedraw = true; 5280 } 5281 } else if (a2TToTHead != null) { 5282 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a2TToTHead, layoutTurnout1); 5283 if (assigned == LayoutTurnout.Geometry.NONE) { 5284 if (isHeadOnPanel(a2TToTHead) 5285 && isHeadAssignedAnywhere(a2TToTHead)) { 5286 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5287 Bundle.getMessage("SignalsError8", 5288 new Object[]{signalHeadName}), 5289 Bundle.getMessage("ErrorTitle"), 5290 JmriJOptionPane.ERROR_MESSAGE); 5291 return; 5292 } else { 5293 removeSignalHeadFromPanel(layoutTurnout1.getSignalB2Name()); 5294 removeAssignment(a2TToTHead); 5295 layoutTurnout1.setSignalB2Name(signalHeadName); 5296 } 5297 //} else if (assigned != B2) { 5298 //need to figure out what to do in this case. 5299 } 5300 } else { //a2TToTHead known to be null here 5301 removeSignalHeadFromPanel(layoutTurnout1.getSignalB2Name()); 5302 layoutTurnout1.setSignalB2Name(""); 5303 } 5304 5305 signalHeadName = b1TToTSignalHeadComboBox.getSelectedItemDisplayName(); 5306 if (signalHeadName == null) { 5307 signalHeadName = ""; 5308 } 5309 if (setB1TToTHead.isSelected()) { 5310 if (isHeadOnPanel(b1TToTHead) 5311 && (b1TToTHead != getHeadFromName(layoutTurnout1.getSignalC1Name()))) { 5312 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5313 Bundle.getMessage("SignalsError6", 5314 new Object[]{signalHeadName}), 5315 Bundle.getMessage("ErrorTitle"), 5316 JmriJOptionPane.ERROR_MESSAGE); 5317 return; 5318 } else { 5319 removeSignalHeadFromPanel(layoutTurnout1.getSignalC1Name()); 5320 if (layoutTurnout1.getContinuingSense() == Turnout.CLOSED) { 5321 placeB1TToT(signalHeadName); 5322 } else { 5323 placeA1TToT(signalHeadName); 5324 } 5325 removeAssignment(b1TToTHead); 5326 layoutTurnout1.setSignalC1Name(signalHeadName); 5327 needRedraw = true; 5328 } 5329 } else { 5330 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b1TToTHead, layoutTurnout1); 5331 if (assigned == LayoutTurnout.Geometry.NONE) { 5332 if (isHeadOnPanel(b1TToTHead) 5333 && isHeadAssignedAnywhere(b1TToTHead)) { 5334 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5335 Bundle.getMessage("SignalsError8", 5336 new Object[]{signalHeadName}), 5337 Bundle.getMessage("ErrorTitle"), 5338 JmriJOptionPane.ERROR_MESSAGE); 5339 return; 5340 } else { 5341 removeSignalHeadFromPanel(layoutTurnout1.getSignalC1Name()); 5342 removeAssignment(b1TToTHead); 5343 layoutTurnout1.setSignalC1Name(signalHeadName); 5344 } 5345 //} else if (assigned != C1) { 5346 //need to figure out what to do in this case. 5347 } 5348 } 5349 5350 signalHeadName = b2TToTSignalHeadComboBox.getSelectedItemDisplayName(); 5351 if (signalHeadName == null) { 5352 signalHeadName = ""; 5353 } 5354 if ((b2TToTHead != null) && setB2TToTHead.isSelected()) { 5355 if (isHeadOnPanel(b2TToTHead) 5356 && (b2TToTHead != getHeadFromName(layoutTurnout1.getSignalC2Name()))) { 5357 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5358 Bundle.getMessage("SignalsError6", 5359 new Object[]{signalHeadName}), 5360 Bundle.getMessage("ErrorTitle"), 5361 JmriJOptionPane.ERROR_MESSAGE); 5362 return; 5363 } else { 5364 removeSignalHeadFromPanel(layoutTurnout1.getSignalC2Name()); 5365 if (layoutTurnout1.getContinuingSense() == Turnout.CLOSED) { 5366 placeB2TToT(signalHeadName); 5367 } else { 5368 placeA2TToT(signalHeadName); 5369 } 5370 removeAssignment(b2TToTHead); 5371 layoutTurnout1.setSignalC2Name(signalHeadName); 5372 needRedraw = true; 5373 } 5374 } else if (b2TToTHead != null) { 5375 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b2TToTHead, layoutTurnout1); 5376 if (assigned == LayoutTurnout.Geometry.NONE) { 5377 if (isHeadOnPanel(b2TToTHead) 5378 && isHeadAssignedAnywhere(b2TToTHead)) { 5379 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5380 Bundle.getMessage("SignalsError8", 5381 new Object[]{signalHeadName}), 5382 Bundle.getMessage("ErrorTitle"), 5383 JmriJOptionPane.ERROR_MESSAGE); 5384 return; 5385 } else { 5386 removeSignalHeadFromPanel(layoutTurnout1.getSignalC2Name()); 5387 removeAssignment(b2TToTHead); 5388 layoutTurnout1.setSignalC2Name(signalHeadName); 5389 } 5390 //} else if (assigned != C2) { 5391 //need to figure out what to do in this case. 5392 } 5393 } else { //b2TToTHead known to be null here 5394 removeSignalHeadFromPanel(layoutTurnout1.getSignalC2Name()); 5395 layoutTurnout1.setSignalC2Name(""); 5396 } 5397 5398 //signal heads on turnout 2 5399 signalHeadName = c1TToTSignalHeadComboBox.getSelectedItemDisplayName(); 5400 if (signalHeadName == null) { 5401 signalHeadName = ""; 5402 } 5403 if (setC1TToTHead.isSelected()) { 5404 if (isHeadOnPanel(c1TToTHead) 5405 && (c1TToTHead != getHeadFromName(layoutTurnout2.getSignalB1Name()))) { 5406 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5407 Bundle.getMessage("SignalsError6", 5408 new Object[]{signalHeadName}), 5409 Bundle.getMessage("ErrorTitle"), 5410 JmriJOptionPane.ERROR_MESSAGE); 5411 return; 5412 } else { 5413 removeSignalHeadFromPanel(layoutTurnout2.getSignalB1Name()); 5414 if (layoutTurnout2.getContinuingSense() == Turnout.CLOSED) { 5415 placeC1TToT(signalHeadName); 5416 } else { 5417 placeD1TToT(signalHeadName); 5418 } 5419 removeAssignment(c1TToTHead); 5420 layoutTurnout2.setSignalB1Name(signalHeadName); 5421 needRedraw = true; 5422 } 5423 } else { 5424 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c1TToTHead, layoutTurnout2); 5425 if (assigned == LayoutTurnout.Geometry.NONE) { 5426 if (isHeadOnPanel(c1TToTHead) 5427 && isHeadAssignedAnywhere(c1TToTHead)) { 5428 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5429 Bundle.getMessage("SignalsError8", 5430 new Object[]{signalHeadName}), 5431 Bundle.getMessage("ErrorTitle"), 5432 JmriJOptionPane.ERROR_MESSAGE); 5433 return; 5434 } else { 5435 removeSignalHeadFromPanel(layoutTurnout2.getSignalB1Name()); 5436 removeAssignment(c1TToTHead); 5437 layoutTurnout2.setSignalB1Name(signalHeadName); 5438 } 5439 //} else if (assigned != B1) { 5440 //need to figure out what to do in this case. 5441 } 5442 } 5443 5444 signalHeadName = c2TToTSignalHeadComboBox.getSelectedItemDisplayName(); 5445 if (signalHeadName == null) { 5446 signalHeadName = ""; 5447 } 5448 if ((c2TToTHead != null) && setC2TToTHead.isSelected()) { 5449 if (isHeadOnPanel(c2TToTHead) 5450 && (c2TToTHead != getHeadFromName(layoutTurnout2.getSignalB2Name()))) { 5451 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5452 Bundle.getMessage("SignalsError6", 5453 new Object[]{signalHeadName}), 5454 Bundle.getMessage("ErrorTitle"), 5455 JmriJOptionPane.ERROR_MESSAGE); 5456 return; 5457 } else { 5458 removeSignalHeadFromPanel(layoutTurnout2.getSignalB2Name()); 5459 if (layoutTurnout2.getContinuingSense() == Turnout.CLOSED) { 5460 placeC2TToT(signalHeadName); 5461 } else { 5462 placeD2TToT(signalHeadName); 5463 } 5464 removeAssignment(c2TToTHead); 5465 layoutTurnout2.setSignalB2Name(signalHeadName); 5466 needRedraw = true; 5467 } 5468 } else if (c2TToTHead != null) { 5469 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c2TToTHead, layoutTurnout2); 5470 if (assigned == LayoutTurnout.Geometry.NONE) { 5471 if (isHeadOnPanel(c2TToTHead) 5472 && isHeadAssignedAnywhere(c2TToTHead)) { 5473 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5474 Bundle.getMessage("SignalsError8", 5475 new Object[]{signalHeadName}), 5476 Bundle.getMessage("ErrorTitle"), 5477 JmriJOptionPane.ERROR_MESSAGE); 5478 return; 5479 } else { 5480 removeSignalHeadFromPanel(layoutTurnout2.getSignalB2Name()); 5481 removeAssignment(c2TToTHead); 5482 layoutTurnout2.setSignalB2Name(signalHeadName); 5483 } 5484 //} else if (assigned != B2) { 5485 //need to figure out what to do in this case. 5486 } 5487 } else { //c2TToTHead known to be null here 5488 removeSignalHeadFromPanel(layoutTurnout2.getSignalB2Name()); 5489 layoutTurnout2.setSignalB2Name(""); 5490 } 5491 5492 signalHeadName = d1TToTSignalHeadComboBox.getSelectedItemDisplayName(); 5493 if (signalHeadName == null) { 5494 signalHeadName = ""; 5495 } 5496 if (setD1TToTHead.isSelected()) { 5497 if (isHeadOnPanel(d1TToTHead) 5498 && (d1TToTHead != getHeadFromName(layoutTurnout2.getSignalC1Name()))) { 5499 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5500 Bundle.getMessage("SignalsError6", 5501 new Object[]{signalHeadName}), 5502 Bundle.getMessage("ErrorTitle"), 5503 JmriJOptionPane.ERROR_MESSAGE); 5504 return; 5505 } else { 5506 removeSignalHeadFromPanel(layoutTurnout2.getSignalC1Name()); 5507 if (layoutTurnout2.getContinuingSense() == Turnout.CLOSED) { 5508 placeD1TToT(signalHeadName); 5509 } else { 5510 placeC1TToT(signalHeadName); 5511 } 5512 removeAssignment(d1TToTHead); 5513 layoutTurnout2.setSignalC1Name(signalHeadName); 5514 needRedraw = true; 5515 } 5516 } else { 5517 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d1TToTHead, layoutTurnout2); 5518 if (assigned == LayoutTurnout.Geometry.NONE) { 5519 if (isHeadOnPanel(d1TToTHead) 5520 && isHeadAssignedAnywhere(d1TToTHead)) { 5521 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5522 Bundle.getMessage("SignalsError8", 5523 new Object[]{signalHeadName}), 5524 Bundle.getMessage("ErrorTitle"), 5525 JmriJOptionPane.ERROR_MESSAGE); 5526 return; 5527 } else { 5528 removeSignalHeadFromPanel(layoutTurnout2.getSignalC1Name()); 5529 removeAssignment(d1TToTHead); 5530 layoutTurnout2.setSignalC1Name(signalHeadName); 5531 } 5532 //} else if (assigned != C1) { 5533 //need to figure out what to do in this case. 5534 } 5535 } 5536 5537 signalHeadName = d2TToTSignalHeadComboBox.getSelectedItemDisplayName(); 5538 if (signalHeadName == null) { 5539 signalHeadName = ""; 5540 } 5541 if ((d2TToTHead != null) && setD2TToTHead.isSelected()) { 5542 if (isHeadOnPanel(d2TToTHead) 5543 && (d2TToTHead != getHeadFromName(layoutTurnout2.getSignalC2Name()))) { 5544 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5545 Bundle.getMessage("SignalsError6", 5546 new Object[]{signalHeadName}), 5547 Bundle.getMessage("ErrorTitle"), 5548 JmriJOptionPane.ERROR_MESSAGE); 5549 return; 5550 } else { 5551 removeSignalHeadFromPanel(layoutTurnout2.getSignalC2Name()); 5552 if (layoutTurnout2.getContinuingSense() == Turnout.CLOSED) { 5553 placeD2TToT(signalHeadName); 5554 } else { 5555 placeC2TToT(signalHeadName); 5556 } 5557 removeAssignment(d2TToTHead); 5558 layoutTurnout2.setSignalC2Name(signalHeadName); 5559 needRedraw = true; 5560 } 5561 } else if (d2TToTHead != null) { 5562 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d2TToTHead, layoutTurnout2); 5563 if (assigned == LayoutTurnout.Geometry.NONE) { 5564 if (isHeadOnPanel(d2TToTHead) 5565 && isHeadAssignedAnywhere(d2TToTHead)) { 5566 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5567 Bundle.getMessage("SignalsError8", 5568 new Object[]{signalHeadName}), 5569 Bundle.getMessage("ErrorTitle"), 5570 JmriJOptionPane.ERROR_MESSAGE); 5571 return; 5572 } else { 5573 removeSignalHeadFromPanel(layoutTurnout2.getSignalC2Name()); 5574 removeAssignment(d2TToTHead); 5575 layoutTurnout2.setSignalC2Name(signalHeadName); 5576 } 5577 //} else if (assigned != C2) { 5578 //need to figure out what to do in this case. 5579 } 5580 } else { //d2TToTHead known to be null here 5581 removeSignalHeadFromPanel(layoutTurnout2.getSignalC2Name()); 5582 layoutTurnout2.setSignalC2Name(""); 5583 } 5584 5585 //setup logic if requested 5586 if (setupA1TToTLogic.isSelected() || setupA2TToTLogic.isSelected()) { 5587 setLogicTToT(a1TToTHead, (TrackSegment) layoutTurnout2.getConnectB(), a2TToTHead, 5588 (TrackSegment) layoutTurnout2.getConnectC(), setupA1TToTLogic.isSelected(), 5589 setupA2TToTLogic.isSelected(), true, layoutTurnout2, layoutTurnout1); 5590 } 5591 if (setupB1TToTLogic.isSelected() || setupB2TToTLogic.isSelected()) { 5592 setLogicTToT(b1TToTHead, (TrackSegment) layoutTurnout2.getConnectB(), b2TToTHead, 5593 (TrackSegment) layoutTurnout2.getConnectC(), setupB1TToTLogic.isSelected(), 5594 setupB2TToTLogic.isSelected(), false, layoutTurnout2, layoutTurnout1); 5595 } 5596 if (setupC1TToTLogic.isSelected() || setupC2TToTLogic.isSelected()) { 5597 setLogicTToT(c1TToTHead, (TrackSegment) layoutTurnout1.getConnectB(), c2TToTHead, 5598 (TrackSegment) layoutTurnout1.getConnectC(), setupC1TToTLogic.isSelected(), 5599 setupC2TToTLogic.isSelected(), true, layoutTurnout1, layoutTurnout2); 5600 } 5601 if (setupD1TToTLogic.isSelected() || setupD2TToTLogic.isSelected()) { 5602 setLogicTToT(d1TToTHead, (TrackSegment) layoutTurnout1.getConnectB(), d2TToTHead, 5603 (TrackSegment) layoutTurnout1.getConnectC(), setupD1TToTLogic.isSelected(), 5604 setupD2TToTLogic.isSelected(), false, layoutTurnout1, layoutTurnout2); 5605 } 5606 //link the two turnouts 5607 layoutTurnout1.setLinkedTurnoutName(turnout2ComboBox.getSelectedItemDisplayName()); 5608 layoutTurnout1.setLinkType(LayoutTurnout.LinkType.THROAT_TO_THROAT); 5609 layoutTurnout2.setLinkedTurnoutName(turnout1ComboBox.getSelectedItemDisplayName()); 5610 layoutTurnout2.setLinkType(LayoutTurnout.LinkType.THROAT_TO_THROAT); 5611 //finish up 5612 setSignalsAtThroatToThroatTurnoutsOpenFlag = false; 5613 setSignalsAtThroatToThroatTurnoutsFrame.setVisible(false); 5614 if (needRedraw) { 5615 layoutEditor.redrawPanel(); 5616 needRedraw = false; 5617 layoutEditor.setDirty(); 5618 } 5619 } //setTToTSignalsDonePressed 5620 5621 private boolean getTToTSignalHeadInformation() { 5622 a1TToTHead = getSignalHeadFromEntry(a1TToTSignalHeadComboBox, true, setSignalsAtThroatToThroatTurnoutsFrame); 5623 if (a1TToTHead == null) { 5624 return false; 5625 } 5626 a2TToTHead = getSignalHeadFromEntry(a2TToTSignalHeadComboBox, false, setSignalsAtThroatToThroatTurnoutsFrame); 5627 b1TToTHead = getSignalHeadFromEntry(b1TToTSignalHeadComboBox, true, setSignalsAtThroatToThroatTurnoutsFrame); 5628 if (b1TToTHead == null) { 5629 return false; 5630 } 5631 b2TToTHead = getSignalHeadFromEntry(b2TToTSignalHeadComboBox, false, setSignalsAtThroatToThroatTurnoutsFrame); 5632 c1TToTHead = getSignalHeadFromEntry(c1TToTSignalHeadComboBox, true, setSignalsAtThroatToThroatTurnoutsFrame); 5633 if (c1TToTHead == null) { 5634 return false; 5635 } 5636 c2TToTHead = getSignalHeadFromEntry(c2TToTSignalHeadComboBox, false, setSignalsAtThroatToThroatTurnoutsFrame); 5637 d1TToTHead = getSignalHeadFromEntry(d1TToTSignalHeadComboBox, true, setSignalsAtThroatToThroatTurnoutsFrame); 5638 if (d1TToTHead == null) { 5639 return false; 5640 } 5641 d2TToTHead = getSignalHeadFromEntry(d2TToTSignalHeadComboBox, false, setSignalsAtThroatToThroatTurnoutsFrame); 5642 return true; 5643 } 5644 5645 private void placeA1TToT(String signalHeadName) { 5646 //place head near the continuing track of turnout 1 5647 if (testIcon == null) { 5648 testIcon = signalIconEditor.getIcon(0); 5649 } 5650 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 5651 5652 LayoutTurnoutView layoutTurnout1View = layoutEditor.getLayoutTurnoutView(layoutTurnout1); 5653 Point2D coordsB = layoutTurnout1View.getCoordsB(); 5654 Point2D coordsCenter = layoutTurnout1View.getCoordsCenter(); 5655 5656 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 5657 Point2D delta = new Point2D.Double(0.0, -shift); 5658 5659 delta = MathUtil.rotateDEG(delta, bDirDEG); 5660 Point2D where = MathUtil.add(coordsB, delta); 5661 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 5662 } 5663 5664 private void placeA2TToT(String signalHeadName) { 5665 if (testIcon == null) { 5666 testIcon = signalIconEditor.getIcon(0); 5667 } 5668 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 5669 5670 LayoutTurnoutView layoutTurnout1View = layoutEditor.getLayoutTurnoutView(layoutTurnout1); 5671 Point2D coordsB = layoutTurnout1View.getCoordsB(); 5672 Point2D coordsCenter = layoutTurnout1View.getCoordsCenter(); 5673 5674 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 5675 Point2D delta = new Point2D.Double(2.0 * shift, -shift); 5676 5677 delta = MathUtil.rotateDEG(delta, bDirDEG); 5678 Point2D where = MathUtil.add(coordsB, delta); 5679 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 5680 } 5681 5682 private void placeB1TToT(String signalHeadName) { 5683 if (testIcon == null) { 5684 testIcon = signalIconEditor.getIcon(0); 5685 } 5686 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 5687 5688 LayoutTurnoutView layoutTurnout1View = layoutEditor.getLayoutTurnoutView(layoutTurnout1); 5689 Point2D coordsB = layoutTurnout1View.getCoordsB(); 5690 Point2D coordsC = layoutTurnout1View.getCoordsC(); 5691 Point2D coordsCenter = layoutTurnout1View.getCoordsCenter(); 5692 5693 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 5694 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 5695 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 5696 double shiftX = 0.0; 5697 if (diffDirDEG >= 0.0) { 5698 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 5699 } 5700 Point2D delta = new Point2D.Double(shiftX, -shift); 5701 5702 delta = MathUtil.rotateDEG(delta, cDirDEG); 5703 Point2D where = MathUtil.add(coordsC, delta); 5704 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 5705 } 5706 5707 private void placeB2TToT(String signalHeadName) { 5708 if (testIcon == null) { 5709 testIcon = signalIconEditor.getIcon(0); 5710 } 5711 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 5712 5713 LayoutTurnoutView layoutTurnout1View = layoutEditor.getLayoutTurnoutView(layoutTurnout1); 5714 Point2D coordsB = layoutTurnout1View.getCoordsB(); 5715 Point2D coordsC = layoutTurnout1View.getCoordsC(); 5716 Point2D coordsCenter = layoutTurnout1View.getCoordsCenter(); 5717 5718 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 5719 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 5720 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 5721 double shiftX = 2.0 * shift; 5722 if (diffDirDEG >= 0.0) { 5723 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 5724 } 5725 Point2D delta = new Point2D.Double(shiftX, -shift); 5726 5727 delta = MathUtil.rotateDEG(delta, cDirDEG); 5728 Point2D where = MathUtil.add(coordsC, delta); 5729 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 5730 } 5731 5732 private void placeC1TToT(String signalHeadName) { 5733 if (testIcon == null) { 5734 testIcon = signalIconEditor.getIcon(0); 5735 } 5736 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 5737 5738 LayoutTurnoutView layoutTurnout2View = layoutEditor.getLayoutTurnoutView(layoutTurnout2); 5739 Point2D coordsB = layoutTurnout2View.getCoordsB(); 5740 Point2D coordsCenter = layoutTurnout2View.getCoordsCenter(); 5741 5742 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 5743 Point2D delta = new Point2D.Double(0.0, -shift); 5744 5745 delta = MathUtil.rotateDEG(delta, bDirDEG); 5746 Point2D where = MathUtil.add(coordsB, delta); 5747 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 5748 } 5749 5750 private void placeC2TToT(String signalHeadName) { 5751 if (testIcon == null) { 5752 testIcon = signalIconEditor.getIcon(0); 5753 } 5754 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 5755 5756 LayoutTurnoutView layoutTurnout2View = layoutEditor.getLayoutTurnoutView(layoutTurnout2); 5757 Point2D coordsB = layoutTurnout2View.getCoordsB(); 5758 Point2D coordsCenter = layoutTurnout2View.getCoordsCenter(); 5759 5760 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 5761 Point2D delta = new Point2D.Double(2.0 * shift, -shift); 5762 5763 delta = MathUtil.rotateDEG(delta, bDirDEG); 5764 Point2D where = MathUtil.add(coordsB, delta); 5765 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 5766 } 5767 5768 private void placeD1TToT(String signalHeadName) { 5769 if (testIcon == null) { 5770 testIcon = signalIconEditor.getIcon(0); 5771 } 5772 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 5773 5774 LayoutTurnoutView layoutTurnout2View = layoutEditor.getLayoutTurnoutView(layoutTurnout2); 5775 Point2D coordsB = layoutTurnout2View.getCoordsB(); 5776 Point2D coordsC = layoutTurnout2View.getCoordsC(); 5777 Point2D coordsCenter = layoutTurnout2View.getCoordsCenter(); 5778 5779 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 5780 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 5781 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 5782 double shiftX = 0.0; 5783 if (diffDirDEG >= 0.0) { 5784 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 5785 } 5786 Point2D delta = new Point2D.Double(shiftX, -shift); 5787 5788 delta = MathUtil.rotateDEG(delta, cDirDEG); 5789 Point2D where = MathUtil.add(coordsC, delta); 5790 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 5791 } 5792 5793 private void placeD2TToT(String signalHeadName) { 5794 if (testIcon == null) { 5795 testIcon = signalIconEditor.getIcon(0); 5796 } 5797 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 5798 5799 LayoutTurnoutView layoutTurnout2View = layoutEditor.getLayoutTurnoutView(layoutTurnout2); 5800 Point2D coordsB = layoutTurnout2View.getCoordsB(); 5801 Point2D coordsC = layoutTurnout2View.getCoordsC(); 5802 Point2D coordsCenter = layoutTurnout2View.getCoordsCenter(); 5803 5804 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 5805 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 5806 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 5807 double shiftX = 2.0 * shift; 5808 if (diffDirDEG >= 0.0) { 5809 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 5810 } 5811 Point2D delta = new Point2D.Double(shiftX, -shift); 5812 5813 delta = MathUtil.rotateDEG(delta, cDirDEG); 5814 Point2D where = MathUtil.add(coordsC, delta); 5815 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 5816 } 5817 5818 @SuppressWarnings("null") 5819 private void setLogicTToT(SignalHead head, TrackSegment track1, SignalHead secondHead, TrackSegment track2, 5820 boolean setup1, boolean setup2, boolean continuing, 5821 LayoutTurnout farTurnout, LayoutTurnout nearTurnout) { 5822 //initialize common components and ensure all is defined 5823 LayoutBlock connectorBlock = connectorTrack.getLayoutBlock(); 5824 LayoutBlock nearTurnoutBlock = nearTurnout.getLayoutBlock(); 5825 LayoutBlock farTurnoutBlock = farTurnout.getLayoutBlock(); 5826 Sensor connectorOccupancy = null; 5827 if ((connectorBlock == null) || (nearTurnoutBlock == null) || (farTurnoutBlock == null)) { 5828 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5829 Bundle.getMessage("InfoMessage6"), 5830 Bundle.getMessage("MessageTitle"), 5831 JmriJOptionPane.INFORMATION_MESSAGE); 5832 return; 5833 } 5834 connectorOccupancy = connectorBlock.getOccupancySensor(); 5835 if (connectorOccupancy == null) { 5836 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5837 Bundle.getMessage("InfoMessage4", 5838 new Object[]{connectorBlock.getUserName()}), 5839 Bundle.getMessage("MessageTitle"), 5840 JmriJOptionPane.INFORMATION_MESSAGE); 5841 return; 5842 } 5843 //setup signal head for continuing track of far turnout (or both tracks of far turnout) 5844 if ((track1 == null) && setup1) { 5845 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5846 Bundle.getMessage("InfoMessage7"), 5847 Bundle.getMessage("MessageTitle"), 5848 JmriJOptionPane.INFORMATION_MESSAGE); 5849 return; 5850 } 5851 Sensor occupancy = null; 5852 SignalHead nextHead = null; 5853 if ((track1 != null) && setup1) { 5854 LayoutBlock block = track1.getLayoutBlock(); 5855 if (block == null) { 5856 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5857 Bundle.getMessage("InfoMessage6"), 5858 Bundle.getMessage("MessageTitle"), 5859 JmriJOptionPane.INFORMATION_MESSAGE); 5860 return; 5861 } 5862 occupancy = block.getOccupancySensor(); 5863 if (occupancy == null) { 5864 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5865 Bundle.getMessage("InfoMessage4", 5866 new Object[]{block.getUserName()}), 5867 Bundle.getMessage("MessageTitle"), 5868 JmriJOptionPane.INFORMATION_MESSAGE); 5869 return; 5870 } 5871 nextHead = getNextSignalFromObject(track1, farTurnout, 5872 head.getSystemName(), setSignalsAtThroatToThroatTurnoutsFrame); 5873 if ((nextHead == null) && (!reachedEndBumper())) { 5874 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 5875 Bundle.getMessage("InfoMessage5", 5876 new Object[]{block.getUserName()}), 5877 Bundle.getMessage("MessageTitle"), 5878 JmriJOptionPane.INFORMATION_MESSAGE); 5879 return; 5880 } 5881 if (secondHead != null) { 5882 //this head signals only the continuing track of the far turnout 5883 if (!initializeBlockBossLogic(head.getDisplayName())) { 5884 return; 5885 } 5886 logic.setMode(BlockBossLogic.TRAILINGMAIN); 5887 logic.setTurnout(farTurnout.getTurnout().getDisplayName()); 5888 logic.setSensor1(occupancy.getDisplayName()); 5889 if (occupancy != connectorOccupancy) { 5890 logic.setSensor2(connectorOccupancy.getDisplayName()); 5891 } 5892 if (nextHead != null) { 5893 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 5894 } 5895 if (auxSignal != null) { 5896 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 5897 } 5898 String nearSensorName = setupNearLogix(nearTurnout, continuing, head); 5899 addNearSensorToLogic(nearSensorName); 5900 finalizeBlockBossLogic(); 5901 } 5902 } 5903 if ((secondHead != null) && !setup2) { 5904 return; 5905 } 5906 SignalHead savedAuxSignal = auxSignal; 5907 if (track2 == null) { 5908 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5909 Bundle.getMessage("InfoMessage7"), 5910 Bundle.getMessage("MessageTitle"), 5911 JmriJOptionPane.INFORMATION_MESSAGE); 5912 return; 5913 } 5914 LayoutBlock block2 = track2.getLayoutBlock(); 5915 if (block2 == null) { 5916 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5917 Bundle.getMessage("InfoMessage6"), 5918 Bundle.getMessage("MessageTitle"), 5919 JmriJOptionPane.INFORMATION_MESSAGE); 5920 return; 5921 } 5922 Sensor occupancy2 = block2.getOccupancySensor(); 5923 if (occupancy2 == null) { 5924 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5925 Bundle.getMessage("InfoMessage4", 5926 new Object[]{block2.getUserName()}), 5927 Bundle.getMessage("MessageTitle"), 5928 JmriJOptionPane.INFORMATION_MESSAGE); 5929 return; 5930 } 5931 SignalHead nextHead2 = null; 5932 if (secondHead != null) { 5933 nextHead2 = getNextSignalFromObject(track2, 5934 farTurnout, secondHead.getSystemName(), setSignalsAtThroatToThroatTurnoutsFrame); 5935 if ((nextHead2 == null) && (!reachedEndBumper())) { 5936 JmriJOptionPane.showMessageDialog(setSignalsAtThroatToThroatTurnoutsFrame, 5937 Bundle.getMessage("InfoMessage5", 5938 new Object[]{block2.getUserName()}), 5939 Bundle.getMessage("MessageTitle"), 5940 JmriJOptionPane.INFORMATION_MESSAGE); 5941 return; 5942 } 5943 } 5944 if ((secondHead == null) && (track1 != null) && setup1) { 5945 if (!initializeBlockBossLogic(head.getDisplayName())) { 5946 return; 5947 } 5948 logic.setMode(BlockBossLogic.FACING); 5949 logic.setTurnout(farTurnout.getTurnout().getDisplayName()); 5950 logic.setWatchedSensor1(occupancy.getDisplayName()); 5951 logic.setWatchedSensor2(occupancy2.getDisplayName()); 5952 logic.setSensor2(connectorOccupancy.getDisplayName()); 5953 if (nextHead != null) { 5954 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 5955 } 5956 if (savedAuxSignal != null) { 5957 logic.setWatchedSignal1Alt(savedAuxSignal.getDisplayName()); 5958 } 5959 if (nextHead2 != null) { 5960 logic.setWatchedSignal2(nextHead2.getDisplayName()); 5961 } 5962 if (auxSignal != null) { 5963 logic.setWatchedSignal2Alt(auxSignal.getDisplayName()); 5964 } 5965 String nearSensorName = setupNearLogix(nearTurnout, continuing, head); 5966 addNearSensorToLogic(nearSensorName); 5967 logic.setLimitSpeed2(true); 5968 finalizeBlockBossLogic(); 5969 } else if ((secondHead != null) && setup2) { 5970 if (!initializeBlockBossLogic(secondHead.getDisplayName())) { 5971 return; 5972 } 5973 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 5974 logic.setTurnout(farTurnout.getTurnout().getDisplayName()); 5975 logic.setSensor1(occupancy2.getDisplayName()); 5976 if (occupancy2 != connectorOccupancy) { 5977 logic.setSensor2(connectorOccupancy.getDisplayName()); 5978 } 5979 if (nextHead2 != null) { 5980 logic.setWatchedSignal1(nextHead2.getDisplayName(), false); 5981 } 5982 if (auxSignal != null) { 5983 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 5984 } 5985 String nearSensorName = setupNearLogix(nearTurnout, continuing, head); 5986 addNearSensorToLogic(nearSensorName); 5987 logic.setLimitSpeed2(true); 5988 finalizeBlockBossLogic(); 5989 } 5990 } //setLogicTToT 5991 5992 /* 5993 * Sets up a Logix to set a sensor active if a turnout is set against 5994 * a track. This routine creates an internal sensor for the purpose. 5995 * Note: The sensor and logix are named pref + S or pref + X followed by TTT_X_HHH where 5996 * TTT is the system name of the turnout, X is either C or T depending 5997 * on "continuing", and HHH is the system name of the signal head. 5998 * Note: If there is any problem, a string of "" is returned, and a warning 5999 * message is issued. 6000 */ 6001 private String setupNearLogix(LayoutTurnout nearTurnout, boolean continuing, 6002 SignalHead head) { 6003 String turnoutName = nearTurnout.getTurnout().getSystemName(); 6004 String namer = turnoutName + "_T_" + head.getSystemName(); 6005 if (!continuing) { 6006 namer = turnoutName + "_C_" + head.getSystemName(); 6007 } 6008 String pref = InstanceManager.getDefault(jmri.LogixManager.class).getSystemPrefix(); 6009 String sensorName = pref + "S" + namer; 6010 String logixName = pref + "X" + namer; 6011 try { 6012 InstanceManager.sensorManagerInstance().provideSensor(sensorName); 6013 } catch (IllegalArgumentException ex) { 6014 log.error("Trouble creating sensor {} while setting up Logix.", sensorName); 6015 return ""; 6016 6017 } 6018 if (InstanceManager.getDefault(LogixManager.class).getBySystemName(logixName) == null) { 6019 //Logix does not exist, create it 6020 Logix x = InstanceManager.getDefault(LogixManager.class).createNewLogix(logixName, ""); 6021 if (x == null) { 6022 log.error("Trouble creating logix {} while setting up signal logic.", logixName); 6023 return ""; 6024 } 6025 String cName = x.getSystemName() + "C1"; 6026 Conditional c = InstanceManager.getDefault(ConditionalManager.class). 6027 createNewConditional(cName, ""); 6028 if (c == null) { 6029 log.error("Trouble creating conditional {} while setting up Logix.", cName); 6030 return ""; 6031 } 6032 Conditional.Type type = Conditional.Type.TURNOUT_THROWN; 6033 if (!continuing) { 6034 type = Conditional.Type.TURNOUT_CLOSED; 6035 } 6036 List<ConditionalVariable> variableList = c.getCopyOfStateVariables(); 6037 variableList.add(new ConditionalVariable(false, Conditional.Operator.AND, 6038 type, turnoutName, true)); 6039 c.setStateVariables(variableList); 6040 List<ConditionalAction> actionList = c.getCopyOfActions(); 6041 actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE, 6042 Conditional.Action.SET_SENSOR, sensorName, 6043 Sensor.ACTIVE, "")); 6044 actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_FALSE, 6045 Conditional.Action.SET_SENSOR, sensorName, 6046 Sensor.INACTIVE, "")); 6047 c.setAction(actionList); // string data 6048 x.addConditional(cName, -1); 6049 x.activateLogix(); 6050 } 6051 return sensorName; 6052 } 6053 6054 /* 6055 * Adds the sensor specified to the open BlockBossLogic, provided it is not already there and 6056 * provided there is an open slot. If 'name' is null or empty, returns without doing anything. 6057 */ 6058 private void addNearSensorToLogic(String name) { 6059 if ((name != null) && !name.isEmpty()) { 6060 //return if a sensor by this name is already present 6061 if ((logic.getSensor1() != null) && (logic.getSensor1().equals(name))) { 6062 return; 6063 } 6064 if ((logic.getSensor2() != null) && (logic.getSensor2().equals(name))) { 6065 return; 6066 } 6067 if ((logic.getSensor3() != null) && (logic.getSensor3().equals(name))) { 6068 return; 6069 } 6070 if ((logic.getSensor4() != null) && (logic.getSensor4().equals(name))) { 6071 return; 6072 } 6073 if ((logic.getSensor5() != null) && (logic.getSensor5().equals(name))) { 6074 return; 6075 } 6076 //add in the first available slot 6077 if (logic.getSensor1() == null) { 6078 logic.setSensor1(name); 6079 } else if (logic.getSensor2() == null) { 6080 logic.setSensor2(name); 6081 } else if (logic.getSensor3() == null) { 6082 logic.setSensor3(name); 6083 } else if (logic.getSensor4() == null) { 6084 logic.setSensor4(name); 6085 } else if (logic.getSensor5() == null) { 6086 logic.setSensor5(name); 6087 } else { 6088 log.error("Error - could not add sensor to SSL for signal head {}", logic.getDrivenSignal()); 6089 } 6090 } 6091 } 6092 6093 /*=========================*\ 6094 |* setSignalsAt3WayTurnout *| 6095 \*=========================*/ 6096 /** 6097 * Tool to set signals at a three-way turnout, including placing the signal 6098 * icons and setup of signal logic for each signal head 6099 * <p> 6100 * This tool can only be accessed from the Tools menu. There is no access 6101 * from a turnout pop-up menu. 6102 * <p> 6103 * This tool requires a situation where two turnouts are connected to model 6104 * a 3-way turnout, with the throat of the second turnout connected to the 6105 * continuing leg of the first turnout by a very short track segment. The 6106 * actual length of the track segment is not tested. If this situation is 6107 * not found, and error message is sent to the user. 6108 * <p> 6109 * This tool assumes two turnouts connected with the throat of the second 6110 * turnout connected to the continuing leg of the first turnou, as used to 6111 * represent a 3-way turnout. The turnouts may be either left-handed, or 6112 * right-handed, or any pair of these. This tool also assumes that there are 6113 * no signals between the two turnouts. Signal heads are allowed/required at 6114 * the continuing leg of the second turnout, at each of the diverging legs, 6115 * and at the throat. At the throat, either one or three heads are provided 6116 * for. So four or six heads will be placed. 6117 * <p> 6118 * This tool assumes that each of the four tracks, the continuing, the two 6119 * diverging, and the throat is contained in a different block. The two 6120 * turnouts used to model the 3-way turnout must be in the same block. 6121 * Things work best if the two turnouts are in the same block as the track 6122 * connecting at the throat, or if the two turnouts are in their own 6123 * separate block, either works fine. 6124 */ 6125 //operational variables for Set Signals at 3-Way Turnout tool 6126 private JmriJFrame setSignalsAt3WayTurnoutFrame = null; 6127 private boolean setSignalsAt3WayTurnoutOpenFlag = false; 6128 private boolean setSignalsAt3WayTurnoutFromMenuFlag = false; 6129 6130 private JLabel turnoutANameLabel = null; 6131 private JLabel turnoutBNameLabel = null; 6132 6133 private final NamedBeanComboBox<Turnout> turnoutAComboBox = new NamedBeanComboBox<>( 6134 InstanceManager.turnoutManagerInstance(), 6135 null, DisplayOptions.DISPLAYNAME); 6136 private final NamedBeanComboBox<Turnout> turnoutBComboBox = new NamedBeanComboBox<>( 6137 InstanceManager.turnoutManagerInstance(), 6138 null, DisplayOptions.DISPLAYNAME); 6139 6140 private final NamedBeanComboBox<SignalHead> a1_3WaySignalHeadComboBox = new NamedBeanComboBox<>( 6141 InstanceManager.getDefault(SignalHeadManager.class 6142 ), 6143 null, DisplayOptions.DISPLAYNAME); 6144 private final NamedBeanComboBox<SignalHead> a2_3WaySignalHeadComboBox = new NamedBeanComboBox<>( 6145 InstanceManager.getDefault(SignalHeadManager.class 6146 ), 6147 null, DisplayOptions.DISPLAYNAME); 6148 private final NamedBeanComboBox<SignalHead> a3_3WaySignalHeadComboBox = new NamedBeanComboBox<>( 6149 InstanceManager.getDefault(SignalHeadManager.class 6150 ), 6151 null, DisplayOptions.DISPLAYNAME); 6152 private final NamedBeanComboBox<SignalHead> b_3WaySignalHeadComboBox = new NamedBeanComboBox<>( 6153 InstanceManager.getDefault(SignalHeadManager.class 6154 ), 6155 null, DisplayOptions.DISPLAYNAME); 6156 private final NamedBeanComboBox<SignalHead> c_3WaySignalHeadComboBox = new NamedBeanComboBox<>( 6157 InstanceManager.getDefault(SignalHeadManager.class 6158 ), 6159 null, DisplayOptions.DISPLAYNAME); 6160 private final NamedBeanComboBox<SignalHead> d_3WaySignalHeadComboBox = new NamedBeanComboBox<>( 6161 InstanceManager.getDefault(SignalHeadManager.class 6162 ), 6163 null, DisplayOptions.DISPLAYNAME); 6164 6165 private final JCheckBox setA13WayHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 6166 private final JCheckBox setupA13WayLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 6167 private final JCheckBox setA23WayHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 6168 private final JCheckBox setupA23WayLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 6169 private final JCheckBox setA33WayHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 6170 private final JCheckBox setupA33WayLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 6171 private final JCheckBox setB3WayHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 6172 private final JCheckBox setupB3WayLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 6173 private final JCheckBox setC3WayHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 6174 private final JCheckBox setupC3WayLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 6175 private final JCheckBox setD3WayHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 6176 private final JCheckBox setupD3WayLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 6177 private JButton getSaved3WaySignalHeads = null; 6178 private JButton change3WaySignalIcon = null; 6179 private JButton set3WaySignalsDone = null; 6180 private JButton set3WaySignalsCancel = null; 6181 private LayoutTurnout layoutTurnoutA = null; 6182 private LayoutTurnout layoutTurnoutB = null; 6183 private Turnout turnoutA = null; 6184 private Turnout turnoutB = null; 6185 //private TrackSegment conTrack = null; 6186 private SignalHead a13WayHead = null; //saved in A1 of Turnout A - Throat - continuing 6187 private SignalHead a23WayHead = null; //saved in A2 of Turnout A - Throat - diverging A (optional) 6188 private SignalHead a33WayHead = null; //saved in A3 of Turnout A - Throat - diverging B (optional) 6189 private SignalHead b3WayHead = null; //saved in C1 of Turnout A - at diverging A 6190 private SignalHead c3WayHead = null; //saved in B1 of Turnout B - at continuing 6191 private SignalHead d3WayHead = null; //saved in C1 of Turnout B - at diverging B 6192 6193 public void setSignalsAt3WayTurnoutFromMenu( 6194 @Nonnull String aName, @Nonnull String bName, 6195 @Nonnull MultiIconEditor theEditor, @Nonnull JFrame theFrame) { 6196 Turnout ta = InstanceManager.getDefault(jmri.TurnoutManager.class).getTurnout(aName); 6197 Turnout tb = InstanceManager.getDefault(jmri.TurnoutManager.class).getTurnout(bName); 6198 turnoutAComboBox.setSelectedItem(ta); 6199 turnoutBComboBox.setSelectedItem(tb); 6200 a1_3WaySignalHeadComboBox.setSelectedItem(null); 6201 a2_3WaySignalHeadComboBox.setSelectedItem(null); 6202 a3_3WaySignalHeadComboBox.setSelectedItem(null); 6203 b_3WaySignalHeadComboBox.setSelectedItem(null); 6204 c_3WaySignalHeadComboBox.setSelectedItem(null); 6205 d_3WaySignalHeadComboBox.setSelectedItem(null); 6206 setSignalsAt3WayTurnoutFromMenuFlag = true; 6207 setSignalsAt3WayTurnout(theEditor, theFrame); 6208 setSignalsAt3WayTurnoutFromMenuFlag = false; 6209 } 6210 6211 public void setSignalsAt3WayTurnout(@Nonnull MultiIconEditor theEditor, 6212 @Nonnull JFrame theFrame) { 6213 signalIconEditor = theEditor; 6214 signalFrame = theFrame; 6215 6216 //Initialize if needed 6217 if (setSignalsAt3WayTurnoutFrame == null) { 6218 setSignalsAt3WayTurnoutOpenFlag = false; 6219 setSignalsAt3WayTurnoutFrame = new JmriJFrame(Bundle.getMessage("SignalsAt3WayTurnout"), false, true); 6220 oneFrameToRuleThemAll(setSignalsAt3WayTurnoutFrame); 6221 setSignalsAt3WayTurnoutFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 6222 setSignalsAt3WayTurnoutFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAt3WayTurnout", true); 6223 setSignalsAt3WayTurnoutFrame.setLocation(70, 30); 6224 Container theContentPane = setSignalsAt3WayTurnoutFrame.getContentPane(); 6225 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 6226 6227 JPanel panel1A = new JPanel(new FlowLayout()); 6228 turnoutANameLabel = new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("TurnoutAName"))); 6229 panel1A.add(turnoutANameLabel); 6230 panel1A.add(turnoutAComboBox); 6231 turnoutAComboBox.setToolTipText(Bundle.getMessage("SignalsTurnoutNameHint")); 6232 theContentPane.add(panel1A); 6233 6234 JPanel panel1B = new JPanel(new FlowLayout()); 6235 turnoutBNameLabel = new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("TurnoutBName"))); 6236 panel1B.add(turnoutBNameLabel); 6237 panel1B.add(turnoutBComboBox); 6238 turnoutBComboBox.setToolTipText(Bundle.getMessage("SignalsTurnoutNameHint")); 6239 theContentPane.add(panel1B); 6240 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 6241 //Provide for retrieval of names of previously saved signal heads 6242 6243 JPanel panel2 = new JPanel(new FlowLayout()); 6244 JLabel shTitle = new JLabel(Bundle.getMessage("SignalHeads")); 6245 panel2.add(shTitle); 6246 panel2.add(new JLabel(" ")); 6247 panel2.add(getSaved3WaySignalHeads = new JButton(Bundle.getMessage("GetSaved"))); 6248 getSaved3WaySignalHeads.addActionListener(this::getSaved3WaySignals); 6249 getSaved3WaySignalHeads.setToolTipText(Bundle.getMessage("GetSavedHint")); 6250 theContentPane.add(panel2); 6251 6252 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 6253 JPanel panel2a = new JPanel(new FlowLayout()); 6254 panel2a.add(new JLabel(" ")); 6255 panel2a.add(setPlaceAllHeads); 6256 setPlaceAllHeads.setToolTipText(Bundle.getMessage("PlaceAllHeadsHint")); 6257 setPlaceAllHeads.addActionListener((ActionEvent e) -> { 6258 boolean isSelected = setPlaceAllHeads.isSelected(); 6259 //(de)select all checkboxes 6260 setA13WayHead.setSelected(isSelected); 6261 setA23WayHead.setSelected(isSelected); 6262 setA33WayHead.setSelected(isSelected); 6263 setB3WayHead.setSelected(isSelected); 6264 setC3WayHead.setSelected(isSelected); 6265 setD3WayHead.setSelected(isSelected); 6266 }); 6267 panel2a.add(new JLabel(" ")); 6268 panel2a.add(setupAllLogic); 6269 setupAllLogic.setToolTipText(Bundle.getMessage("SetAllLogicHint")); 6270 setupAllLogic.addActionListener((ActionEvent e) -> { 6271 boolean isSelected = setupAllLogic.isSelected(); 6272 //(de)select all checkboxes 6273 setupA13WayLogic.setSelected(isSelected); 6274 setupA23WayLogic.setSelected(isSelected); 6275 setupA33WayLogic.setSelected(isSelected); 6276 setupB3WayLogic.setSelected(isSelected); 6277 setupC3WayLogic.setSelected(isSelected); 6278 setupD3WayLogic.setSelected(isSelected); 6279 }); 6280 theContentPane.add(panel2a); 6281 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 6282 6283 //Signal heads located at turnout A 6284 JPanel panel20 = new JPanel(new FlowLayout()); 6285 panel20.add(new JLabel(Bundle.getMessage("SignalLocated") 6286 + " " + Bundle.getMessage("BeanNameTurnout") + " A ")); 6287 theContentPane.add(panel20); 6288 6289 JPanel panel21 = new JPanel(new FlowLayout()); 6290 panel21.add(new JLabel(Bundle.getMessage("MakeLabel", 6291 throatString + " - " 6292 + continuingString))); 6293 panel21.add(a1_3WaySignalHeadComboBox); 6294 a1_3WaySignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 6295 theContentPane.add(panel21); 6296 6297 JPanel panel22 = new JPanel(new FlowLayout()); 6298 panel22.add(new JLabel(" ")); 6299 panel22.add(setA13WayHead); 6300 setA13WayHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 6301 panel22.add(new JLabel(" ")); 6302 panel22.add(setupA13WayLogic); 6303 setupA13WayLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 6304 theContentPane.add(panel22); 6305 6306 JPanel panel23 = new JPanel(new FlowLayout()); 6307 panel23.add(new JLabel(Bundle.getMessage("MakeLabel", 6308 throatString + " - " 6309 + divergingAString))); 6310 panel23.add(a2_3WaySignalHeadComboBox); 6311 a2_3WaySignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 6312 theContentPane.add(panel23); 6313 6314 JPanel panel24 = new JPanel(new FlowLayout()); 6315 panel24.add(new JLabel(" ")); 6316 panel24.add(setA23WayHead); 6317 setA23WayHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 6318 panel24.add(new JLabel(" ")); 6319 panel24.add(setupA23WayLogic); 6320 setupA23WayLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 6321 theContentPane.add(panel24); 6322 6323 JPanel panel25 = new JPanel(new FlowLayout()); 6324 panel25.add(new JLabel(Bundle.getMessage("MakeLabel", 6325 throatString + " - " 6326 + divergingBString))); 6327 panel25.add(a3_3WaySignalHeadComboBox); 6328 a3_3WaySignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 6329 theContentPane.add(panel25); 6330 6331 JPanel panel26 = new JPanel(new FlowLayout()); 6332 panel26.add(new JLabel(" ")); 6333 panel26.add(setA33WayHead); 6334 setA33WayHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 6335 panel26.add(new JLabel(" ")); 6336 panel26.add(setupA33WayLogic); 6337 setupA33WayLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 6338 theContentPane.add(panel26); 6339 6340 JPanel panel31 = new JPanel(new FlowLayout()); 6341 panel31.add(new JLabel(Bundle.getMessage("MakeLabel", 6342 divergingAString))); 6343 panel31.add(b_3WaySignalHeadComboBox); 6344 b_3WaySignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 6345 theContentPane.add(panel31); 6346 6347 JPanel panel32 = new JPanel(new FlowLayout()); 6348 panel32.add(new JLabel(" ")); 6349 panel32.add(setB3WayHead); 6350 setB3WayHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 6351 panel32.add(new JLabel(" ")); 6352 panel32.add(setupB3WayLogic); 6353 setupB3WayLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 6354 theContentPane.add(panel32); 6355 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 6356 //Signal heads located at turnout B 6357 6358 JPanel panel40 = new JPanel(new FlowLayout()); 6359 panel40.add(new JLabel(Bundle.getMessage("SignalLocated") 6360 + " " + Bundle.getMessage("BeanNameTurnout") + " B ")); 6361 theContentPane.add(panel40); 6362 6363 JPanel panel41 = new JPanel(new FlowLayout()); 6364 panel41.add(new JLabel(Bundle.getMessage("MakeLabel", 6365 continuingString))); 6366 panel41.add(c_3WaySignalHeadComboBox); 6367 c_3WaySignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 6368 theContentPane.add(panel41); 6369 6370 JPanel panel42 = new JPanel(new FlowLayout()); 6371 panel42.add(new JLabel(" ")); 6372 panel42.add(setC3WayHead); 6373 setC3WayHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 6374 panel42.add(new JLabel(" ")); 6375 panel42.add(setupC3WayLogic); 6376 setupC3WayLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 6377 theContentPane.add(panel42); 6378 6379 JPanel panel43 = new JPanel(new FlowLayout()); 6380 panel43.add(new JLabel(Bundle.getMessage("MakeLabel", 6381 divergingBString))); 6382 panel43.add(d_3WaySignalHeadComboBox); 6383 d_3WaySignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 6384 theContentPane.add(panel43); 6385 6386 JPanel panel44 = new JPanel(new FlowLayout()); 6387 panel44.add(new JLabel(" ")); 6388 panel44.add(setD3WayHead); 6389 setD3WayHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 6390 panel44.add(new JLabel(" ")); 6391 panel44.add(setupD3WayLogic); 6392 setupD3WayLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 6393 theContentPane.add(panel44); 6394 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 6395 //buttons 6396 6397 JPanel panel6 = new JPanel(new FlowLayout()); 6398 panel6.add(change3WaySignalIcon = new JButton(Bundle.getMessage("ChangeSignalIcon"))); 6399 change3WaySignalIcon.addActionListener((ActionEvent e) -> signalFrame.setVisible(true)); 6400 change3WaySignalIcon.setToolTipText(Bundle.getMessage("ChangeSignalIconHint")); 6401 panel6.add(new JLabel(" ")); 6402 panel6.add(set3WaySignalsDone = new JButton(Bundle.getMessage("ButtonDone"))); 6403 set3WaySignalsDone.addActionListener(this::set3WaySignalsDonePressed); 6404 set3WaySignalsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 6405 6406 panel6.add(set3WaySignalsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 6407 set3WaySignalsCancel.addActionListener(this::set3WaySignalsCancelPressed); 6408 set3WaySignalsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 6409 theContentPane.add(panel6); 6410 6411 //make this button the default button (return or enter activates) 6412 JRootPane rootPane = SwingUtilities.getRootPane(set3WaySignalsDone); 6413 if (rootPane != null) { 6414 rootPane.setDefaultButton(set3WaySignalsDone); 6415 } 6416 6417 setSignalsAt3WayTurnoutFrame.addWindowListener(new WindowAdapter() { 6418 @Override 6419 public void windowClosing(WindowEvent e) { 6420 set3WaySignalsCancelPressed(null); 6421 } 6422 }); 6423 } 6424 setPlaceAllHeads.setSelected(false); 6425 setupAllLogic.setSelected(false); 6426 6427 turnoutAComboBox.setVisible(!setSignalsAt3WayTurnoutFromMenuFlag); 6428 turnoutBComboBox.setVisible(!setSignalsAt3WayTurnoutFromMenuFlag); 6429 if (setSignalsAt3WayTurnoutFromMenuFlag) { 6430 turnoutANameLabel.setText(Bundle.getMessage("MakeLabel", 6431 Bundle.getMessage("BeanNameTurnout") + " A") 6432 + turnoutAComboBox.getSelectedItemDisplayName()); 6433 turnoutBNameLabel.setText(Bundle.getMessage("MakeLabel", 6434 Bundle.getMessage("BeanNameTurnout") + " B") 6435 + turnoutBComboBox.getSelectedItemDisplayName()); 6436 getSaved3WaySignals(null); 6437 } else { 6438 turnoutANameLabel.setText(Bundle.getMessage("MakeLabel", 6439 Bundle.getMessage("TurnoutAName"))); 6440 turnoutBNameLabel.setText(Bundle.getMessage("MakeLabel", 6441 Bundle.getMessage("TurnoutBName"))); 6442 } 6443 6444 if (!setSignalsAt3WayTurnoutOpenFlag) { 6445 setSignalsAt3WayTurnoutFrame.setPreferredSize(null); 6446 setSignalsAt3WayTurnoutFrame.pack(); 6447 setSignalsAt3WayTurnoutOpenFlag = true; 6448 } 6449 setSignalsAt3WayTurnoutFrame.setVisible(true); 6450 } //setSignalsAt3WayTurnout 6451 6452 private void getSaved3WaySignals(ActionEvent a) { 6453 if (!get3WayTurnoutInformation()) { 6454 return; 6455 } 6456 a1_3WaySignalHeadComboBox.setSelectedItem(layoutTurnoutA.getSignalA1()); 6457 a2_3WaySignalHeadComboBox.setSelectedItem(layoutTurnoutA.getSignalA2()); 6458 a3_3WaySignalHeadComboBox.setSelectedItem(layoutTurnoutA.getSignalA3()); 6459 b_3WaySignalHeadComboBox.setSelectedItem(layoutTurnoutA.getSignalC1()); 6460 c_3WaySignalHeadComboBox.setSelectedItem(layoutTurnoutB.getSignalB1()); 6461 d_3WaySignalHeadComboBox.setSelectedItem(layoutTurnoutB.getSignalC1()); 6462 } 6463 6464 private void set3WaySignalsCancelPressed(ActionEvent a) { 6465 setSignalsAt3WayTurnoutOpenFlag = false; 6466 setSignalsAt3WayTurnoutFrame.setVisible(false); 6467 } 6468 6469 private boolean get3WayTurnoutInformation() { 6470 HitPointType type = HitPointType.NONE; 6471 Object connect = null; 6472 turnoutA = null; 6473 turnoutB = null; 6474 layoutTurnoutA = null; 6475 layoutTurnoutB = null; 6476 6477 String str = turnoutAComboBox.getSelectedItemDisplayName(); 6478 if ((str == null) || str.isEmpty()) { 6479 //turnout A not entered, test turnout B 6480 str = turnoutBComboBox.getSelectedItemDisplayName(); 6481 if ((str == null) || str.isEmpty()) { 6482 //no entries in turnout fields 6483 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6484 Bundle.getMessage("SignalsError1"), 6485 Bundle.getMessage("ErrorTitle"), 6486 JmriJOptionPane.ERROR_MESSAGE); 6487 return false; 6488 } 6489 turnoutB = InstanceManager.turnoutManagerInstance().getTurnout(str); 6490 if (turnoutB == null) { 6491 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6492 Bundle.getMessage("SignalsError2", 6493 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 6494 JmriJOptionPane.ERROR_MESSAGE); 6495 return false; 6496 } 6497 String uname = turnoutB.getUserName(); 6498 if ((uname == null) || uname.isEmpty() 6499 || !uname.equals(str)) { 6500 turnoutBComboBox.setSelectedItem(turnoutB); 6501 } 6502 layoutTurnoutB = getLayoutTurnoutFromTurnout(turnoutB, false, str, setSignalsAt3WayTurnoutFrame); 6503 if (layoutTurnoutB == null) { 6504 return false; 6505 } 6506 //have turnout B and layout turnout B - look for turnout A 6507 connectorTrack = (TrackSegment) layoutTurnoutB.getConnectA(); 6508 if (connectorTrack == null) { 6509 //Inform user of error, and terminate 6510 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6511 Bundle.getMessage("SignalsError19"), 6512 Bundle.getMessage("ErrorTitle"), 6513 JmriJOptionPane.ERROR_MESSAGE); 6514 return false; 6515 } 6516 type = connectorTrack.getType1(); 6517 connect = connectorTrack.getConnect1(); 6518 if (connect == layoutTurnoutB) { 6519 type = connectorTrack.getType2(); 6520 connect = connectorTrack.getConnect2(); 6521 } 6522 if ((type != HitPointType.TURNOUT_B) || (connect == null)) { 6523 //Not two turnouts connected as required by a single Track Segment 6524 //Inform user of error and terminate 6525 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6526 Bundle.getMessage("SignalsError19"), 6527 Bundle.getMessage("ErrorTitle"), 6528 JmriJOptionPane.ERROR_MESSAGE); 6529 return false; 6530 } 6531 layoutTurnoutA = (LayoutTurnout) connect; 6532 turnoutA = layoutTurnoutA.getTurnout(); 6533 if (turnoutA == null) { 6534 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6535 Bundle.getMessage("SignalsError19"), 6536 Bundle.getMessage("ErrorTitle"), 6537 JmriJOptionPane.ERROR_MESSAGE); 6538 return false; 6539 } 6540 turnoutAComboBox.setSelectedItem(turnoutA); 6541 } else { 6542 //something was entered in the turnout A field 6543 turnoutA = InstanceManager.turnoutManagerInstance().getTurnout(str); 6544 if (turnoutA == null) { 6545 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6546 Bundle.getMessage("SignalsError2", 6547 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 6548 JmriJOptionPane.ERROR_MESSAGE); 6549 return false; 6550 } 6551 String uname = turnoutA.getUserName(); 6552 if ((uname == null) || uname.isEmpty() 6553 || !uname.equals(str)) { 6554 turnoutAComboBox.setSelectedItem(turnoutA); 6555 } 6556 //have turnout A - get corresponding layoutTurnout 6557 layoutTurnoutA = getLayoutTurnoutFromTurnout(turnoutA, false, str, setSignalsAt3WayTurnoutFrame); 6558 if (layoutTurnoutA == null) { 6559 return false; 6560 } 6561 turnoutAComboBox.setSelectedItem(layoutTurnoutA.getTurnout()); 6562 //have turnout A and layout turnout A - was something entered for turnout B 6563 str = turnoutBComboBox.getSelectedItemDisplayName(); 6564 if ((str == null) || str.isEmpty()) { 6565 //no entry for turnout B 6566 connectorTrack = (TrackSegment) layoutTurnoutA.getConnectB(); 6567 if (connectorTrack == null) { 6568 //Inform user of error, and terminate 6569 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6570 Bundle.getMessage("SignalsError19"), 6571 Bundle.getMessage("ErrorTitle"), 6572 JmriJOptionPane.ERROR_MESSAGE); 6573 return false; 6574 } 6575 type = connectorTrack.getType1(); 6576 connect = connectorTrack.getConnect1(); 6577 if (connect == layoutTurnoutA) { 6578 type = connectorTrack.getType2(); 6579 connect = connectorTrack.getConnect2(); 6580 } 6581 if ((type != HitPointType.TURNOUT_A) || (connect == null)) { 6582 // Not two turnouts connected with the throat of B connected to the continuing of A 6583 // by a single Track Segment. Inform user of error and terminate. 6584 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6585 Bundle.getMessage("SignalsError19"), 6586 Bundle.getMessage("ErrorTitle"), 6587 JmriJOptionPane.ERROR_MESSAGE); 6588 return false; 6589 } 6590 layoutTurnoutB = (LayoutTurnout) connect; 6591 turnoutB = layoutTurnoutB.getTurnout(); 6592 if (turnoutB == null) { 6593 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6594 Bundle.getMessage("SignalsError19"), 6595 Bundle.getMessage("ErrorTitle"), 6596 JmriJOptionPane.ERROR_MESSAGE); 6597 return false; 6598 } 6599 turnoutBComboBox.setSelectedItem(turnoutB); 6600 } else { 6601 //turnout B entered also 6602 turnoutB = InstanceManager.turnoutManagerInstance().getTurnout(str); 6603 if (turnoutB == null) { 6604 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6605 Bundle.getMessage("SignalsError2", 6606 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 6607 JmriJOptionPane.ERROR_MESSAGE); 6608 return false; 6609 } 6610 uname = turnoutB.getUserName(); 6611 if ((uname == null) || uname.isEmpty() 6612 || !uname.equals(str)) { 6613 turnoutBComboBox.setSelectedItem(turnoutB); 6614 } 6615 layoutTurnoutB = getLayoutTurnoutFromTurnout(turnoutB, false, str, setSignalsAt3WayTurnoutFrame); 6616 if (layoutTurnoutB == null) { 6617 return false; 6618 } 6619 turnoutBComboBox.setSelectedItem(layoutTurnoutB.getTurnout()); 6620 //check that layout turnout A and layout turnout B are connected as required 6621 if (layoutTurnoutA.getConnectB() != layoutTurnoutB.getConnectA()) { 6622 //Not two turnouts connected as required by a single Track Segment 6623 //Inform user of error and terminate 6624 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6625 Bundle.getMessage("SignalsError19"), 6626 Bundle.getMessage("ErrorTitle"), 6627 JmriJOptionPane.ERROR_MESSAGE); 6628 return false; 6629 } 6630 connectorTrack = (TrackSegment) layoutTurnoutA.getConnectB(); 6631 } 6632 } 6633 return true; 6634 } //get3WayTurnoutInformation 6635 6636 private void set3WaySignalsDonePressed(ActionEvent a) { 6637 //process turnout names 6638 if (!get3WayTurnoutInformation()) { 6639 return; 6640 } 6641 //process signal head names 6642 if (!get3WaySignalHeadInformation()) { 6643 return; 6644 } 6645 //place signals as requested at turnout A 6646 String signalHeadName = a1_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 6647 if (signalHeadName == null) { 6648 signalHeadName = ""; 6649 } 6650 if (setA13WayHead.isSelected()) { 6651 if (isHeadOnPanel(a13WayHead) 6652 && (a13WayHead != getHeadFromName(layoutTurnoutA.getSignalA1Name()))) { 6653 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6654 Bundle.getMessage("SignalsError6", 6655 new Object[]{signalHeadName}), 6656 Bundle.getMessage("ErrorTitle"), 6657 JmriJOptionPane.ERROR_MESSAGE); 6658 return; 6659 } else { 6660 removeSignalHeadFromPanel(layoutTurnoutA.getSignalA1Name()); 6661 place3WayThroatContinuing(); 6662 removeAssignment(a13WayHead); 6663 layoutTurnoutA.setSignalA1Name(signalHeadName); 6664 needRedraw = true; 6665 } 6666 } else { 6667 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a13WayHead, layoutTurnoutA); 6668 if (assigned == LayoutTurnout.Geometry.NONE) { 6669 if (isHeadOnPanel(a13WayHead) 6670 && isHeadAssignedAnywhere(a13WayHead)) { 6671 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6672 Bundle.getMessage("SignalsError8", 6673 new Object[]{signalHeadName}), 6674 Bundle.getMessage("ErrorTitle"), 6675 JmriJOptionPane.ERROR_MESSAGE); 6676 return; 6677 } else { 6678 removeSignalHeadFromPanel(layoutTurnoutA.getSignalA1Name()); 6679 removeAssignment(a13WayHead); 6680 layoutTurnoutA.setSignalA1Name(signalHeadName); 6681 } 6682 //} else if (assigned != A1) { 6683 //need to figure out what to do in this case. 6684 } 6685 } 6686 6687 signalHeadName = a2_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 6688 if (signalHeadName == null) { 6689 signalHeadName = ""; 6690 } 6691 if ((setA23WayHead.isSelected()) && (a23WayHead != null)) { 6692 if (isHeadOnPanel(a23WayHead) 6693 && (a23WayHead != getHeadFromName(layoutTurnoutA.getSignalA2Name()))) { 6694 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6695 Bundle.getMessage("SignalsError6", 6696 new Object[]{signalHeadName}), 6697 Bundle.getMessage("ErrorTitle"), 6698 JmriJOptionPane.ERROR_MESSAGE); 6699 return; 6700 } else { 6701 removeSignalHeadFromPanel(layoutTurnoutA.getSignalA2Name()); 6702 place3WayThroatDivergingA(); 6703 removeAssignment(a23WayHead); 6704 layoutTurnoutA.setSignalA2Name(signalHeadName); 6705 needRedraw = true; 6706 } 6707 } else if (a23WayHead != null) { 6708 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a23WayHead, layoutTurnoutA); 6709 if (assigned == LayoutTurnout.Geometry.NONE) { 6710 if (isHeadOnPanel(a23WayHead) 6711 && isHeadAssignedAnywhere(a23WayHead)) { 6712 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6713 Bundle.getMessage("SignalsError8", 6714 new Object[]{signalHeadName}), 6715 Bundle.getMessage("ErrorTitle"), 6716 JmriJOptionPane.ERROR_MESSAGE); 6717 return; 6718 } else { 6719 removeSignalHeadFromPanel(layoutTurnoutA.getSignalA2Name()); 6720 removeAssignment(a23WayHead); 6721 layoutTurnoutA.setSignalA2Name(signalHeadName); 6722 } 6723 //} else if (assigned != A2) { 6724 //need to figure out what to do in this case. 6725 } 6726 } else { //a23WayHead is always null here 6727 removeSignalHeadFromPanel(layoutTurnoutA.getSignalA2Name()); 6728 layoutTurnoutA.setSignalA2Name(""); 6729 } 6730 6731 signalHeadName = a3_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 6732 if (signalHeadName == null) { 6733 signalHeadName = ""; 6734 } 6735 if ((setA33WayHead.isSelected()) && (a33WayHead != null)) { 6736 if (isHeadOnPanel(a33WayHead) 6737 && (a33WayHead != getHeadFromName(layoutTurnoutA.getSignalA3Name()))) { 6738 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6739 Bundle.getMessage("SignalsError6", 6740 new Object[]{signalHeadName}), 6741 Bundle.getMessage("ErrorTitle"), 6742 JmriJOptionPane.ERROR_MESSAGE); 6743 return; 6744 } else { 6745 removeSignalHeadFromPanel(layoutTurnoutA.getSignalA3Name()); 6746 place3WayThroatDivergingB(); 6747 removeAssignment(a33WayHead); 6748 layoutTurnoutA.setSignalA3Name(signalHeadName); 6749 needRedraw = true; 6750 } 6751 } else if (a33WayHead != null) { 6752 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a33WayHead, layoutTurnoutA); 6753 if (assigned == LayoutTurnout.Geometry.NONE) { 6754 if (isHeadOnPanel(a33WayHead) 6755 && isHeadAssignedAnywhere(a33WayHead)) { 6756 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6757 Bundle.getMessage("SignalsError8", 6758 new Object[]{signalHeadName}), 6759 Bundle.getMessage("ErrorTitle"), 6760 JmriJOptionPane.ERROR_MESSAGE); 6761 return; 6762 } else { 6763 removeSignalHeadFromPanel(layoutTurnoutA.getSignalA3Name()); 6764 removeAssignment(a33WayHead); 6765 layoutTurnoutA.setSignalA3Name(signalHeadName); 6766 } 6767 //} else if (assigned != A3) { 6768 //need to figure out what to do in this case. 6769 } 6770 } else { //a23WayHead is always null here 6771 removeSignalHeadFromPanel(layoutTurnoutA.getSignalA3Name()); 6772 layoutTurnoutA.setSignalA3Name(""); 6773 } 6774 6775 signalHeadName = b_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 6776 if (signalHeadName == null) { 6777 signalHeadName = ""; 6778 } 6779 if (setB3WayHead.isSelected()) { 6780 if (isHeadOnPanel(b3WayHead) 6781 && (b3WayHead != getHeadFromName(layoutTurnoutA.getSignalC1Name()))) { 6782 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6783 Bundle.getMessage("SignalsError6", 6784 new Object[]{signalHeadName}), 6785 Bundle.getMessage("ErrorTitle"), 6786 JmriJOptionPane.ERROR_MESSAGE); 6787 return; 6788 } else { 6789 removeSignalHeadFromPanel(layoutTurnoutA.getSignalC1Name()); 6790 place3WayDivergingA(); 6791 removeAssignment(b3WayHead); 6792 layoutTurnoutA.setSignalC1Name(signalHeadName); 6793 needRedraw = true; 6794 } 6795 } else { 6796 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b3WayHead, layoutTurnoutA); 6797 if (assigned == LayoutTurnout.Geometry.NONE) { 6798 if (isHeadOnPanel(b3WayHead) 6799 && isHeadAssignedAnywhere(b3WayHead)) { 6800 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6801 Bundle.getMessage("SignalsError8", 6802 new Object[]{signalHeadName}), 6803 Bundle.getMessage("ErrorTitle"), 6804 JmriJOptionPane.ERROR_MESSAGE); 6805 return; 6806 } else { 6807 removeSignalHeadFromPanel(layoutTurnoutA.getSignalC1Name()); 6808 removeAssignment(b3WayHead); 6809 layoutTurnoutA.setSignalC1Name(signalHeadName); 6810 } 6811 //} else if (assigned != A1) { 6812 //need to figure out what to do in this case. 6813 } 6814 } 6815 6816 //place signals as requested at Turnout C 6817 signalHeadName = c_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 6818 if (signalHeadName == null) { 6819 signalHeadName = ""; 6820 } 6821 if (setC3WayHead.isSelected()) { 6822 if (isHeadOnPanel(c3WayHead) 6823 && (c3WayHead != getHeadFromName(layoutTurnoutB.getSignalB1Name()))) { 6824 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6825 Bundle.getMessage("SignalsError6", 6826 new Object[]{signalHeadName}), 6827 Bundle.getMessage("ErrorTitle"), 6828 JmriJOptionPane.ERROR_MESSAGE); 6829 return; 6830 } else { 6831 removeSignalHeadFromPanel(layoutTurnoutB.getSignalB1Name()); 6832 place3WayContinuing(); 6833 removeAssignment(c3WayHead); 6834 layoutTurnoutB.setSignalB1Name(signalHeadName); 6835 needRedraw = true; 6836 } 6837 } else { 6838 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c3WayHead, layoutTurnoutB); 6839 if (assigned == LayoutTurnout.Geometry.NONE) { 6840 if (isHeadOnPanel(c3WayHead) 6841 && isHeadAssignedAnywhere(c3WayHead)) { 6842 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6843 Bundle.getMessage("SignalsError8", 6844 new Object[]{signalHeadName}), 6845 Bundle.getMessage("ErrorTitle"), 6846 JmriJOptionPane.ERROR_MESSAGE); 6847 return; 6848 } else { 6849 removeSignalHeadFromPanel(layoutTurnoutB.getSignalB1Name()); 6850 removeAssignment(c3WayHead); 6851 layoutTurnoutB.setSignalB1Name(signalHeadName); 6852 } 6853 //} else if (assigned != B1) { 6854 //need to figure out what to do in this case. 6855 } 6856 } 6857 6858 signalHeadName = d_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 6859 if (signalHeadName == null) { 6860 signalHeadName = ""; 6861 } 6862 if (setD3WayHead.isSelected()) { 6863 if (isHeadOnPanel(d3WayHead) 6864 && (d3WayHead != getHeadFromName(layoutTurnoutB.getSignalC1Name()))) { 6865 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6866 Bundle.getMessage("SignalsError6", 6867 new Object[]{signalHeadName}), 6868 Bundle.getMessage("ErrorTitle"), 6869 JmriJOptionPane.ERROR_MESSAGE); 6870 return; 6871 } else { 6872 removeSignalHeadFromPanel(layoutTurnoutB.getSignalC1Name()); 6873 place3WayDivergingB(); 6874 removeAssignment(d3WayHead); 6875 layoutTurnoutB.setSignalC1Name(signalHeadName); 6876 needRedraw = true; 6877 } 6878 } else { 6879 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d3WayHead, layoutTurnoutB); 6880 if (assigned == LayoutTurnout.Geometry.NONE) { 6881 if (isHeadOnPanel(d3WayHead) 6882 && isHeadAssignedAnywhere(d3WayHead)) { 6883 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 6884 Bundle.getMessage("SignalsError8", 6885 new Object[]{signalHeadName}), 6886 Bundle.getMessage("ErrorTitle"), 6887 JmriJOptionPane.ERROR_MESSAGE); 6888 return; 6889 } else { 6890 removeSignalHeadFromPanel(layoutTurnoutB.getSignalC1Name()); 6891 removeAssignment(d3WayHead); 6892 layoutTurnoutB.setSignalC1Name(signalHeadName); 6893 } 6894 //} else if (assigned != C1) { 6895 //need to figure out what to do in this case. 6896 } 6897 } 6898 //setup Logic if requested and enough information is available 6899 if (setupA13WayLogic.isSelected()) { 6900 set3WayLogicThroatContinuing(); 6901 } 6902 if ((a23WayHead != null) && setupA23WayLogic.isSelected()) { 6903 set3WayLogicThroatDivergingA(); 6904 } 6905 if ((a33WayHead != null) && setupA33WayLogic.isSelected()) { 6906 set3WayLogicThroatDivergingB(); 6907 } 6908 if (setupB3WayLogic.isSelected()) { 6909 set3WayLogicDivergingA(); 6910 } 6911 if (setupC3WayLogic.isSelected()) { 6912 set3WayLogicContinuing(); 6913 } 6914 if (setupD3WayLogic.isSelected()) { 6915 set3WayLogicDivergingB(); 6916 } 6917 //link the two turnouts 6918 signalHeadName = turnoutBComboBox.getSelectedItemDisplayName(); 6919 if (signalHeadName == null) { 6920 signalHeadName = ""; 6921 } 6922 layoutTurnoutA.setLinkedTurnoutName(signalHeadName); 6923 layoutTurnoutA.setLinkType(LayoutTurnout.LinkType.FIRST_3_WAY); 6924 signalHeadName = turnoutAComboBox.getSelectedItemDisplayName(); 6925 if (signalHeadName == null) { 6926 signalHeadName = ""; 6927 } 6928 layoutTurnoutB.setLinkedTurnoutName(signalHeadName); 6929 layoutTurnoutB.setLinkType(LayoutTurnout.LinkType.SECOND_3_WAY); 6930 //finish up 6931 setSignalsAt3WayTurnoutOpenFlag = false; 6932 setSignalsAt3WayTurnoutFrame.setVisible(false); 6933 if (needRedraw) { 6934 layoutEditor.redrawPanel(); 6935 needRedraw = false; 6936 layoutEditor.setDirty(); 6937 } 6938 } //set3WaySignalsDonePressed 6939 6940 private boolean get3WaySignalHeadInformation() { 6941 a13WayHead = getSignalHeadFromEntry(a1_3WaySignalHeadComboBox, true, setSignalsAt3WayTurnoutFrame); 6942 if (a13WayHead == null) { 6943 return false; 6944 } 6945 a23WayHead = getSignalHeadFromEntry(a2_3WaySignalHeadComboBox, false, setSignalsAt3WayTurnoutFrame); 6946 a33WayHead = getSignalHeadFromEntry(a3_3WaySignalHeadComboBox, false, setSignalsAt3WayTurnoutFrame); 6947 if (((a23WayHead == null) && (a33WayHead != null)) || ((a33WayHead == null) 6948 && (a23WayHead != null))) { 6949 return false; 6950 } 6951 b3WayHead = getSignalHeadFromEntry(b_3WaySignalHeadComboBox, true, setSignalsAt3WayTurnoutFrame); 6952 if (b3WayHead == null) { 6953 return false; 6954 } 6955 c3WayHead = getSignalHeadFromEntry(c_3WaySignalHeadComboBox, true, setSignalsAt3WayTurnoutFrame); 6956 if (c3WayHead == null) { 6957 return false; 6958 } 6959 d3WayHead = getSignalHeadFromEntry(d_3WaySignalHeadComboBox, true, setSignalsAt3WayTurnoutFrame); 6960 if (d3WayHead == null) { 6961 return false; 6962 } 6963 return true; 6964 } 6965 6966 private void place3WayThroatContinuing() { 6967 if (testIcon == null) { 6968 testIcon = signalIconEditor.getIcon(0); 6969 } 6970 String signalHeadName = a1_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 6971 if (signalHeadName == null) { 6972 signalHeadName = ""; 6973 } 6974 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 6975 6976 LayoutTurnoutView layoutTurnoutAView = layoutEditor.getLayoutTurnoutView(layoutTurnoutA); 6977 Point2D coordsA = layoutTurnoutAView.getCoordsA(); 6978 Point2D coordsCenter = layoutTurnoutAView.getCoordsCenter(); 6979 6980 double aDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsA, coordsCenter)); 6981 Point2D delta = new Point2D.Double(-shift, -shift); 6982 6983 delta = MathUtil.rotateDEG(delta, aDirDEG); 6984 Point2D where = MathUtil.add(coordsA, delta); 6985 setSignalHeadOnPanel(aDirDEG, signalHeadName, where); 6986 } 6987 6988 private void place3WayThroatDivergingA() { 6989 if (testIcon == null) { 6990 testIcon = signalIconEditor.getIcon(0); 6991 } 6992 String signalHeadName = a2_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 6993 if (signalHeadName == null) { 6994 signalHeadName = ""; 6995 } 6996 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 6997 6998 LayoutTurnoutView layoutTurnoutAView = layoutEditor.getLayoutTurnoutView(layoutTurnoutA); 6999 Point2D coordsA = layoutTurnoutAView.getCoordsA(); 7000 Point2D coordsCenter = layoutTurnoutAView.getCoordsCenter(); 7001 7002 double aDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsA, coordsCenter)); 7003 Point2D delta = new Point2D.Double(+shift, -shift); 7004 7005 delta = MathUtil.rotateDEG(delta, aDirDEG); 7006 Point2D where = MathUtil.add(coordsA, delta); 7007 setSignalHeadOnPanel(aDirDEG, signalHeadName, where); 7008 } 7009 7010 private void place3WayThroatDivergingB() { 7011 if (testIcon == null) { 7012 testIcon = signalIconEditor.getIcon(0); 7013 } 7014 String signalHeadName = a3_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7015 if (signalHeadName == null) { 7016 signalHeadName = ""; 7017 } 7018 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 7019 7020 LayoutTurnoutView layoutTurnoutAView = layoutEditor.getLayoutTurnoutView(layoutTurnoutA); 7021 Point2D coordsA = layoutTurnoutAView.getCoordsA(); 7022 Point2D coordsCenter = layoutTurnoutAView.getCoordsCenter(); 7023 7024 double aDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsA, coordsCenter)); 7025 Point2D delta = new Point2D.Double(+3.0 * shift, -shift); 7026 7027 delta = MathUtil.rotateDEG(delta, aDirDEG); 7028 Point2D where = MathUtil.add(coordsA, delta); 7029 setSignalHeadOnPanel(aDirDEG, signalHeadName, where); 7030 } 7031 7032 private void place3WayDivergingA() { 7033 if (testIcon == null) { 7034 testIcon = signalIconEditor.getIcon(0); 7035 } 7036 String signalHeadName = b_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7037 if (signalHeadName == null) { 7038 signalHeadName = ""; 7039 } 7040 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 7041 7042 LayoutTurnoutView layoutTurnoutAView = layoutEditor.getLayoutTurnoutView(layoutTurnoutA); 7043 Point2D coordsB = layoutTurnoutAView.getCoordsB(); 7044 Point2D coordsC = layoutTurnoutAView.getCoordsC(); 7045 Point2D coordsCenter = layoutTurnoutAView.getCoordsCenter(); 7046 7047 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 7048 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 7049 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 7050 double shiftX = shift; 7051 if (diffDirDEG >= 0.0) { 7052 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 7053 } 7054 Point2D delta = new Point2D.Double(shiftX, -shift); 7055 7056 delta = MathUtil.rotateDEG(delta, cDirDEG); 7057 Point2D where = MathUtil.add(coordsC, delta); 7058 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 7059 } 7060 7061 private void place3WayContinuing() { 7062 if (testIcon == null) { 7063 testIcon = signalIconEditor.getIcon(0); 7064 } 7065 String signalHeadName = c_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7066 if (signalHeadName == null) { 7067 signalHeadName = ""; 7068 } 7069 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 7070 7071 LayoutTurnoutView layoutTurnoutBView = layoutEditor.getLayoutTurnoutView(layoutTurnoutB); 7072 Point2D coordsB = layoutTurnoutBView.getCoordsB(); 7073 Point2D coordsC = layoutTurnoutBView.getCoordsC(); 7074 Point2D coordsCenter = layoutTurnoutBView.getCoordsCenter(); 7075 7076 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 7077 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 7078 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 7079 double shiftX = shift; 7080 if (diffDirDEG >= 0.0) { 7081 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 7082 } 7083 Point2D delta = new Point2D.Double(shiftX, -shift); 7084 7085 delta = MathUtil.rotateDEG(delta, bDirDEG); 7086 Point2D where = MathUtil.add(coordsB, delta); 7087 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 7088 } 7089 7090 private void place3WayDivergingB() { 7091 if (testIcon == null) { 7092 testIcon = signalIconEditor.getIcon(0); 7093 } 7094 String signalHeadName = d_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7095 if (signalHeadName == null) { 7096 signalHeadName = ""; 7097 } 7098 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 7099 7100 LayoutTurnoutView layoutTurnoutBView = layoutEditor.getLayoutTurnoutView(layoutTurnoutB); 7101 Point2D coordsC = layoutTurnoutBView.getCoordsC(); 7102 Point2D coordsB = layoutTurnoutBView.getCoordsB(); 7103 Point2D coordsCenter = layoutTurnoutBView.getCoordsCenter(); 7104 7105 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 7106 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 7107 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 7108 double shiftX = shift; 7109 if (diffDirDEG >= 0.0) { 7110 shiftX += shift * Math.cos(Math.toRadians(diffDirDEG)); 7111 } 7112 Point2D delta = new Point2D.Double(shiftX, -shift); 7113 7114 delta = MathUtil.rotateDEG(delta, cDirDEG); 7115 Point2D where = MathUtil.add(coordsC, delta); 7116 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 7117 } 7118 7119 private void set3WayLogicThroatContinuing() { 7120 TrackSegment track = (TrackSegment) layoutTurnoutB.getConnectB(); 7121 if (track == null) { 7122 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7123 Bundle.getMessage("InfoMessage7"), 7124 Bundle.getMessage("MessageTitle"), 7125 JmriJOptionPane.INFORMATION_MESSAGE); 7126 return; 7127 } 7128 LayoutBlock block = track.getLayoutBlock(); 7129 if (block == null) { 7130 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7131 Bundle.getMessage("InfoMessage6"), 7132 Bundle.getMessage("MessageTitle"), 7133 JmriJOptionPane.INFORMATION_MESSAGE); 7134 return; 7135 } 7136 Sensor occupancy = block.getOccupancySensor(); 7137 if (occupancy == null) { 7138 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7139 Bundle.getMessage("InfoMessage4", 7140 new Object[]{block.getUserName()}), 7141 Bundle.getMessage("MessageTitle"), 7142 JmriJOptionPane.INFORMATION_MESSAGE); 7143 return; 7144 } 7145 String signalHeadName = a1_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7146 if (signalHeadName == null) { 7147 signalHeadName = ""; 7148 } 7149 SignalHead nextHead = getNextSignalFromObject(track, layoutTurnoutB, 7150 signalHeadName, setSignalsAt3WayTurnoutFrame); 7151 if ((nextHead == null) && (!reachedEndBumper())) { 7152 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7153 Bundle.getMessage("InfoMessage5", 7154 new Object[]{block.getUserName()}), 7155 Bundle.getMessage("MessageTitle"), 7156 JmriJOptionPane.INFORMATION_MESSAGE); 7157 return; 7158 } 7159 if (a23WayHead != null) { 7160 //set up logic for continuing head with 3 heads at throat 7161 if (!initializeBlockBossLogic(signalHeadName)) { 7162 return; 7163 } 7164 logic.setMode(BlockBossLogic.TRAILINGMAIN); 7165 logic.setTurnout(turnoutB.getDisplayName()); 7166 logic.setSensor1(occupancy.getDisplayName()); 7167 if (nextHead != null) { 7168 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 7169 } 7170 if (auxSignal != null) { 7171 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 7172 } 7173 String nearSensorName = setupNearLogix(layoutTurnoutA, true, a13WayHead); 7174 addNearSensorToLogic(nearSensorName); 7175 finalizeBlockBossLogic(); 7176 return; 7177 } 7178 //only one head at the throat 7179 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7180 Bundle.getMessage("InfoMessage9"), 7181 Bundle.getMessage("MessageTitle"), 7182 JmriJOptionPane.INFORMATION_MESSAGE); 7183 return; 7184 } //set3WayLogicThroatContinuing 7185 7186 private void set3WayLogicThroatDivergingA() { 7187 TrackSegment track = (TrackSegment) layoutTurnoutA.getConnectC(); 7188 if (track == null) { 7189 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7190 Bundle.getMessage("InfoMessage7"), 7191 Bundle.getMessage("MessageTitle"), 7192 JmriJOptionPane.INFORMATION_MESSAGE); 7193 return; 7194 } 7195 LayoutBlock block = track.getLayoutBlock(); 7196 if (block == null) { 7197 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7198 Bundle.getMessage("InfoMessage6"), 7199 Bundle.getMessage("MessageTitle"), 7200 JmriJOptionPane.INFORMATION_MESSAGE); 7201 return; 7202 } 7203 Sensor occupancy = block.getOccupancySensor(); 7204 if (occupancy == null) { 7205 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7206 Bundle.getMessage("InfoMessage4", 7207 new Object[]{block.getUserName()}), 7208 Bundle.getMessage("MessageTitle"), 7209 JmriJOptionPane.INFORMATION_MESSAGE); 7210 return; 7211 } 7212 String signalHeadName = a2_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7213 if (signalHeadName == null) { 7214 signalHeadName = ""; 7215 } 7216 SignalHead nextHead = getNextSignalFromObject(track, layoutTurnoutA, 7217 signalHeadName, setSignalsAt3WayTurnoutFrame); 7218 if ((nextHead == null) && (!reachedEndBumper())) { 7219 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7220 Bundle.getMessage("InfoMessage5", 7221 new Object[]{block.getUserName()}), 7222 Bundle.getMessage("MessageTitle"), 7223 JmriJOptionPane.INFORMATION_MESSAGE); 7224 return; 7225 } 7226 if (!initializeBlockBossLogic(signalHeadName)) { 7227 return; 7228 } 7229 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 7230 logic.setTurnout(turnoutA.getDisplayName()); 7231 logic.setSensor1(occupancy.getDisplayName()); 7232 if (nextHead != null) { 7233 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 7234 } 7235 if (auxSignal != null) { 7236 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 7237 } 7238 if (!layoutTurnoutA.isMainlineC()) { 7239 logic.setLimitSpeed2(true); 7240 } 7241 finalizeBlockBossLogic(); 7242 } //set3WayLogicThroatDivergingA 7243 7244 private void set3WayLogicThroatDivergingB() { 7245 TrackSegment track = (TrackSegment) layoutTurnoutB.getConnectC(); 7246 if (track == null) { 7247 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7248 Bundle.getMessage("InfoMessage7"), 7249 Bundle.getMessage("MessageTitle"), 7250 JmriJOptionPane.INFORMATION_MESSAGE); 7251 return; 7252 } 7253 LayoutBlock block = track.getLayoutBlock(); 7254 if (block == null) { 7255 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7256 Bundle.getMessage("InfoMessage6"), 7257 Bundle.getMessage("MessageTitle"), 7258 JmriJOptionPane.INFORMATION_MESSAGE); 7259 return; 7260 } 7261 Sensor occupancy = block.getOccupancySensor(); 7262 if (occupancy == null) { 7263 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7264 Bundle.getMessage("InfoMessage4", 7265 new Object[]{block.getUserName()}), 7266 Bundle.getMessage("MessageTitle"), 7267 JmriJOptionPane.INFORMATION_MESSAGE); 7268 return; 7269 } 7270 String signalHeadName = a3_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7271 if (signalHeadName == null) { 7272 signalHeadName = ""; 7273 } 7274 SignalHead nextHead = getNextSignalFromObject(track, layoutTurnoutB, 7275 signalHeadName, setSignalsAt3WayTurnoutFrame); 7276 if ((nextHead == null) && (!reachedEndBumper())) { 7277 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7278 Bundle.getMessage("InfoMessage5", 7279 new Object[]{block.getUserName()}), 7280 Bundle.getMessage("MessageTitle"), 7281 JmriJOptionPane.INFORMATION_MESSAGE); 7282 return; 7283 } 7284 if (!initializeBlockBossLogic(signalHeadName)) { 7285 return; 7286 } 7287 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 7288 logic.setTurnout(turnoutB.getDisplayName()); 7289 logic.setSensor1(occupancy.getDisplayName()); 7290 if (nextHead != null) { 7291 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 7292 } 7293 if (auxSignal != null) { 7294 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 7295 } 7296 String nearSensorName = setupNearLogix(layoutTurnoutA, true, a33WayHead); 7297 addNearSensorToLogic(nearSensorName); 7298 if (!layoutTurnoutB.isMainlineC()) { 7299 logic.setLimitSpeed2(true); 7300 } 7301 finalizeBlockBossLogic(); 7302 } //set3WayLogicThroatDivergingB 7303 7304 private void set3WayLogicDivergingA() { 7305 TrackSegment track = (TrackSegment) layoutTurnoutA.getConnectA(); 7306 if (track == null) { 7307 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7308 Bundle.getMessage("InfoMessage7"), 7309 Bundle.getMessage("MessageTitle"), 7310 JmriJOptionPane.INFORMATION_MESSAGE); 7311 return; 7312 } 7313 LayoutBlock block = track.getLayoutBlock(); 7314 if (block == null) { 7315 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7316 Bundle.getMessage("InfoMessage6"), 7317 Bundle.getMessage("MessageTitle"), 7318 JmriJOptionPane.INFORMATION_MESSAGE); 7319 return; 7320 } 7321 Sensor occupancy = block.getOccupancySensor(); 7322 if (occupancy == null) { 7323 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7324 Bundle.getMessage("InfoMessage4", 7325 new Object[]{block.getUserName()}), 7326 Bundle.getMessage("MessageTitle"), 7327 JmriJOptionPane.INFORMATION_MESSAGE); 7328 return; 7329 } 7330 String signalHeadName = b_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7331 if (signalHeadName == null) { 7332 signalHeadName = ""; 7333 } 7334 SignalHead nextHead = getNextSignalFromObject(track, layoutTurnoutA, 7335 signalHeadName, setSignalsAt3WayTurnoutFrame); 7336 if ((nextHead == null) && (!reachedEndBumper())) { 7337 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7338 Bundle.getMessage("InfoMessage5", 7339 new Object[]{block.getUserName()}), 7340 Bundle.getMessage("MessageTitle"), 7341 JmriJOptionPane.INFORMATION_MESSAGE); 7342 return; 7343 } 7344 if (!initializeBlockBossLogic(signalHeadName)) { 7345 return; 7346 } 7347 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 7348 logic.setTurnout(turnoutA.getDisplayName()); 7349 logic.setSensor1(occupancy.getDisplayName()); 7350 if (nextHead != null) { 7351 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 7352 } 7353 if (auxSignal != null) { 7354 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 7355 } 7356 if (!layoutTurnoutA.isMainlineC()) { 7357 logic.setLimitSpeed2(true); 7358 } 7359 finalizeBlockBossLogic(); 7360 } //set3WayLogicDivergingA 7361 7362 private void set3WayLogicContinuing() { 7363 TrackSegment track = (TrackSegment) layoutTurnoutA.getConnectA(); 7364 if (track == null) { 7365 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7366 Bundle.getMessage("InfoMessage7"), 7367 Bundle.getMessage("MessageTitle"), 7368 JmriJOptionPane.INFORMATION_MESSAGE); 7369 return; 7370 } 7371 LayoutBlock block = track.getLayoutBlock(); 7372 if (block == null) { 7373 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7374 Bundle.getMessage("InfoMessage6"), 7375 Bundle.getMessage("MessageTitle"), 7376 JmriJOptionPane.INFORMATION_MESSAGE); 7377 return; 7378 } 7379 Sensor occupancy = block.getOccupancySensor(); 7380 if (occupancy == null) { 7381 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7382 Bundle.getMessage("InfoMessage4", 7383 new Object[]{block.getUserName()}), 7384 Bundle.getMessage("MessageTitle"), 7385 JmriJOptionPane.INFORMATION_MESSAGE); 7386 return; 7387 } 7388 String signalHeadName = c_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7389 if (signalHeadName == null) { 7390 signalHeadName = ""; 7391 } 7392 SignalHead nextHead = getNextSignalFromObject(track, layoutTurnoutA, 7393 signalHeadName, setSignalsAt3WayTurnoutFrame); 7394 if ((nextHead == null) && (!reachedEndBumper())) { 7395 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7396 Bundle.getMessage("InfoMessage5", 7397 new Object[]{block.getUserName()}), 7398 Bundle.getMessage("MessageTitle"), 7399 JmriJOptionPane.INFORMATION_MESSAGE); 7400 return; 7401 } 7402 if (!initializeBlockBossLogic(signalHeadName)) { 7403 return; 7404 } 7405 logic.setMode(BlockBossLogic.TRAILINGMAIN); 7406 logic.setTurnout(turnoutB.getDisplayName()); 7407 logic.setSensor1(occupancy.getDisplayName()); 7408 if (nextHead != null) { 7409 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 7410 } 7411 if (auxSignal != null) { 7412 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 7413 } 7414 String nearSensorName = setupNearLogix(layoutTurnoutA, true, c3WayHead); 7415 addNearSensorToLogic(nearSensorName); 7416 if (!layoutTurnoutB.isMainlineB()) { 7417 logic.setLimitSpeed2(true); 7418 } 7419 finalizeBlockBossLogic(); 7420 } //set3WayLogicContinuing 7421 7422 private void set3WayLogicDivergingB() { 7423 TrackSegment track = (TrackSegment) layoutTurnoutA.getConnectA(); 7424 if (track == null) { 7425 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7426 Bundle.getMessage("InfoMessage7"), 7427 Bundle.getMessage("MessageTitle"), 7428 JmriJOptionPane.INFORMATION_MESSAGE); 7429 return; 7430 } 7431 LayoutBlock block = track.getLayoutBlock(); 7432 if (block == null) { 7433 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7434 Bundle.getMessage("InfoMessage6"), 7435 Bundle.getMessage("MessageTitle"), 7436 JmriJOptionPane.INFORMATION_MESSAGE); 7437 return; 7438 } 7439 Sensor occupancy = block.getOccupancySensor(); 7440 if (occupancy == null) { 7441 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7442 Bundle.getMessage("InfoMessage4", 7443 new Object[]{block.getUserName()}), 7444 Bundle.getMessage("MessageTitle"), 7445 JmriJOptionPane.INFORMATION_MESSAGE); 7446 return; 7447 } 7448 String signalHeadName = d_3WaySignalHeadComboBox.getSelectedItemDisplayName(); 7449 if (signalHeadName == null) { 7450 signalHeadName = ""; 7451 } 7452 SignalHead nextHead = getNextSignalFromObject(track, layoutTurnoutA, 7453 signalHeadName, setSignalsAt3WayTurnoutFrame); 7454 if ((nextHead == null) && (!reachedEndBumper())) { 7455 JmriJOptionPane.showMessageDialog(setSignalsAt3WayTurnoutFrame, 7456 Bundle.getMessage("InfoMessage5", 7457 new Object[]{block.getUserName()}), 7458 Bundle.getMessage("MessageTitle"), 7459 JmriJOptionPane.INFORMATION_MESSAGE); 7460 return; 7461 } 7462 if (!initializeBlockBossLogic(signalHeadName)) { 7463 return; 7464 } 7465 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 7466 logic.setTurnout(turnoutB.getDisplayName()); 7467 logic.setSensor1(occupancy.getDisplayName()); 7468 if (nextHead != null) { 7469 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 7470 } 7471 if (auxSignal != null) { 7472 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 7473 } 7474 String nearSensorName = setupNearLogix(layoutTurnoutA, true, d3WayHead); 7475 addNearSensorToLogic(nearSensorName); 7476 if (!layoutTurnoutB.isMainlineC()) { 7477 logic.setLimitSpeed2(true); 7478 } 7479 finalizeBlockBossLogic(); 7480 } //set3WayLogicDivergingB 7481 7482 /*===========================*\ 7483 |* setSensorsAtBlockBoundary *| 7484 \*===========================*/ 7485 // 7486 //The following is for placement of sensors and signal masts at points around the layout 7487 // 7488 //This section deals with assigning a sensor to a specific boundary point 7489 BeanDetails<Sensor> westBoundSensor; 7490 BeanDetails<Sensor> eastBoundSensor; 7491 7492 private JmriJFrame setSensorsAtBlockBoundaryFrame = null; 7493 private boolean setSensorsAtBlockBoundaryOpenFlag = false; 7494 private boolean setSensorsAtBlockBoundaryFromMenuFlag = false; 7495 7496 private JButton getAnchorSavedSensors = null; 7497 private JButton changeSensorAtBoundaryIcon = null; 7498 private JButton setSensorsAtBlockBoundaryDone = null; 7499 private JButton setSensorsAtBlockBoundaryCancel = null; 7500 7501 private JFrame sensorFrame = null; 7502 private MultiIconEditor sensorIconEditor = null; 7503 7504 JPanel sensorBlockPanel = new JPanel(new FlowLayout()); 7505 7506 public void setSensorsAtBlockBoundaryFromMenu(@Nonnull PositionablePoint p, 7507 @Nonnull MultiIconEditor theEditor, 7508 @Nonnull JFrame theFrame) { 7509 boundary = p; 7510 block1IDComboBox.setSelectedItem(boundary.getConnect1().getLayoutBlock().getBlock()); 7511 if (boundary.getConnect2() == null) { 7512 block2IDComboBox.setSelectedItem(boundary.getConnect1().getLayoutBlock().getBlock()); 7513 } else { 7514 block2IDComboBox.setSelectedItem(boundary.getConnect2().getLayoutBlock().getBlock()); 7515 } 7516 setSensorsAtBlockBoundaryFromMenuFlag = true; 7517 setSensorsAtBlockBoundary(theEditor, theFrame); 7518 setSensorsAtBlockBoundaryFromMenuFlag = false; 7519 } 7520 7521 //TODO: Add to Tools menu? 7522 public void setSensorsAtBlockBoundary(@Nonnull MultiIconEditor theEditor, 7523 @Nonnull JFrame theFrame) { 7524 sensorIconEditor = theEditor; 7525 sensorFrame = theFrame; 7526 7527 //Initialize if needed 7528 if (setSensorsAtBlockBoundaryFrame == null) { 7529 setSensorsAtBlockBoundaryOpenFlag = false; 7530 7531 westBoundSensor = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 7532 eastBoundSensor = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 7533 7534 setSensorsAtBlockBoundaryFrame = new JmriJFrame(Bundle.getMessage("SensorsAtBoundary"), false, true); 7535 oneFrameToRuleThemAll(setSensorsAtBlockBoundaryFrame); 7536 setSensorsAtBlockBoundaryFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 7537// setSensorsAtBlockBoundaryFrame.addHelpMenu("package.jmri.jmrit.display.SetSensorsAtBoundary", true); 7538 setSensorsAtBlockBoundaryFrame.setLocation(70, 30); 7539 Container theContentPane = setSensorsAtBlockBoundaryFrame.getContentPane(); 7540 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 7541 7542 JPanel header = new JPanel(); 7543 header.setLayout(new BoxLayout(header, BoxLayout.Y_AXIS)); 7544 7545 JPanel panel11 = new JPanel(new FlowLayout()); 7546 block1NameLabel = new JLabel(Bundle.getMessage("MakeLabel", 7547 Bundle.getMessage("BeanNameBlock") + " 1 - " 7548 + Bundle.getMessage("Name"))); 7549 panel11.add(block1NameLabel); 7550 7551 panel11.add(block1IDComboBox); 7552 block1IDComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 7553 header.add(panel11); 7554 7555 JPanel panel12 = new JPanel(new FlowLayout()); 7556 block2NameLabel = new JLabel(Bundle.getMessage("MakeLabel", 7557 Bundle.getMessage("BeanNameBlock") + " 2 - " 7558 + Bundle.getMessage("Name"))); 7559 panel12.add(block2NameLabel); 7560 7561 panel12.add(block2IDComboBox); 7562 block2IDComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 7563 header.add(panel12); 7564 7565 header.add(new JSeparator(JSeparator.HORIZONTAL)); 7566 theContentPane.add(header); 7567 7568 JPanel panel2 = new JPanel(new FlowLayout()); 7569 JLabel shTitle = new JLabel(Bundle.getMessage("Sensors")); 7570 panel2.add(shTitle); 7571 panel2.add(new JLabel(" ")); 7572 panel2.add(getAnchorSavedSensors = new JButton(Bundle.getMessage("GetSaved"))); 7573 getAnchorSavedSensors.addActionListener(this::getSavedAnchorSensors); 7574 getAnchorSavedSensors.setToolTipText(Bundle.getMessage("GetSavedHint")); 7575 theContentPane.add(panel2); 7576 7577 sensorBlockPanel.setLayout(new GridLayout(0, 1)); 7578 theContentPane.add(sensorBlockPanel); 7579 7580 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 7581 7582 JPanel panel6 = new JPanel(new FlowLayout()); 7583 panel6.add(changeSensorAtBoundaryIcon = new JButton(Bundle.getMessage("ChangeSensorIcon"))); 7584 changeSensorAtBoundaryIcon.addActionListener((ActionEvent e) -> sensorFrame.setVisible(true)); 7585 changeSensorAtBoundaryIcon.setToolTipText(Bundle.getMessage("ChangeSensorIconHint")); 7586 panel6.add(new JLabel(" ")); 7587 panel6.add(setSensorsAtBlockBoundaryDone = new JButton(Bundle.getMessage("ButtonDone"))); 7588 setSensorsAtBlockBoundaryDone.addActionListener(this::setSensorsAtBlockBoundaryDonePressed); 7589 setSensorsAtBlockBoundaryDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 7590 7591 panel6.add(setSensorsAtBlockBoundaryCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 7592 setSensorsAtBlockBoundaryCancel.addActionListener(this::setSensorsAtBlockBoundaryCancelPressed); 7593 setSensorsAtBlockBoundaryCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 7594 theContentPane.add(panel6, BorderLayout.SOUTH); 7595 7596//make this button the default button (return or enter activates) 7597 JRootPane rootPane = SwingUtilities.getRootPane(setSensorsAtBlockBoundaryDone); 7598 if (rootPane != null) { 7599 rootPane.setDefaultButton(setSensorsAtBlockBoundaryDone); 7600 } 7601 7602 setSensorsAtBlockBoundaryFrame.addWindowListener(new WindowAdapter() { 7603 @Override 7604 public void windowClosing(WindowEvent e) { 7605 setSensorsAtBlockBoundaryCancelPressed(null); 7606 } 7607 }); 7608 } 7609 7610 sensorBlockPanel.removeAll(); 7611 7612 if (boundary.getType() != PositionablePoint.PointType.END_BUMPER) { 7613 eastBoundSensor.setBoundaryTitle(Bundle.getMessage("East/SouthBound")); 7614 if ((setSensorsAtBlockBoundaryFromMenuFlag) && (boundary.getType() == PositionablePoint.PointType.ANCHOR)) { 7615 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 7616 eastBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect2().getLayoutBlock().getDisplayName()); 7617 } else { 7618 eastBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 7619 } 7620 } 7621 eastBoundSensor.getDetailsPanel().setBackground(new Color(255, 255, 200)); 7622 sensorBlockPanel.add(eastBoundSensor.getDetailsPanel()); 7623 7624 westBoundSensor.setBoundaryTitle(Bundle.getMessage("West/NorthBound")); 7625 if (setSensorsAtBlockBoundaryFromMenuFlag) { 7626 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 7627 westBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 7628 } else { 7629 westBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect2().getLayoutBlock().getDisplayName()); 7630 } 7631 } 7632 westBoundSensor.getDetailsPanel().setBackground(new Color(200, 255, 255)); 7633 sensorBlockPanel.add(westBoundSensor.getDetailsPanel()); 7634 } else { 7635 if (setSensorsAtBlockBoundaryFromMenuFlag) { 7636 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 7637 eastBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 7638 eastBoundSensor.getDetailsPanel().setBackground(new Color(200, 255, 255)); 7639 sensorBlockPanel.add(eastBoundSensor.getDetailsPanel()); 7640 } else { 7641 westBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 7642 westBoundSensor.getDetailsPanel().setBackground(new Color(255, 255, 200)); 7643 sensorBlockPanel.add(westBoundSensor.getDetailsPanel()); 7644 } 7645 } 7646 } 7647 7648 block1IDComboBox.setVisible(!setSensorsAtBlockBoundaryFromMenuFlag); 7649 block2IDComboBox.setVisible(!setSensorsAtBlockBoundaryFromMenuFlag); 7650 7651 if (setSensorsAtBlockBoundaryFromMenuFlag) { 7652 block1NameLabel.setText(Bundle.getMessage("MakeLabel", 7653 Bundle.getMessage("BeanNameBlock") + " 1 " 7654 + Bundle.getMessage("Name")) 7655 + " " + boundary.getConnect1().getLayoutBlock().getId()); 7656 if (boundary.getConnect2() != null) { 7657 block2NameLabel.setText(Bundle.getMessage("MakeLabel", 7658 Bundle.getMessage("BeanNameBlock") + " 2 " 7659 + Bundle.getMessage("Name")) 7660 + " " + boundary.getConnect2().getLayoutBlock().getId()); 7661 } 7662 getSavedAnchorSensors(null); 7663 } else { 7664 block1NameLabel.setText(Bundle.getMessage("MakeLabel", 7665 Bundle.getMessage("Name") + " 1 " 7666 + Bundle.getMessage("Name"))); 7667 block2NameLabel.setText(Bundle.getMessage("MakeLabel", 7668 Bundle.getMessage("Name") + " 2 " 7669 + Bundle.getMessage("Name"))); 7670 } 7671 //boundary should never be null... however, just in case... 7672 boolean enable = ((boundary != null) && (boundary.getType() != PositionablePoint.PointType.END_BUMPER)); 7673 block2NameLabel.setVisible(enable); 7674 7675 if (!setSensorsAtBlockBoundaryOpenFlag) { 7676 setSensorsAtBlockBoundaryFrame.setPreferredSize(null); 7677 setSensorsAtBlockBoundaryFrame.pack(); 7678 setSensorsAtBlockBoundaryOpenFlag = true; 7679 } 7680 setSensorsAtBlockBoundaryFrame.setVisible(true); 7681 } //setSensorsAtBlockBoundary 7682 7683 /** 7684 * Returns the Sensor corresponding to an entry field in the specified 7685 * dialog. 7686 * <p> 7687 * This also takes care of UpperCase and trimming of leading and 7688 * trailing blanks. 7689 * If entry is required, and no entry is present, an error message is sent. 7690 * An error message also results if a sensor head with the 7691 * entered name is not found in the SensorTable. 7692 * @param sensorName sensor name. 7693 * @param requireEntry true if mandatory field, else false. 7694 * @param frame the main frame. 7695 * @return sensor, may be null. 7696 */ 7697 @CheckReturnValue 7698 public Sensor getSensorFromEntry(@CheckForNull String sensorName, 7699 boolean requireEntry, 7700 @Nonnull JmriJFrame frame) { 7701 if ((sensorName == null) || sensorName.isEmpty()) { 7702 if (requireEntry) { 7703 JmriJOptionPane.showMessageDialog(frame, Bundle.getMessage("SensorsError5"), 7704 Bundle.getMessage("ErrorTitle"), 7705 JmriJOptionPane.ERROR_MESSAGE); 7706 } 7707 return null; 7708 } 7709 Sensor head = InstanceManager.sensorManagerInstance().getSensor(sensorName); 7710 if (head == null) { 7711 JmriJOptionPane.showMessageDialog(frame, 7712 Bundle.getMessage("SensorsError4", 7713 new Object[]{sensorName}), Bundle.getMessage("ErrorTitle"), 7714 JmriJOptionPane.ERROR_MESSAGE); 7715 return null; 7716 } 7717 return (head); 7718 } 7719 7720 @CheckReturnValue 7721 public SensorIcon getSensorIcon(@Nonnull String sensorName) { 7722 SensorIcon l = new SensorIcon(new NamedIcon("resources/icons/smallschematics/tracksegments/circuit-error.gif", 7723 "resources/icons/smallschematics/tracksegments/circuit-error.gif"), layoutEditor); 7724 l.setIcon("SensorStateActive", sensorIconEditor.getIcon(0)); 7725 l.setIcon("SensorStateInactive", sensorIconEditor.getIcon(1)); 7726 l.setIcon("BeanStateInconsistent", sensorIconEditor.getIcon(2)); 7727 l.setIcon("BeanStateUnknown", sensorIconEditor.getIcon(3)); 7728 l.setSensor(sensorName); 7729 return l; 7730 } 7731 7732 /** 7733 * Returns true if the specified Sensor is assigned to an object on the 7734 * panel, regardless of whether an icon is displayed or not. With sensors we 7735 * NO LONGER (4.11.2) allow the same sensor to be allocated in both 7736 * directions. 7737 * 7738 * @param sensor The sensor to be checked. 7739 * @return true if the sensor is currently assigned someplace. 7740 */ 7741 public boolean isSensorAssignedAnywhere(@Nonnull Sensor sensor) { 7742 boolean result = false; 7743 7744 //check positionable points 7745 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 7746 if (po.getEastBoundSensor() == sensor) { 7747 result = true; 7748 break; 7749 } 7750 if (po.getWestBoundSensor() == sensor) { 7751 result = true; 7752 break; 7753 } 7754 } 7755 if (!result) { 7756 //check turnouts and slips 7757 for (LayoutTurnout to : layoutEditor.getLayoutTurnoutsAndSlips()) { 7758 if (whereIsSensorAssigned(sensor, to) != LayoutTurnout.Geometry.NONE) { 7759 result = true; 7760 break; 7761 } 7762 } 7763 } 7764 if (!result) { 7765 //check level crossings 7766 for (LevelXing x : layoutEditor.getLevelXings()) { 7767 if ((x.getSensorA() != null) && x.getSensorA() == sensor) { 7768 result = true; 7769 break; 7770 } 7771 if ((x.getSensorB() != null) && x.getSensorB() == sensor) { 7772 result = true; 7773 break; 7774 } 7775 if ((x.getSensorC() != null) && x.getSensorC() == sensor) { 7776 result = true; 7777 break; 7778 } 7779 if ((x.getSensorD() != null) && x.getSensorD() == sensor) { 7780 result = true; 7781 break; 7782 } 7783 } 7784 } 7785 7786 return result; 7787 } //isSensorAssignedAnywhere 7788 7789 private LayoutTurnout.Geometry whereIsSensorAssigned(Sensor sensor, LayoutTurnout lTurnout) { 7790 LayoutTurnout.Geometry result = LayoutTurnout.Geometry.NONE; 7791 7792 if (sensor != null && lTurnout != null) { 7793 String sName = sensor.getSystemName(); 7794 String uName = sensor.getUserName(); 7795 7796 String name = lTurnout.getSensorAName(); 7797 if (!name.isEmpty() && name.equals(uName) || name.equals(sName)) { 7798 return LayoutTurnout.Geometry.POINTA1; 7799 } 7800 name = lTurnout.getSensorBName(); 7801 if (!name.isEmpty() && name.equals(uName) || name.equals(sName)) { 7802 return LayoutTurnout.Geometry.POINTA2; 7803 } 7804 name = lTurnout.getSensorCName(); 7805 if (!name.isEmpty() && name.equals(uName) || name.equals(sName)) { 7806 return LayoutTurnout.Geometry.POINTA3; 7807 } 7808 name = lTurnout.getSensorDName(); 7809 if (!name.isEmpty() && name.equals(uName) || name.equals(sName)) { 7810 return LayoutTurnout.Geometry.POINTB1; 7811 } 7812 } 7813 return result; 7814 } 7815 7816 /** 7817 * Display an error dialog. 7818 * 7819 * @param sensor The sensor that is already assigned. 7820 */ 7821 void sensorAssignedElseWhere(@Nonnull Sensor sensor) { 7822 JmriJOptionPane.showMessageDialog(setSensorsAtBlockBoundaryFrame, 7823 Bundle.getMessage("SensorsError6", // NOI18N 7824 new Object[]{sensor.getDisplayName()}), 7825 Bundle.getMessage("ErrorTitle"), 7826 JmriJOptionPane.ERROR_MESSAGE); // NOI18N 7827 } 7828 7829 /** 7830 * Removes the assignment of the specified Sensor to either a turnout, a 7831 * positionable point, or a level crossing wherever it is assigned. Removes 7832 * any NX Pairs that use the sensor. 7833 * <p> 7834 * If the NX deletes fail due to Conditional references or user deny, the 7835 * assignment is not deleted. No additional notification is necessary since 7836 * they have already been notified or made a choice to not continue. 7837 * 7838 * @param sensor The sensor to be removed. 7839 * @return true if the sensor has been removed. 7840 */ 7841 public boolean removeSensorAssignment(@Nonnull Sensor sensor) { 7842 log.trace("Remove sensor assignment at block boundary for '{}'", sensor.getDisplayName()); // NOI18N 7843 if (!InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class).deleteNxPair(sensor)) { 7844 log.trace("Removal of NX pairs for sensor '{}' failed", sensor.getDisplayName()); // NOI18N 7845 return false; 7846 } 7847 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 7848 if (po.getEastBoundSensor() == sensor) { 7849 po.setEastBoundSensor(null); 7850 } 7851 if (po.getWestBoundSensor() == sensor) { 7852 po.setWestBoundSensor(null); 7853 } 7854 } 7855 7856 for (LayoutTurnout to : layoutEditor.getLayoutTurnoutsAndSlips()) { 7857 if (to.getSensorA() == sensor) { 7858 to.setSensorA(null); 7859 } 7860 if (to.getSensorB() == sensor) { 7861 to.setSensorB(null); 7862 } 7863 if (to.getSensorC() == sensor) { 7864 to.setSensorC(null); 7865 } 7866 if (to.getSensorD() == sensor) { 7867 to.setSensorD(null); 7868 } 7869 } 7870 7871 for (LevelXing x : layoutEditor.getLevelXings()) { 7872 if (x.getSensorA() == sensor) { 7873 x.setSensorAName(null); 7874 } 7875 if (x.getSensorB() == sensor) { 7876 x.setSensorBName(null); 7877 } 7878 if (x.getSensorC() == sensor) { 7879 x.setSensorCName(null); 7880 } 7881 if (x.getSensorD() == sensor) { 7882 x.setSensorDName(null); 7883 } 7884 } 7885 7886 return true; 7887 } //removeSensorAssignment 7888 7889 /** 7890 * Removes the Sensor icon from the panel and from assignment to any 7891 * turnout, positionable point, or level crossing. 7892 * 7893 * @param sensor The sensor whose icon and references are to be removed. 7894 * @return true if the removal was successful. 7895 */ 7896 public boolean removeSensorFromPanel(@Nonnull Sensor sensor) { 7897 log.trace("Remove sensor icon and assignment for '{}'", sensor.getDisplayName()); // NOI18N 7898 if (!removeSensorAssignment(sensor)) { 7899 return false; 7900 } 7901 7902 SensorIcon h = null; 7903 int index = -1; 7904 for (int i = 0; (i < layoutEditor.getSensorList().size()) && (index == -1); i++) { 7905 h = layoutEditor.getSensorList().get(i); 7906 if (h.getSensor() == sensor) { 7907 index = i; 7908 } 7909 } 7910 if ((h != null) && (index != -1)) { 7911 layoutEditor.getSensorList().remove(index); 7912 h.remove(); 7913 h.dispose(); 7914 needRedraw = true; 7915 } 7916 return true; 7917 } 7918 7919 private void getSavedAnchorSensors(ActionEvent a) { 7920 if (!getSimpleBlockInformation()) { 7921 return; 7922 } 7923 eastBoundSensor.setTextField(boundary.getEastBoundSensorName()); 7924 westBoundSensor.setTextField(boundary.getWestBoundSensorName()); 7925 7926 if (boundary.getType() != PositionablePoint.PointType.END_BUMPER) { 7927 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 7928 eastBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect2().getLayoutBlock().getDisplayName()); 7929 } else { 7930 eastBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 7931 } 7932 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 7933 westBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 7934 } else { 7935 westBoundSensor.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect2().getLayoutBlock().getDisplayName()); 7936 } 7937 } else { 7938 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 7939 westBoundSensor.setBoundaryLabelText(Bundle.getMessage("EndOfBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 7940 } else { 7941 eastBoundSensor.setBoundaryLabelText(Bundle.getMessage("EndOfBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 7942 } 7943 } 7944 7945 setSensorsAtBlockBoundaryFrame.setPreferredSize(null); 7946 setSensorsAtBlockBoundaryFrame.pack(); 7947 } 7948 7949 private void setSensorsAtBlockBoundaryCancelPressed(ActionEvent a) { 7950 setSensorsAtBlockBoundaryOpenFlag = false; 7951 setSensorsAtBlockBoundaryFrame.setVisible(false); 7952 } 7953 7954 private void setSensorsAtBlockBoundaryDonePressed(ActionEvent a) { 7955 log.trace("setSensorsAtBlockBoundaryDonePressed"); // NOI18N 7956 if (!getSimpleBlockInformation()) { 7957 return; 7958 } 7959 7960 Sensor eastSensor = getSensorFromEntry(eastBoundSensor.getText(), false, setSensorsAtBlockBoundaryFrame); 7961 Sensor westSensor = getSensorFromEntry(westBoundSensor.getText(), false, setSensorsAtBlockBoundaryFrame); 7962 Sensor currEastSensor = InstanceManager.sensorManagerInstance().getSensor(boundary.getEastBoundSensorName()); 7963 Sensor currWestSensor = InstanceManager.sensorManagerInstance().getSensor(boundary.getWestBoundSensorName()); 7964 7965 if (log.isTraceEnabled()) { 7966 log.trace("current sensors: east = {}, west = {}", // NOI18N 7967 (currEastSensor == null) ? "- none- " : currEastSensor.getDisplayName(), // NOI18N 7968 (currWestSensor == null) ? "- none- " : currWestSensor.getDisplayName()); // NOI18N 7969 log.trace("new sensors: east = {}, west = {}", // NOI18N 7970 (eastSensor == null) ? "- none- " : eastSensor.getDisplayName(), // NOI18N 7971 (westSensor == null) ? "- none- " : westSensor.getDisplayName()); // NOI18N 7972 } 7973 7974 if (eastSensor == null) { 7975 if (currEastSensor != null && removeSensorFromPanel(currEastSensor)) { 7976 boundary.setEastBoundSensor(null); 7977 } 7978 } else if (eastBoundSensor != null) { 7979 setBoundarySensor(eastSensor, currEastSensor, eastBoundSensor, "East"); // NOI18N 7980 } 7981 7982 if (westSensor == null) { 7983 if (currWestSensor != null && removeSensorFromPanel(currWestSensor)) { 7984 boundary.setWestBoundSensor(null); 7985 } 7986 } else if (westBoundSensor != null) { 7987 setBoundarySensor(westSensor, currWestSensor, westBoundSensor, "West"); // NOI18N 7988 } 7989 7990 setSensorsAtBlockBoundaryOpenFlag = false; 7991 setSensorsAtBlockBoundaryFrame.setVisible(false); 7992 if (needRedraw) { 7993 layoutEditor.redrawPanel(); 7994 needRedraw = false; 7995 layoutEditor.setDirty(); 7996 } 7997 } 7998 7999 /** 8000 * Attached a sensor to the block boundary positional point. 8001 * 8002 * @since 4.11.2 8003 * @param newSensor The sensor that is being added. 8004 * @param currSensor The sensor that might already be there, otherwise null. 8005 * @param beanDetail The BeanDetails object that contains the supporting 8006 * data. 8007 * @param direction The direction, East or West. 8008 */ 8009 void setBoundarySensor(Sensor newSensor, Sensor currSensor, 8010 BeanDetails<Sensor> beanDetail, String direction) { 8011 if (currSensor == null) { 8012 if (!isSensorAssignedAnywhere(newSensor)) { 8013 log.trace("Add sensor '{}'", newSensor.getDisplayName()); // NOI18N 8014 if (direction.equals("West")) { // NOI18N 8015 boundary.setWestBoundSensor(beanDetail.getText()); 8016 } else { 8017 boundary.setEastBoundSensor(beanDetail.getText()); 8018 } 8019 if (beanDetail.addToPanel()) { 8020 log.trace("Add icon for sensor '{}'", newSensor.getDisplayName()); // NOI18N 8021 if (direction.equals("West")) { // NOI18N 8022 placeWestBoundIcon(getSensorIcon(beanDetail.getText()), 8023 beanDetail.isRightSelected(), 0.0); 8024 } else { 8025 placeEastBoundIcon(getSensorIcon(beanDetail.getText()), 8026 beanDetail.isRightSelected(), 0.0); 8027 } 8028 needRedraw = true; 8029 } 8030 } else { 8031 sensorAssignedElseWhere(newSensor); 8032 } 8033 } else if (currSensor == newSensor) { 8034 if (beanDetail.addToPanel()) { 8035 if (!isSensorOnPanel(newSensor)) { 8036 log.trace("Add icon for existing sensor '{}'", newSensor.getDisplayName()); // NOI18N 8037 if (direction.equals("West")) { // NOI18N 8038 placeWestBoundIcon(getSensorIcon(beanDetail.getText()), 8039 beanDetail.isRightSelected(), 0.0); 8040 } else { 8041 placeEastBoundIcon(getSensorIcon(beanDetail.getText()), 8042 beanDetail.isRightSelected(), 0.0); 8043 } 8044 needRedraw = true; 8045 } 8046 } 8047 } else { 8048 if (!isSensorAssignedAnywhere(newSensor)) { 8049 if (removeSensorFromPanel(currSensor)) { 8050 log.trace("Replace sensor '{}' with sensor '{}'", // NOI18N 8051 currSensor.getDisplayName(), newSensor.getDisplayName()); 8052 if (direction.equals("West")) { // NOI18N 8053 boundary.setWestBoundSensor(beanDetail.getText()); 8054 } else { 8055 boundary.setEastBoundSensor(beanDetail.getText()); 8056 } 8057 if (beanDetail.addToPanel()) { 8058 log.trace("Add icon for replacement sensor '{}'", // NOI18N 8059 newSensor.getDisplayName()); 8060 if (direction.equals("West")) { // NOI18N 8061 placeWestBoundIcon(getSensorIcon(beanDetail.getText()), 8062 beanDetail.isRightSelected(), 0.0); 8063 } else { 8064 placeEastBoundIcon(getSensorIcon(beanDetail.getText()), 8065 beanDetail.isRightSelected(), 0.0); 8066 } 8067 needRedraw = true; 8068 } 8069 } 8070 } else { 8071 sensorAssignedElseWhere(newSensor); 8072 } 8073 } 8074 } 8075 8076 public boolean isSensorOnPanel(@Nonnull Sensor sensor) { 8077 for (SensorIcon s : layoutEditor.getSensorList()) { 8078 if (s.getSensor() == sensor) { 8079 return true; 8080 } 8081 } 8082 return false; 8083 } 8084 8085 /*===============================*\ 8086 |* setSignalMastsAtBlockBoundary *| 8087 \*===============================*/ 8088 private JmriJFrame setSignalMastsAtBlockBoundaryFrame = null; 8089 private boolean setSignalMastsAtBlockBoundaryOpenFlag = false; 8090 private boolean setSignalMastsAtBlockBoundaryFromMenuFlag = false; 8091 8092 private JButton getAnchorSavedSignalMasts = null; 8093 private JButton setSignalMastsAtBlockBoundaryDone = null; 8094 private JButton setSignalMastsAtBlockBoundaryCancel = null; 8095 8096 BeanDetails<SignalMast> eastSignalMast; 8097 BeanDetails<SignalMast> westSignalMast; 8098 8099 JPanel signalMastBlockPanel = new JPanel(new FlowLayout()); 8100 8101 public void setSignalMastsAtBlockBoundaryFromMenu( 8102 @Nonnull PositionablePoint p) { 8103 boundary = p; 8104 block1IDComboBox.setSelectedItem(boundary.getConnect1().getLayoutBlock().getBlock()); 8105 if (boundary.getType() != PositionablePoint.PointType.END_BUMPER) { 8106 block2IDComboBox.setSelectedItem(boundary.getConnect2().getLayoutBlock().getBlock()); 8107 } else { 8108 block2IDComboBox.setSelectedItem(boundary.getConnect1().getLayoutBlock().getBlock()); 8109 } 8110 setSignalMastsAtBlockBoundaryFromMenuFlag = true; 8111 setSignalMastsAtBlockBoundary(); 8112 setSignalMastsAtBlockBoundaryFromMenuFlag = false; 8113 } 8114 8115 //TODO: Add to Tools menu? 8116 public void setSignalMastsAtBlockBoundary() { 8117 8118 //Initialize if needed 8119 if (setSignalMastsAtBlockBoundaryFrame == null) { 8120 setSignalMastsAtBlockBoundaryOpenFlag = false; 8121 8122 eastSignalMast = new BeanDetails<>("SignalMast", // NOI18N 8123 InstanceManager.getDefault(SignalMastManager.class)); 8124 westSignalMast = new BeanDetails<>("SignalMast", // NOI18N 8125 InstanceManager.getDefault(SignalMastManager.class)); 8126 8127 setSignalMastsAtBlockBoundaryFrame = new JmriJFrame(Bundle.getMessage("SignalMastsAtBoundary"), false, true); 8128 oneFrameToRuleThemAll(setSignalMastsAtBlockBoundaryFrame); 8129 setSignalMastsAtBlockBoundaryFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 8130 //setSignalMastsAtBlockBoundaryFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalMastsAtBoundary", true); 8131 setSignalMastsAtBlockBoundaryFrame.setLocation(70, 30); 8132 Container theContentPane = setSignalMastsAtBlockBoundaryFrame.getContentPane(); 8133 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 8134 8135 JPanel header = new JPanel(); 8136 header.setLayout(new BoxLayout(header, BoxLayout.Y_AXIS)); 8137 8138 //Create the block 1 label and combo box 8139 JPanel panel11 = new JPanel(new FlowLayout()); 8140 block1NameLabel = new JLabel(Bundle.getMessage("MakeLabel", 8141 Bundle.getMessage("BeanNameBlock") + " 1 " 8142 + Bundle.getMessage("Name"))); 8143 panel11.add(block1NameLabel); 8144 panel11.add(block1IDComboBox); 8145 block1IDComboBox.setToolTipText(Bundle.getMessage("SignalMastsBlockNameHint")); 8146 header.add(panel11); 8147 8148 //Create the block 2 label and combo box, visibility will be controlled later 8149 block2NameLabel = new JLabel(Bundle.getMessage("MakeLabel", 8150 Bundle.getMessage("BeanNameBlock") + " 2 " 8151 + Bundle.getMessage("Name"))); 8152 block2IDComboBox.setToolTipText(Bundle.getMessage("SignalMastsBlockNameHint")); 8153 8154 JPanel panel12 = new JPanel(new FlowLayout()); 8155 panel12.add(block2NameLabel); 8156 panel12.add(block2IDComboBox); 8157 header.add(panel12); 8158 8159 header.add(new JSeparator(JSeparator.HORIZONTAL)); 8160 theContentPane.add(header); 8161 8162 JPanel panel2 = new JPanel(new FlowLayout()); 8163 JLabel shTitle = new JLabel(Bundle.getMessage("SignalMasts")); 8164 panel2.add(shTitle); 8165 panel2.add(new JLabel(" ")); 8166 panel2.add(getAnchorSavedSignalMasts = new JButton(Bundle.getMessage("GetSaved"))); 8167 getAnchorSavedSignalMasts.addActionListener(this::getSavedAnchorSignalMasts); 8168 getAnchorSavedSignalMasts.setToolTipText(Bundle.getMessage("GetSavedHint")); 8169 theContentPane.add(panel2); 8170 8171 signalMastBlockPanel.setLayout(new GridLayout(0, 1)); 8172 theContentPane.add(signalMastBlockPanel); 8173 8174 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 8175 8176 JPanel panel6 = new JPanel(new FlowLayout()); 8177 panel6.add(setSignalMastsAtBlockBoundaryDone = new JButton(Bundle.getMessage("ButtonDone"))); 8178 setSignalMastsAtBlockBoundaryDone.addActionListener(this::setSignalMastsAtBlockBoundaryDonePressed); 8179 setSignalMastsAtBlockBoundaryDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 8180 8181 panel6.add(setSignalMastsAtBlockBoundaryCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 8182 setSignalMastsAtBlockBoundaryCancel.addActionListener(this::setSignalMastsAtBlockBoundaryCancelPressed); 8183 setSignalMastsAtBlockBoundaryCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 8184 theContentPane.add(panel6); 8185 8186 //make this button the default button (return or enter activates) 8187 JRootPane rootPane = SwingUtilities.getRootPane(setSignalMastsAtBlockBoundaryDone); 8188 if (rootPane != null) { 8189 rootPane.setDefaultButton(setSignalMastsAtBlockBoundaryDone); 8190 } 8191 8192 setSignalMastsAtBlockBoundaryFrame.addWindowListener(new WindowAdapter() { 8193 @Override 8194 public void windowClosing(WindowEvent e) { 8195 setSignalMastsAtBlockBoundaryCancelPressed(null); 8196 } 8197 }); 8198 } 8199 8200 eastSignalMast.getCombo().setExcludedItems(new HashSet<>()); 8201 westSignalMast.getCombo().setExcludedItems(new HashSet<>()); 8202 signalMastBlockPanel.removeAll(); 8203 8204 if (boundary.getType() != PositionablePoint.PointType.END_BUMPER) { //Anchor points and Edge Connectors 8205 eastSignalMast.setBoundaryTitle(Bundle.getMessage("East/SouthBound")); 8206 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 8207 eastSignalMast.setBoundaryTitle(Bundle.getMessage("West/NorthBound")); 8208 } 8209 if (setSignalMastsAtBlockBoundaryFromMenuFlag) { 8210 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8211 eastSignalMast.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect2().getLayoutBlock().getDisplayName()); 8212 } else { 8213 eastSignalMast.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 8214 } 8215 } 8216 eastSignalMast.getDetailsPanel().setBackground(new Color(255, 255, 200)); 8217 signalMastBlockPanel.add(eastSignalMast.getDetailsPanel()); 8218 8219 westSignalMast.setBoundaryTitle(Bundle.getMessage("West/NorthBound")); 8220 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 8221 westSignalMast.setBoundaryTitle(Bundle.getMessage("East/SouthBound")); 8222 } 8223 if (setSignalMastsAtBlockBoundaryFromMenuFlag) { 8224 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8225 westSignalMast.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 8226 } else { 8227 westSignalMast.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect2().getLayoutBlock().getDisplayName()); 8228 } 8229 } 8230 westSignalMast.getDetailsPanel().setBackground(new Color(200, 255, 255)); 8231 signalMastBlockPanel.add(westSignalMast.getDetailsPanel()); 8232 } else { //End Bumper 8233 if (setSignalMastsAtBlockBoundaryFromMenuFlag) { 8234 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8235 eastSignalMast.setBoundaryLabelText(Bundle.getMessage("EndOfBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 8236 eastSignalMast.getDetailsPanel().setBackground(new Color(200, 255, 255)); 8237 signalMastBlockPanel.add(eastSignalMast.getDetailsPanel()); 8238 } else { 8239 westSignalMast.setBoundaryLabelText(Bundle.getMessage("EndOfBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 8240 westSignalMast.getDetailsPanel().setBackground(new Color(255, 255, 200)); 8241 signalMastBlockPanel.add(westSignalMast.getDetailsPanel()); 8242 } 8243 } 8244 } 8245 block1IDComboBox.setVisible(!setSignalMastsAtBlockBoundaryFromMenuFlag); 8246 block2IDComboBox.setVisible(!setSignalMastsAtBlockBoundaryFromMenuFlag); 8247 8248 if (setSignalMastsAtBlockBoundaryFromMenuFlag) { 8249 block1NameLabel.setText(Bundle.getMessage("MakeLabel", 8250 Bundle.getMessage("BeanNameBlock") + " 1 " 8251 + Bundle.getMessage("Name")) 8252 + " " + boundary.getConnect1().getLayoutBlock().getId()); 8253 if (boundary.getConnect2() != null) { 8254 block2NameLabel.setText(Bundle.getMessage("MakeLabel", 8255 Bundle.getMessage("BeanNameBlock") + " 2 " 8256 + Bundle.getMessage("Name")) 8257 + " " + boundary.getConnect2().getLayoutBlock().getId()); 8258 block2NameLabel.setVisible(true); 8259 } else { 8260 block2NameLabel.setVisible(false); 8261 } 8262 getSavedAnchorSignalMasts(null); 8263 } 8264 8265 if (!setSignalMastsAtBlockBoundaryOpenFlag) { 8266 setSignalMastsAtBlockBoundaryFrame.setPreferredSize(null); 8267 setSignalMastsAtBlockBoundaryFrame.pack(); 8268 setSignalMastsAtBlockBoundaryOpenFlag = true; 8269 } 8270 refreshSignalMastAtBoundaryComboBox(); 8271 setSignalMastsAtBlockBoundaryFrame.setVisible(true); 8272 } 8273 8274 /** 8275 * Returns the SignalMast corresponding to an entry field in the specified 8276 * dialog. This also takes care of UpperCase and trimming of leading and 8277 * trailing blanks. If entry is required, and no entry is present, and error 8278 * message is sent. An error message also results if a signalMast head with 8279 * the entered name is not found in the SignalMastTable. 8280 * @param signalMastName name of the signal mast. 8281 * @param requireEntry true if a required field, else false. 8282 * @param frame main frame. 8283 * @return signal mast, may be null. 8284 */ 8285 @CheckReturnValue 8286 public SignalMast getSignalMastFromEntry(@CheckForNull String signalMastName, 8287 boolean requireEntry, 8288 @Nonnull JmriJFrame frame) { 8289 if ((signalMastName == null) || signalMastName.isEmpty()) { 8290 if (requireEntry) { 8291 JmriJOptionPane.showMessageDialog(frame, Bundle.getMessage("SignalMastsError5"), 8292 Bundle.getMessage("ErrorTitle"), 8293 JmriJOptionPane.ERROR_MESSAGE); 8294 } 8295 return null; 8296 8297 } 8298 SignalMast head = InstanceManager.getDefault(SignalMastManager.class 8299 ).getSignalMast(signalMastName); 8300 if (head == null) { 8301 JmriJOptionPane.showMessageDialog(frame, 8302 Bundle.getMessage("SignalMastsError4", 8303 new Object[]{signalMastName}), Bundle.getMessage("ErrorTitle"), 8304 JmriJOptionPane.ERROR_MESSAGE); 8305 return null; 8306 } 8307 return (head); 8308 } 8309 8310 /** 8311 * Returns true if the specified SignalMast is assigned to an object on the 8312 * panel, regardless of whether an icon is displayed or not. 8313 * @param signalMast the signal mast to query. 8314 * @return true if associated with panel, else false. 8315 */ 8316 public boolean isSignalMastAssignedAnywhere(@Nonnull SignalMast signalMast) { 8317 boolean result = false; 8318 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 8319 if ((po.getEastBoundSignalMast() != null) && po.getEastBoundSignalMast() == signalMast) { 8320 result = true; 8321 break; 8322 } 8323 if ((po.getWestBoundSignalMast() != null) && po.getWestBoundSignalMast() == signalMast) { 8324 result = true; 8325 break; 8326 } 8327 } 8328 8329 if (!result) { 8330 for (LayoutTurnout to : layoutEditor.getLayoutTurnoutsAndSlips()) { 8331 if ((to.getSignalAMast() != null) && to.getSignalAMast() == signalMast) { 8332 result = true; 8333 break; 8334 } 8335 if ((to.getSignalBMast() != null) && to.getSignalBMast() == signalMast) { 8336 result = true; 8337 break; 8338 } 8339 if ((to.getSignalCMast() != null) && to.getSignalCMast() == signalMast) { 8340 result = true; 8341 break; 8342 } 8343 if ((to.getSignalDMast() != null) && to.getSignalDMast() == signalMast) { 8344 result = true; 8345 break; 8346 } 8347 } 8348 } 8349 8350 if (!result) { 8351 for (LevelXing x : layoutEditor.getLevelXings()) { 8352 if ((x.getSignalAMast() != null) && x.getSignalAMast() == signalMast) { 8353 result = true; 8354 break; 8355 } 8356 if ((x.getSignalBMast() != null) && x.getSignalBMast() == signalMast) { 8357 result = true; 8358 break; 8359 } 8360 if ((x.getSignalCMast() != null) && x.getSignalCMast() == signalMast) { 8361 result = true; 8362 break; 8363 } 8364 if ((x.getSignalDMast() != null) && x.getSignalDMast() == signalMast) { 8365 result = true; 8366 break; 8367 } 8368 } 8369 } 8370 return result; 8371 } 8372 8373 /** 8374 * Removes the assignment of the specified SignalMast to either a turnout, a 8375 * positionable point, or a level crossing wherever it is assigned. 8376 * @param signalMast the signal mast to remove. 8377 */ 8378 public void removeSignalMastAssignment(@CheckForNull SignalMast signalMast) { 8379 if (signalMast == null) { 8380 return; 8381 } 8382 8383 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 8384 if ((po.getEastBoundSignalMast() != null) && po.getEastBoundSignalMast() == signalMast) { 8385 po.setEastBoundSignalMast(null); 8386 } 8387 if ((po.getWestBoundSignalMast() != null) && po.getWestBoundSignalMast() == signalMast) { 8388 po.setWestBoundSignalMast(null); 8389 } 8390 } 8391 for (LayoutTurnout to : layoutEditor.getLayoutTurnoutsAndSlips()) { 8392 if ((to.getSignalAMast() != null) && to.getSignalAMast() == signalMast) { 8393 to.setSignalAMast(null); 8394 } 8395 if ((to.getSignalBMast() != null) && to.getSignalBMast() == signalMast) { 8396 to.setSignalBMast(null); 8397 } 8398 if ((to.getSignalCMast() != null) && to.getSignalCMast() == signalMast) { 8399 to.setSignalCMast(null); 8400 } 8401 if ((to.getSignalDMast() != null) && to.getSignalDMast() == signalMast) { 8402 to.setSignalDMast(null); 8403 } 8404 } 8405 8406 for (LevelXing x : layoutEditor.getLevelXings()) { 8407 if ((x.getSignalAMast() != null) && x.getSignalAMast() == signalMast) { 8408 x.setSignalAMast(null); 8409 } 8410 8411 if ((x.getSignalBMast() != null) && x.getSignalBMast() == signalMast) { 8412 x.setSignalBMast(null); 8413 } 8414 8415 if ((x.getSignalCMast() != null) && x.getSignalCMast() == signalMast) { 8416 x.setSignalCMast(null); 8417 } 8418 8419 if ((x.getSignalDMast() != null) && x.getSignalDMast() == signalMast) { 8420 x.setSignalDMast(null); 8421 } 8422 } 8423 } 8424 8425 /** 8426 * Removes the SignalMast with the specified name from the panel and from 8427 * assignment to any turnout, positionable point, or level crossing. 8428 * @param signalMast the signal mast to remove. 8429 */ 8430 public void removeSignalMastFromPanel(@Nonnull SignalMast signalMast) { 8431 removeSignalMastAssignment(signalMast); 8432 SignalMastIcon h = null; 8433 int index = -1; 8434 for (int i = 0; (i < layoutEditor.getSignalMastList().size()) && (index == -1); i++) { 8435 h = layoutEditor.getSignalMastList().get(i); 8436 if ((h != null) && (h.getSignalMast() == signalMast)) { 8437 index = i; 8438 } 8439 } 8440 if ((h != null) && (index != -1)) { 8441 layoutEditor.getSignalMastList().remove(index); 8442 h.remove(); 8443 h.dispose(); 8444 needRedraw = true; 8445 } 8446 } 8447 8448 private void getSavedAnchorSignalMasts(ActionEvent a) { 8449 if (!getSimpleBlockInformation()) { 8450 return; 8451 } 8452 8453 eastSignalMast.setTextField(boundary.getEastBoundSignalMastName()); 8454 westSignalMast.setTextField(boundary.getWestBoundSignalMastName()); 8455 8456 if (boundary.getType() != PositionablePoint.PointType.END_BUMPER) { 8457 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8458 eastSignalMast.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect2().getLayoutBlock().getDisplayName()); 8459 } else { 8460 eastSignalMast.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 8461 } 8462 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8463 westSignalMast.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 8464 } else { 8465 westSignalMast.setBoundaryLabelText(Bundle.getMessage("ProtectingBlock") + boundary.getConnect2().getLayoutBlock().getDisplayName()); 8466 } 8467 } else { 8468 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8469 westSignalMast.setBoundaryLabelText(Bundle.getMessage("EndOfBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 8470 } else { 8471 eastSignalMast.setBoundaryLabelText(Bundle.getMessage("EndOfBlock") + boundary.getConnect1().getLayoutBlock().getDisplayName()); 8472 } 8473 } 8474 setSignalMastsAtBlockBoundaryFrame.setPreferredSize(null); 8475 setSignalMastsAtBlockBoundaryFrame.pack(); 8476 } 8477 8478 private void setSignalMastsAtBlockBoundaryCancelPressed(ActionEvent a) { 8479 setSignalMastsAtBlockBoundaryOpenFlag = false; 8480 setSignalMastsAtBlockBoundaryFrame.setVisible(false); 8481 } 8482 8483 void refreshSignalMastAtBoundaryComboBox() { 8484 createListUsedSignalMasts(); 8485 usedMasts.remove(eastSignalMast.getBean()); 8486 usedMasts.remove(westSignalMast.getBean()); 8487 eastSignalMast.getCombo().setExcludedItems(usedMasts); 8488 westSignalMast.getCombo().setExcludedItems(usedMasts); 8489 } 8490 8491 private void setSignalMastsAtBlockBoundaryDonePressed(ActionEvent a) { 8492 if (!getSimpleBlockInformation()) { 8493 return; 8494 } 8495 8496 SignalMast oldBlock1SignalMast = boundary.getEastBoundSignalMast(); 8497 SignalMast block1BoundSignalMast = getSignalMastFromEntry(eastSignalMast.getText(), false, setSignalMastsAtBlockBoundaryFrame); 8498 8499 if (block1BoundSignalMast == null) { 8500 if (InstanceManager.getDefault(LayoutBlockManager.class).isAdvancedRoutingEnabled() 8501 && InstanceManager.getDefault(SignalMastLogicManager.class).isSignalMastUsed(oldBlock1SignalMast)) { 8502 SignallingGuiTools.removeSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, oldBlock1SignalMast); 8503 } 8504 8505 removeSignalMastFromPanel(boundary.getEastBoundSignalMast()); 8506 removeSignalMastAssignment(boundary.getEastBoundSignalMast()); 8507 boundary.setEastBoundSignalMast(""); 8508 } 8509 8510 SignalMast oldBlock2SignalMast = boundary.getWestBoundSignalMast(); 8511 SignalMast block2BoundSignalMast = getSignalMastFromEntry(westSignalMast.getText(), false, setSignalMastsAtBlockBoundaryFrame); 8512 8513 if (block2BoundSignalMast == null) { 8514 if (InstanceManager.getDefault(LayoutBlockManager.class 8515 ).isAdvancedRoutingEnabled() && InstanceManager.getDefault(SignalMastLogicManager.class 8516 ).isSignalMastUsed(oldBlock2SignalMast)) { 8517 SignallingGuiTools.removeSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, oldBlock2SignalMast); 8518 } 8519 8520 removeSignalMastFromPanel(boundary.getWestBoundSignalMast()); 8521 removeSignalMastAssignment(boundary.getWestBoundSignalMast()); 8522 boundary.setWestBoundSignalMast(""); 8523 } 8524 if (block2BoundSignalMast != null && block1BoundSignalMast != null) { 8525 if (block1BoundSignalMast == block2BoundSignalMast) { 8526 JmriJOptionPane.showMessageDialog(setSignalMastsAtBlockBoundaryFrame, 8527 Bundle.getMessage("SignalMastsError14"), 8528 Bundle.getMessage("ErrorTitle"), 8529 JmriJOptionPane.ERROR_MESSAGE); 8530 return; 8531 } 8532 if (oldBlock1SignalMast == block2BoundSignalMast && oldBlock2SignalMast == block1BoundSignalMast) { 8533 //We are going for a swap! 8534 //Need to remove old items first 8535 removeSignalMastFromPanel(boundary.getWestBoundSignalMast()); 8536 removeSignalMastFromPanel(boundary.getEastBoundSignalMast()); 8537 removeSignalMastAssignment(block1BoundSignalMast); 8538 removeSignalMastAssignment(block2BoundSignalMast); 8539 //Then place new ones 8540 SignalMastIcon l; 8541 if (eastSignalMast.addToPanel()) { 8542 l = new SignalMastIcon(layoutEditor); 8543 l.setSignalMast(eastSignalMast.getText()); 8544 placeEastBoundIcon(l, eastSignalMast.isRightSelected(), 0); 8545 } 8546 if (westSignalMast.addToPanel()) { 8547 l = new SignalMastIcon(layoutEditor); 8548 l.setSignalMast(westSignalMast.getText()); 8549 placeWestBoundIcon(l, westSignalMast.isRightSelected(), 0); 8550 } 8551 boundary.setEastBoundSignalMast(eastSignalMast.getText()); 8552 boundary.setWestBoundSignalMast(westSignalMast.getText()); 8553 //Then sort out the logic 8554 8555 if (InstanceManager.getDefault(LayoutBlockManager.class 8556 ).isAdvancedRoutingEnabled()) { 8557 SignallingGuiTools.swapSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, block1BoundSignalMast, block2BoundSignalMast); 8558 } 8559 needRedraw = true; 8560 } 8561 } 8562 if (!needRedraw) { 8563 if (block1BoundSignalMast != null) { 8564 if (eastSignalMast.addToPanel()) { 8565 if (isSignalMastAssignedAnywhere(block1BoundSignalMast) 8566 && (block1BoundSignalMast != oldBlock1SignalMast)) { 8567 JmriJOptionPane.showMessageDialog(setSignalMastsAtBlockBoundaryFrame, 8568 Bundle.getMessage("SignalMastsError6", 8569 new Object[]{eastSignalMast.getText()}), 8570 Bundle.getMessage("ErrorTitle"), 8571 JmriJOptionPane.ERROR_MESSAGE); 8572 return; 8573 } else { 8574 removeSignalMastFromPanel(boundary.getEastBoundSignalMast()); 8575 SignalMastIcon l = new SignalMastIcon(layoutEditor); 8576 l.setSignalMast(eastSignalMast.getText()); 8577 placeEastBoundIcon(l, eastSignalMast.isRightSelected(), 0); 8578 removeSignalMastAssignment(block1BoundSignalMast); 8579 boundary.setEastBoundSignalMast(eastSignalMast.getText()); 8580 needRedraw = true; 8581 } 8582 } else if ((block1BoundSignalMast != boundary.getEastBoundSignalMast()) 8583 && (block1BoundSignalMast != boundary.getWestBoundSignalMast())) { 8584 if (isSignalMastOnPanel(block1BoundSignalMast)) { 8585 JmriJOptionPane.showMessageDialog(setSignalMastsAtBlockBoundaryFrame, 8586 Bundle.getMessage("SignalMastsError13", 8587 new Object[]{eastSignalMast.getText()}), 8588 Bundle.getMessage("ErrorTitle"), 8589 JmriJOptionPane.ERROR_MESSAGE); 8590 return; 8591 } else { 8592 removeSignalMastFromPanel(boundary.getEastBoundSignalMast()); 8593 removeSignalMastAssignment(block1BoundSignalMast); 8594 boundary.setEastBoundSignalMast(eastSignalMast.getText()); 8595 } 8596 } 8597 } 8598 if (block2BoundSignalMast != null) { 8599 if (westSignalMast.addToPanel()) { 8600 if (isSignalMastAssignedAnywhere(block2BoundSignalMast) 8601 && (block2BoundSignalMast != oldBlock2SignalMast)) { 8602 JmriJOptionPane.showMessageDialog(setSignalMastsAtBlockBoundaryFrame, 8603 Bundle.getMessage("SignalMastsError6", 8604 new Object[]{westSignalMast.getText()}), 8605 Bundle.getMessage("ErrorTitle"), 8606 JmriJOptionPane.ERROR_MESSAGE); 8607 return; 8608 } else /*(oldBlock2SignalMast!=block2BoundSignalMast)*/ { 8609 removeSignalMastFromPanel(boundary.getWestBoundSignalMast()); 8610 SignalMastIcon l = new SignalMastIcon(layoutEditor); 8611 l.setSignalMast(westSignalMast.getText()); 8612 placeWestBoundIcon(l, westSignalMast.isRightSelected(), 0); 8613 removeSignalMastAssignment(block2BoundSignalMast); 8614 boundary.setWestBoundSignalMast(westSignalMast.getText()); 8615 needRedraw = true; 8616 } 8617 } else if ((block2BoundSignalMast != boundary.getEastBoundSignalMast()) 8618 && (block2BoundSignalMast != oldBlock2SignalMast)) { 8619 if (isSignalMastAssignedAnywhere(block2BoundSignalMast)) { 8620 //Need to do this better, so that the signalMast can be on panel multiple times but only alocated to one anchor at a time 8621 JmriJOptionPane.showMessageDialog(setSignalMastsAtBlockBoundaryFrame, 8622 Bundle.getMessage("SignalMastsError13", 8623 new Object[]{westSignalMast.getText()}), 8624 Bundle.getMessage("ErrorTitle"), 8625 JmriJOptionPane.ERROR_MESSAGE); 8626 return; 8627 } else { 8628 removeSignalMastFromPanel(boundary.getWestBoundSignalMast()); 8629 removeSignalMastAssignment(block2BoundSignalMast); 8630 boundary.setWestBoundSignalMast(westSignalMast.getText()); 8631 8632 } 8633 } 8634 } 8635 8636 //If advanced routing is enabled and then this indicates that we are using this for discovering the signalmast logic paths. 8637 if (InstanceManager.getDefault(LayoutBlockManager.class 8638 ).isAdvancedRoutingEnabled() 8639 && (block1BoundSignalMast != null 8640 || block2BoundSignalMast != null)) { 8641 if ((oldBlock1SignalMast != null) && (block2BoundSignalMast != null)) { 8642 updateBoundaryBasedSignalMastLogic( 8643 oldBlock1SignalMast, oldBlock2SignalMast, 8644 block1BoundSignalMast, block2BoundSignalMast); 8645 8646 } 8647 } 8648 } 8649 setSignalMastsAtBlockBoundaryOpenFlag = false; 8650 setSignalMastsAtBlockBoundaryFrame.setVisible(false); 8651 if (needRedraw) { 8652 layoutEditor.redrawPanel(); 8653 needRedraw = false; 8654 layoutEditor.setDirty(); 8655 } 8656 } 8657 8658 public void updateBoundaryBasedSignalMastLogic( 8659 @Nonnull SignalMast oldBlock1SignalMast, 8660 @Nonnull SignalMast oldBlock2SignalMast, 8661 @Nonnull SignalMast block1BoundSignalMast, 8662 @Nonnull SignalMast block2BoundSignalMast) { 8663 SignalMastLogicManager smlm = InstanceManager.getDefault(SignalMastLogicManager.class 8664 ); 8665 boolean old1Used = smlm.isSignalMastUsed(oldBlock1SignalMast); 8666 boolean old2Used = smlm.isSignalMastUsed(oldBlock2SignalMast); 8667 //Just check that the old ones are used in logics somewhere. 8668 if (old1Used || old2Used) { 8669 boolean new1Used = smlm.isSignalMastUsed(block1BoundSignalMast); 8670 boolean new2Used = smlm.isSignalMastUsed(block2BoundSignalMast); 8671 if (new1Used || new2Used) { 8672 if ((new1Used) && (block1BoundSignalMast != oldBlock1SignalMast)) { 8673 SignallingGuiTools.removeAlreadyAssignedSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, block1BoundSignalMast); 8674 } 8675 if ((new2Used) && (block2BoundSignalMast != oldBlock2SignalMast)) { 8676 SignallingGuiTools.removeAlreadyAssignedSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, block2BoundSignalMast); 8677 } 8678 } 8679 if (block1BoundSignalMast != null) { 8680 if (oldBlock2SignalMast != null && old2Used 8681 && oldBlock2SignalMast == block1BoundSignalMast) { 8682 SignallingGuiTools.updateSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, oldBlock2SignalMast, block1BoundSignalMast); 8683 } 8684 8685 if (oldBlock1SignalMast != null && old1Used 8686 && oldBlock1SignalMast != block1BoundSignalMast) { 8687 8688 SignallingGuiTools.updateSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, oldBlock1SignalMast, block1BoundSignalMast); 8689 } 8690 } 8691 if (block2BoundSignalMast != null) { 8692 if (old1Used && oldBlock1SignalMast == block2BoundSignalMast) { 8693 8694 SignallingGuiTools.updateSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, oldBlock1SignalMast, block2BoundSignalMast); 8695 } 8696 if (old2Used && oldBlock2SignalMast != block2BoundSignalMast) { 8697 SignallingGuiTools.updateSignalMastLogic(setSignalMastsAtBlockBoundaryFrame, oldBlock2SignalMast, block2BoundSignalMast); 8698 } 8699 } 8700 } 8701 } 8702 8703 public void setIconOnPanel(@Nonnull PositionableIcon l, 8704 int rotation, @Nonnull Point p) { 8705 setIconOnPanel(l, rotation, (int) p.getX(), (int) p.getY()); 8706 } 8707 8708 public void setIconOnPanel(@Nonnull PositionableIcon l, 8709 int rotation, int xLoc, int yLoc) { 8710 l.setLocation(xLoc, yLoc); 8711 if (rotation > 0) { 8712 l.rotate(rotation); 8713 } 8714 if (l instanceof SignalMastIcon) { 8715 layoutEditor.putSignalMast((SignalMastIcon) l); 8716 } else if (l instanceof SensorIcon) { 8717 layoutEditor.putSensor((SensorIcon) l); 8718 } else if (l instanceof SignalHeadIcon) { 8719 layoutEditor.putSignal((SignalHeadIcon) l); 8720 } 8721 } 8722 8723 private void placeEastBoundIcon(PositionableIcon icon, boolean isRightSide, double fromPoint) { 8724 8725 Point2D p = layoutEditor.getLayoutTrackView(boundary).getCoordsCenter(); 8726 8727 //Track segment is used to determine the alignment, 8728 // therefore this is opposite to the block that we are protecting 8729 8730 //For edge connectors we need to do two things: 8731 // - change the dir value as east and west are swapped 8732 // - and as we have only one track segment on any one layout editor 8733 // so we determine where the track segment would end if we did a mirror image 8734 // so that the calculations for angled segments is correct 8735 8736 TrackSegment t = boundary.getConnect2(); 8737 boolean dir = true; 8738 boolean shouldUseConnect2 = true; 8739 8740 if (boundary.getType() == PositionablePoint.PointType.END_BUMPER) { 8741 t = boundary.getConnect1(); 8742 } else{ 8743 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8744 t = boundary.getConnect1(); 8745 } 8746 } 8747 8748 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 8749 t = boundary.getConnect1(); //have to use connect1 as there is only one track segment attached to edge connector 8750 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8751 shouldUseConnect2 = false; 8752 } 8753 } 8754 8755 Point2D pt2; 8756 if (t.getConnect1() == boundary){ 8757 pt2 = layoutEditor.getCoords(t.getConnect2(), t.getType2()); 8758 } else { 8759 pt2 = layoutEditor.getCoords(t.getConnect1(), t.getType1()); 8760 } 8761 8762 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 8763 Point2D p3 = (Point2D) pt2.clone(); 8764 if (shouldUseConnect2) { 8765 //use a point opposite pt2 (= p + p- pt2 using vector addition) 8766 double px = p.getX(); 8767 double py = p.getY(); 8768 double p2x = pt2.getX(); 8769 double p2y = pt2.getY(); 8770 double p3x = px + px - p2x; 8771 double p3y = py + py - p2y; 8772 p3.setLocation(p3x, p3y); 8773 } 8774 dir = false; //east and west are swapped with edge connectors 8775 setIconOnPanel(t, icon, dir, p, p3, isRightSide, fromPoint); 8776 } else{ 8777 setIconOnPanel(t, icon, dir, p, pt2, isRightSide, fromPoint); 8778 } 8779 8780 } 8781 8782 private void placeWestBoundIcon(PositionableIcon icon, boolean isRightSide, double fromPoint) { 8783 8784 Point2D p = layoutEditor.getLayoutTrackView(boundary).getCoordsCenter(); 8785 8786 //Track segment is used to determine the alignment, 8787 // therefore this is opposite to the block that we are protecting 8788 8789 //For edge connectors we need to do two things: 8790 // - change the dir value as east and west are swapped 8791 // - and as we have only one track segment on any one layout editor 8792 // so we determine where the track segment would end if we did a mirror image 8793 // so that the calculations for angled segments is correct 8794 8795 TrackSegment t = boundary.getConnect1(); 8796 boolean dir = false; 8797 boolean shouldUseConnect2 = false; 8798 if (boundary.getType() != PositionablePoint.PointType.END_BUMPER) { 8799 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8800 t = boundary.getConnect2(); 8801 } 8802 } 8803 8804 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 8805 t = boundary.getConnect1(); //have to use connect1 as there is only one track segment attached to edge connector 8806 if (isAtWestEndOfAnchor(boundary.getConnect1(), boundary)) { 8807 shouldUseConnect2 = true; 8808 } 8809 } 8810 8811 Point2D pt2; 8812 if (t.getConnect1() == boundary) { 8813 pt2 = layoutEditor.getCoords(t.getConnect2(), t.getType2()); 8814 } else { 8815 pt2 = layoutEditor.getCoords(t.getConnect1(), t.getType1()); 8816 } 8817 8818 if (boundary.getType() == PositionablePoint.PointType.EDGE_CONNECTOR) { 8819 Point2D p3 = (Point2D) pt2.clone(); 8820 if (shouldUseConnect2) { 8821 //use a point opposite pt2 (= p + p - pt2 using vector addition) 8822 double px = p.getX(); 8823 double py = p.getY(); 8824 double p2x = pt2.getX(); 8825 double p2y = pt2.getY(); 8826 double p3x = px + px - p2x; 8827 double p3y = py + py - p2y; 8828 p3.setLocation(p3x, p3y); 8829 } 8830 dir = true; //east and west are swapped with edge connectors 8831 setIconOnPanel(t, icon, dir, p, p3, isRightSide, fromPoint); 8832 } else{ 8833 setIconOnPanel(t, icon, dir, p, pt2, isRightSide, fromPoint); 8834 } 8835 } 8836 8837 private void setIconOnPanel(@Nonnull TrackSegment t, 8838 @Nonnull PositionableIcon l, 8839 boolean isEastBound, @Nonnull Point2D pt1, @Nonnull Point2D pt2, 8840 boolean isRightSide, double fromPoint) { 8841 double pt1x = pt1.getX(), pt1y = pt1.getY(); 8842 double pt2x = pt2.getX(), pt2y = pt2.getY(); 8843 8844 int triX = (int) Math.round(pt2x - pt1x); 8845 int triY = (int) Math.round(pt2y - pt1y); 8846 8847 if (log.isDebugEnabled()) { 8848 log.debug("X {} Y {}", triX, triY); 8849 } 8850 Point loc; 8851 if (triX == 0 || triX == 360) { 8852 //In a vertical Straight Line 8853 if (isEastBound) { 8854 log.debug("In a vertical straightline facing South"); 8855 loc = northToSouth(pt1, l, isRightSide, fromPoint); 8856 } else { 8857 log.debug("In a vertical striaghtline facing North"); 8858 loc = southToNorth(pt1, l, isRightSide, fromPoint); 8859 } 8860 } else if (triY == 0 || triY == 360) { 8861 //In a Horizontal Straight Line 8862 if (isEastBound) { 8863 log.debug("In a Horizontal striaghtline facing east"); 8864 loc = westToEast(pt1, l, isRightSide, fromPoint); 8865 } else { 8866 log.debug("In a Horizontal striaghtline facing west"); 8867 loc = eastToWest(pt1, l, isRightSide, fromPoint); 8868 } 8869 } else { 8870 //Compute arc's chord 8871 double a = pt2x - pt1x; 8872 double o = pt2y - pt1y; 8873 double radius = Math.hypot(a, o); //chord equates to radius of circle 8874 8875 double pt1xa = pt1x + radius; 8876 double a1 = pt2x - pt1xa; 8877 double o1 = pt2y - pt1y; 8878 double chord = Math.hypot(a1, o1); 8879 double rsq = Math.pow(radius, 2); 8880 8881 double radAngleFromDatum = Math.acos((rsq + rsq - Math.pow(chord, 2)) / (2 * rsq)); 8882 if (log.isDebugEnabled()) { 8883 log.debug("radius {} Chord {}", radius, chord); 8884 log.debug("Angle from datum line {}", Math.toDegrees(radAngleFromDatum)); 8885 } 8886 8887 int rotateDEG = ((int) Math.toDegrees(radAngleFromDatum)); 8888 8889 if (log.isDebugEnabled()) { 8890 double tanx = o / a; 8891 double angletanRAD = Math.atan2(o, a); 8892 log.debug("{} = atan2({}, {}) ({})", Math.toDegrees(angletanRAD), o, a, tanx); 8893 } 8894 8895 int oldHeight = l.maxHeight(); 8896 int oldWidth = l.maxWidth(); 8897 8898 //pt1 is always our boundary point 8899 //East side 8900 if (pt2x > pt1x) { 8901 //East Sides 8902 if (pt2y > pt1y) { 8903 //"South East Corner" 8904 rotateDEG = rotateDEG + 270; //Correct for SM111, sm101, sm121, SM80 8905 l.rotate(rotateDEG); 8906 loc = southEastToNorthWest(pt1, l, oldWidth, oldHeight, rotateDEG, isRightSide, fromPoint); 8907 } else { 8908 //"North East corner" //correct for sm110, sm70, sm131 8909 rotateDEG = 270 - rotateDEG; 8910 l.rotate(rotateDEG); 8911 loc = northEastToSouthWest(pt1, l, oldWidth, oldHeight, rotateDEG, isRightSide, fromPoint); 8912 } 8913 8914 } else { 8915 //West Side 8916 if (pt2y > pt1y) { 8917 //South West //WORKING FOR SM141, sm130, SM71 8918 l.rotate(rotateDEG - 90); 8919 //South West 8920 loc = southWestToNorthEast(pt1, l, oldWidth, oldHeight, rotateDEG, isRightSide, fromPoint); 8921 } else { 8922 //North West //Working FOR SM140, SM81, sm120 8923 rotateDEG = (180 - rotateDEG) + 90; 8924 l.rotate(rotateDEG); 8925 loc = northWestToSouthEast(pt1, l, oldWidth, oldHeight, rotateDEG, isRightSide, fromPoint); 8926 } 8927 } 8928 } 8929 setIconOnPanel(l, 0, loc); 8930 } 8931 8932 Point southToNorth(Point2D p, PositionableIcon l, boolean right, double fromPoint) { 8933 int offsetx = 0; 8934 int offsety = (int) (p.getY() + offSetFromPoint + fromPoint); 8935 if (right) { 8936 offsetx = (int) p.getX() + offSetFromPoint; 8937 } else { 8938 offsetx = (int) p.getX() - offSetFromPoint - l.maxWidth(); 8939 } 8940 return new Point(offsetx, offsety); 8941 } 8942 8943 Point northToSouth(Point2D p, PositionableIcon l, boolean right, double fromPoint) { 8944 l.rotate(180); 8945 int offsetx = 0; 8946 int offsety = (int) (p.getY() - (offSetFromPoint + fromPoint) - l.maxHeight()); 8947 if (right) { 8948 offsetx = (int) p.getX() - offSetFromPoint - l.maxWidth(); 8949 } else { 8950 offsetx = (int) p.getX() + offSetFromPoint; 8951 } 8952 return new Point(offsetx, offsety); 8953 } 8954 8955 Point westToEast(Point2D p, PositionableIcon l, boolean right, double fromPoint) { 8956 l.rotate(90); 8957 int offsetx = (int) (p.getX() - (l.maxWidth() + (offSetFromPoint + fromPoint - 1))); 8958 int offsety = 0; 8959 if (right) { 8960 offsety = (int) p.getY() + (offSetFromPoint - 1); 8961 } else { 8962 offsety = (int) p.getY() - (offSetFromPoint) - l.maxHeight(); 8963 } 8964 return new Point(offsetx, offsety); 8965 } 8966 8967 Point eastToWest(Point2D p, PositionableIcon l, boolean right, double fromPoint) { 8968 l.rotate(-90); 8969 int offsetx = (int) (p.getX() + offSetFromPoint + fromPoint); 8970 int offsety = 0; 8971 if (right) { 8972 offsety = (int) p.getY() - (offSetFromPoint - 1) - l.maxHeight(); 8973 } else { 8974 offsety = (int) p.getY() + (offSetFromPoint); 8975 } 8976 return new Point(offsetx, offsety); 8977 } 8978 8979 // Come back to this as its a bit tight to the rail on SM110 need re 8980 // checking 8981 Point northEastToSouthWest(Point2D p, PositionableIcon l, int oldWidth, int oldHeight, double angleDEG, boolean right, double fromPoint) { 8982 angleDEG = angleDEG - 180; 8983 if (angleDEG < 45) { 8984 //Because of the angle things get shifted about. 8985 int tmpWidth = oldWidth; 8986 oldWidth = oldHeight; 8987 oldHeight = tmpWidth; 8988 } 8989 double ang = angleDEG; 8990 double oppAng = 90 - ang; 8991 double angleRAD = Math.toRadians(angleDEG); 8992 double oppAngRAD = Math.toRadians(oppAng); 8993 double iconAdj = Math.sin(angleRAD) * oldHeight; 8994 double iconAdjOpp = Math.sin(oppAngRAD) * oldHeight; 8995 double bpa = Math.sin(angleRAD) * (offSetFromPoint + fromPoint); 8996 double bpo = Math.sin(oppAngRAD) * (offSetFromPoint + fromPoint); 8997 double ta = Math.sin(angleRAD) * offSetFromPoint; 8998 double to = Math.sin(oppAngRAD) * offSetFromPoint; 8999 9000 if (log.isDebugEnabled()) { 9001 log.debug("north east to south west {}", angleDEG); 9002 log.debug("oldWidth {} oldHeight {}", oldWidth, oldHeight); 9003 log.debug("newWidth {} newHeight {}", l.maxWidth(), l.maxHeight()); 9004 log.debug("Icon adj: {} opp adj: {}", iconAdj, iconAdjOpp); 9005 log.debug("boundary point opp {}", bpo); 9006 log.debug("boundary point adj {}", bpa); 9007 log.debug("track opp {}", to); 9008 log.debug("track adj {}", ta); 9009 } 9010 int xpos = 0; 9011 int ypos = 0; 9012 if (right) { 9013 //double x_dist_to_Icon = (l.maxWidth()-iconAdj)-(bpa-bpo); 9014 //double y_dist_to_Icon = bpa+bpo+l.maxHeight(); 9015 9016 double x_dist_to_Icon = (iconAdjOpp) - (bpa - to); 9017 double y_dist_to_Icon = ta + bpo + l.maxHeight(); 9018 9019 log.debug("x dist {}, y dist {}", x_dist_to_Icon, y_dist_to_Icon); 9020 9021 xpos = (int) (p.getX() - x_dist_to_Icon); 9022 ypos = (int) (p.getY() - y_dist_to_Icon); 9023 9024 } else { 9025 double y_dist_to_Icon = iconAdjOpp + (bpo - ta); 9026 double x_dist_to_Icon = to + bpa; 9027 //double y_dist_to_Icon = (l.maxHeight()-iconAdj)-(ta-bpo); 9028 //double x_dist_to_Icon = bpa+to; 9029 log.debug("x dist {}, y dist {}", x_dist_to_Icon, y_dist_to_Icon); 9030 9031 xpos = (int) (p.getX() + x_dist_to_Icon); 9032 ypos = (int) (p.getY() - y_dist_to_Icon); 9033 9034 } 9035 if (log.isDebugEnabled()) { 9036 log.debug("xpos {}", xpos); 9037 log.debug("yPos {}", ypos); 9038 } 9039 return new Point(xpos, ypos); 9040 9041 } 9042 9043 Point southWestToNorthEast(Point2D p, PositionableIcon l, int oldWidth, int oldHeight, double angleDEG, boolean right, double fromPoint) { 9044 angleDEG = 180 - angleDEG; 9045 9046 double oppAng = angleDEG; 9047 double angDEG = 90 - oppAng; 9048 9049 //Because of the angle things get shifted about. 9050 if (angDEG < 45) { //was angle 9051 int tmpWidth = oldWidth; 9052 oldWidth = oldHeight; 9053 oldHeight = tmpWidth; 9054 } 9055 9056 double angRAD = Math.toRadians(angDEG); 9057 double oppAngRAD = Math.toRadians(oppAng); 9058 double iconAdj = Math.sin(angRAD) * oldHeight; 9059 double iconAdjOpp = Math.sin(oppAngRAD) * oldHeight; 9060 double bpa = Math.sin(angRAD) * (offSetFromPoint + fromPoint); 9061 double bpo = Math.sin(oppAngRAD) * (offSetFromPoint + fromPoint); 9062 double ta = Math.sin(angRAD) * offSetFromPoint; 9063 double to = Math.sin(oppAngRAD) * offSetFromPoint; 9064 9065 if (log.isDebugEnabled()) { 9066 log.debug("south west to north east {}", angleDEG); 9067 log.debug("oldWidth {} oldHeight {}", oldWidth, oldHeight); 9068 log.debug("newWidth {} newHeight {}", l.maxWidth(), l.maxHeight()); 9069 log.debug("Icon adj: {} opp adj: {}", iconAdj, iconAdjOpp); 9070 log.debug("boundary point opp {}", bpo); 9071 log.debug("boundary point adj {}", bpa); 9072 log.debug("track opp {}", to); 9073 log.debug("track adj {}", ta); 9074 } 9075 9076 int xpos; 9077 int ypos; 9078 9079 if (right) { 9080 double x_dist_to_Icon = iconAdj + (bpa - to); 9081 double y_dist_to_Icon = ta + bpo; 9082 log.debug("x dist {}, y dist {}", x_dist_to_Icon, y_dist_to_Icon); 9083 9084 xpos = (int) (p.getX() - x_dist_to_Icon); 9085 log.debug("xpos {}", xpos); 9086 ypos = (int) (p.getY() + y_dist_to_Icon); 9087 log.debug("yPos {}", ypos); 9088 } else { 9089 double x_dist_to_Icon = (bpa + to) + l.maxWidth(); 9090 //double y_dist_to_Icon = (iconAdj+(ta-bpo)); 9091 double y_dist_to_Icon = (bpo - ta) - (l.maxHeight() - iconAdjOpp); 9092 //double y_dist_to_Icon = (iconAdj+(ta-bpo)); 9093 log.debug("x dist {}, y dist {}", x_dist_to_Icon, y_dist_to_Icon); 9094 xpos = (int) (p.getX() - x_dist_to_Icon); 9095 ypos = (int) (p.getY() + y_dist_to_Icon); 9096 } 9097 if (log.isDebugEnabled()) { 9098 log.debug("xpos {}", xpos); 9099 log.debug("yPos {}", ypos); 9100 } 9101 return new Point(xpos, ypos); 9102 9103 } 9104 9105 //Working FOR SM140, SM81, sm120 9106 Point northWestToSouthEast(Point2D p, PositionableIcon l, int oldWidth, int oldHeight, double angleDEG, boolean right, double fromPoint) { 9107 log.debug("angle before {}", angleDEG); 9108 angleDEG = 180 - angleDEG; 9109 angleDEG = 90 - angleDEG; 9110 log.debug("north west to south east {}", angleDEG); 9111 if (angleDEG < 45) { 9112 //Because of the angle things get shifted about. 9113 int tmpWidth = oldWidth; 9114 oldWidth = oldHeight; 9115 oldHeight = tmpWidth; 9116 } 9117 log.debug("oldWidth {} oldHeight {}", oldWidth, oldHeight); 9118 log.debug("newWidth {} newHeight {}", l.maxWidth(), l.maxHeight()); 9119 //double ang = angle; 9120 double oppAng = 90 - angleDEG; 9121 double angleRAD = Math.toRadians(angleDEG); 9122 double oppAngRAD = Math.toRadians(oppAng); 9123 double iconAdj = Math.sin(angleRAD) * oldHeight; 9124 double iconAdjOpp = Math.sin(oppAngRAD) * oldHeight; 9125 9126 double bpa = Math.sin(angleRAD) * (offSetFromPoint + fromPoint); //distance from point 9127 double bpo = Math.sin(oppAngRAD) * (offSetFromPoint + fromPoint); 9128 double ta = Math.sin(angleRAD) * offSetFromPoint; //distance from track 9129 double to = Math.sin(oppAngRAD) * offSetFromPoint; 9130 9131 if (log.isDebugEnabled()) { 9132 log.debug("north west to south east {}", angleDEG); 9133 log.debug("oldWidth {} oldHeight {}", oldWidth, oldHeight); 9134 log.debug("newWidth {} newHeight {}", l.maxWidth(), l.maxHeight()); 9135 log.debug("Icon adj: {} opp adj: {}", iconAdj, iconAdjOpp); 9136 log.debug("boundary point opp {}", bpo); 9137 log.debug("boundary point adj {}", bpa); 9138 log.debug("track opp {}", to); 9139 log.debug("track adj {}", ta); 9140 } 9141 int xpos = 0; 9142 int ypos = 0; 9143 if (right) { 9144 //double x_dist_to_Icon = bpa+bpo+l.maxWidth(); 9145 //double y_dist_to_Icon = bpa-(l.maxHeight()-iconAdj); 9146 double x_dist_to_Icon = (l.maxWidth() + ta + bpo); 9147 double y_dist_to_Icon = iconAdj + (bpa - to); 9148 9149 log.debug("right x dist {}, y dist {}", x_dist_to_Icon, y_dist_to_Icon); 9150 9151 xpos = (int) (p.getX() - x_dist_to_Icon); 9152 ypos = (int) (p.getY() - y_dist_to_Icon); //was + 9153 } else { 9154 //This still needs to be worked out. 9155 //double y_dist_to_Icon = bpa+bpo+l.maxHeight(); 9156 //double x_dist_to_Icon = iconAdj+(bpa-bpo); 9157 9158 double y_dist_to_Icon = l.maxHeight() + bpa + to;//+(l.maxWidth()-iconAdj); 9159 //double y_dist_to_Icon = bpa-(l.maxHeight()-iconAdj); 9160 //double y_dist_to_Icon = ta+bpo+l.maxHeight(); 9161 double x_dist_to_Icon = (iconAdjOpp) + (bpo - ta); 9162 //double x_dist_to_Icon = iconAdj+(bpa-to); 9163 log.debug("left x dist {}, y dist {}", x_dist_to_Icon, y_dist_to_Icon); 9164 9165 xpos = (int) (p.getX() - x_dist_to_Icon); 9166 ypos = (int) (p.getY() - y_dist_to_Icon); 9167 } 9168 if (log.isDebugEnabled()) { 9169 log.debug("{} xpos {}", p.getX(), xpos); 9170 log.debug("{} yPos {}", p.getY(), ypos); 9171 } 9172 return new Point(xpos, ypos); 9173 } 9174 9175 double adjust = (5.0 / 90.0); 9176 int awayright = 5; 9177 private final int offSetFromPoint = 5; 9178 9179 //Correct for SM111, sm101, sm121, SM80 9180 Point southEastToNorthWest(Point2D p, PositionableIcon l, int oldWidth, int oldHeight, double angleDEG, boolean right, double fromPoint) { 9181 angleDEG = 360 - angleDEG; 9182 9183 if (angleDEG > 45) { 9184 //Because of the angle things get shifted about. 9185 int tmpWidth = oldWidth; 9186 int tmpHeight = oldHeight; 9187 oldWidth = tmpWidth; 9188 oldHeight = tmpHeight; 9189 } 9190 9191 // double ang = angle; 9192 double oppAng = 90 - angleDEG; 9193 double angleRAD = Math.toRadians(angleDEG); 9194 double oppAngRAD = Math.toRadians(oppAng); 9195 double iconAdj = Math.sin(angleRAD) * oldHeight; 9196 double iconAdjOpp = Math.sin(oppAngRAD) * oldHeight; 9197 double bpa = Math.sin(angleRAD) * (offSetFromPoint + fromPoint); 9198 double bpo = Math.sin(oppAngRAD) * (offSetFromPoint + fromPoint); 9199 double ta = Math.sin(angleRAD) * offSetFromPoint; //distance from track 9200 double to = Math.sin(oppAngRAD) * offSetFromPoint; 9201 if (log.isDebugEnabled()) { 9202 log.debug("south east to north west {}", angleDEG); 9203 log.debug("oldWidth {} oldHeight {}", oldWidth, oldHeight); 9204 log.debug("newWidth {} newHeight {}", l.maxWidth(), l.maxHeight()); 9205 log.debug("Icon adj: {} opp adj: {}", iconAdj, iconAdjOpp); 9206 log.debug("boundary point opp {}", bpo); 9207 log.debug("boundary point adj {}", bpa); 9208 log.debug("track opp {}", to); 9209 log.debug("track adj {}", ta); 9210 } 9211 int xpos = 0; 9212 int ypos = 0; 9213 if (right) { 9214 //double x_dist_to_Icon = bpa+bpo; 9215 //double y_dist_to_Icon = (iconAdj+bpa-bpo); 9216 double x_dist_to_Icon = bpa + to; 9217 double y_dist_to_Icon = (bpo - ta) - (l.maxHeight() - iconAdjOpp); 9218 9219 log.debug("ydist {}", Double.toString((bpo - ta) - (l.maxHeight() - iconAdjOpp))); 9220 log.debug(" and {}",Double.toString(bpo - (iconAdj + ta))); 9221 /*if(angleDeg<45){ 9222 y_dist_to_Icon = (bpo-ta)-(l.maxHeight()-iconAdjOpp); 9223 } else { 9224 y_dist_to_Icon = bpo-(iconAdj+ta); 9225 }*/ 9226 //double y_dist_to_Icon = (l.maxHeight()-iconAdj)+(bpo-ta); 9227 xpos = (int) (p.getX() + x_dist_to_Icon); 9228 ypos = (int) (p.getY() + y_dist_to_Icon); 9229 log.debug("right x dist {}, y dist {}", x_dist_to_Icon, y_dist_to_Icon); 9230 } else { 9231 //double x_dist_to_Icon = l.maxWidth()-(iconAdj+(bpa-bpo)); 9232 //double y_dist_to_Icon = bpa+bpo; 9233 9234 double x_dist_to_Icon = (bpa - to) - (l.maxWidth() - iconAdj); 9235 double y_dist_to_Icon = bpo + ta; 9236 9237 xpos = (int) (p.getX() + x_dist_to_Icon); 9238 ypos = (int) (p.getY() + y_dist_to_Icon); 9239 log.debug("left x dist {}, y dist {}", x_dist_to_Icon, y_dist_to_Icon); 9240 } 9241 if (log.isDebugEnabled()) { 9242 log.debug("{} xpos {}", p.getX(), xpos); 9243 log.debug("{} yPos {}", p.getY(), ypos); 9244 } 9245 9246 return new Point(xpos, ypos); 9247 } 9248 9249 public boolean isSignalMastOnPanel(@Nonnull SignalMast signalMast) { 9250 for (SignalMastIcon s : layoutEditor.getSignalMastList()) { 9251 if (s.getSignalMast() == signalMast) { 9252 return true; 9253 } 9254 } 9255 return false; 9256 } 9257 9258 /*=========================*\ 9259 |* setSignalMastsAtTurnout *| 9260 \*=========================*/ 9261 private JmriJFrame setSignalMastsAtTurnoutFrame = null; 9262 private boolean setSignalMastsAtTurnoutOpenFlag = false; 9263 private boolean setSignalMastsAtTurnoutFromMenuFlag = false; 9264 9265 private final NamedBeanComboBox<Turnout> signalMastsTurnoutComboBox = new NamedBeanComboBox<>( 9266 InstanceManager.turnoutManagerInstance(), null, 9267 DisplayOptions.DISPLAYNAME); 9268 9269 private JButton setSignalMastsDone; 9270 private JButton getSavedSignalMasts; 9271 private JButton setSignalMastsCancel; 9272 private JLabel turnoutMastNameLabel = null; 9273 9274 BeanDetails<SignalMast> turnoutSignalMastA; 9275 BeanDetails<SignalMast> turnoutSignalMastB; 9276 BeanDetails<SignalMast> turnoutSignalMastC; 9277 BeanDetails<SignalMast> turnoutSignalMastD; 9278 9279 JPanel signalMastTurnoutPanel = new JPanel(new FlowLayout()); 9280 9281 private String[] turnoutBlocks = new String[4]; 9282 9283 public void setSignalMastsAtTurnoutFromMenu(@Nonnull LayoutTurnout to, 9284 @Nonnull String[] blocks) { 9285 layoutTurnout = to; 9286 turnout = to.getTurnout(); 9287 signalMastsTurnoutComboBox.setSelectedItem(turnout); 9288 turnoutBlocks = new String[4]; 9289 for (int i = 0; i < blocks.length; i++) { 9290 turnoutBlocks[i] = blocks[i]; 9291 } 9292 setSignalMastsAtTurnoutFromMenuFlag = true; 9293 setSignalMastsAtTurnout(); 9294 setSignalMastsAtTurnoutFromMenuFlag = false; 9295 } 9296 9297 //TODO: Add to Tools menu? 9298 public void setSignalMastsAtTurnout() { 9299 9300 //Initialize if needed 9301 if (setSignalMastsAtTurnoutFrame == null) { 9302 setSignalMastsAtTurnoutOpenFlag = false; 9303 9304 turnoutSignalMastA = new BeanDetails<>("SignalMast", // NOI18N 9305 InstanceManager.getDefault(SignalMastManager.class)); 9306 turnoutSignalMastB = new BeanDetails<>("SignalMast", // NOI18N 9307 InstanceManager.getDefault(SignalMastManager.class)); 9308 turnoutSignalMastC = new BeanDetails<>("SignalMast", // NOI18N 9309 InstanceManager.getDefault(SignalMastManager.class)); 9310 turnoutSignalMastD = new BeanDetails<>("SignalMast", // NOI18N 9311 InstanceManager.getDefault(SignalMastManager.class)); 9312 9313 turnoutSignalMastA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 9314 turnoutSignalMastB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 9315 turnoutSignalMastC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 9316 turnoutSignalMastD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 9317 9318 setSignalMastsAtTurnoutFrame = new JmriJFrame(Bundle.getMessage("SignalMastsAtTurnout"), false, true); 9319 oneFrameToRuleThemAll(setSignalMastsAtTurnoutFrame); 9320 setSignalMastsAtTurnoutFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 9321// setSignalMastsAtTurnoutFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalMastsAtTurnout", true); 9322 setSignalMastsAtTurnoutFrame.setLocation(70, 30); 9323 Container theContentPane = setSignalMastsAtTurnoutFrame.getContentPane(); 9324 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 9325 9326 JPanel panel1 = new JPanel(new FlowLayout()); 9327 9328 turnoutMastNameLabel = new JLabel( 9329 Bundle.getMessage("BeanNameTurnout") 9330 + " " + Bundle.getMessage("Name")); 9331 panel1.add(turnoutMastNameLabel); 9332 panel1.add(signalMastsTurnoutComboBox); 9333 signalMastsTurnoutComboBox.setToolTipText(Bundle.getMessage("SignalMastsTurnoutNameHint")); 9334 9335 theContentPane.add(panel1); 9336 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 9337 9338 JPanel panel2 = new JPanel(new FlowLayout()); 9339 JLabel shTitle = new JLabel(Bundle.getMessage("SignalMasts")); 9340 panel2.add(shTitle); 9341 panel2.add(new JLabel(" ")); 9342 panel2.add(getSavedSignalMasts = new JButton(Bundle.getMessage("GetSaved"))); 9343 getSavedSignalMasts.addActionListener(this::turnoutSignalMastsGetSaved); 9344 getSavedSignalMasts.setToolTipText(Bundle.getMessage("GetSavedHint")); 9345 theContentPane.add(panel2); 9346 9347 signalMastTurnoutPanel.setLayout(new GridLayout(0, 2)); 9348 theContentPane.add(signalMastTurnoutPanel); 9349 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 9350 9351 JPanel panel6 = new JPanel(new FlowLayout()); 9352 panel6.add(new JLabel(" ")); 9353 panel6.add(setSignalMastsDone = new JButton(Bundle.getMessage("ButtonDone"))); 9354 setSignalMastsDone.addActionListener(this::setSignalMastsDonePressed); 9355 setSignalMastsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 9356 9357 panel6.add(setSignalMastsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 9358 setSignalMastsCancel.addActionListener(this::setSignalMastsCancelPressed); 9359 setSignalMastsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 9360 theContentPane.add(panel6); 9361 9362//make this button the default button (return or enter activates) 9363 JRootPane rootPane = SwingUtilities.getRootPane(setSignalMastsDone); 9364 if (rootPane != null) { 9365 rootPane.setDefaultButton(setSignalMastsDone); 9366 } 9367 } 9368 9369 turnoutSignalMastA.getCombo().setExcludedItems(new HashSet<>()); 9370 turnoutSignalMastB.getCombo().setExcludedItems(new HashSet<>()); 9371 turnoutSignalMastC.getCombo().setExcludedItems(new HashSet<>()); 9372 turnoutSignalMastD.getCombo().setExcludedItems(new HashSet<>()); 9373 signalMastTurnoutPanel.removeAll(); 9374 9375 signalMastsTurnoutComboBox.setVisible(!setSignalMastsAtTurnoutFromMenuFlag); 9376 9377 if (setSignalMastsAtTurnoutFromMenuFlag) { 9378 turnoutMastNameLabel.setText(Bundle.getMessage("MakeLabel", 9379 Bundle.getMessage("BeanNameTurnout") 9380 + " " + Bundle.getMessage("Name")) 9381 + " " + layoutTurnout.getTurnoutName()); 9382 } 9383 9384 if (!setSignalMastsAtTurnoutOpenFlag) { 9385 setSignalMastsAtTurnoutFrame.setPreferredSize(null); 9386 setSignalMastsAtTurnoutFrame.pack(); 9387 setSignalMastsAtTurnoutOpenFlag = true; 9388 } 9389 refreshSignalMastAtTurnoutComboBox(); 9390 setSignalMastsAtTurnoutFrame.setVisible(true); 9391 } //setSignalMastsAtTurnout 9392 9393 private void turnoutSignalMastsGetSaved(ActionEvent a) { 9394 if (!getTurnoutMastInformation()) { 9395 return; 9396 } 9397 turnoutBlocks = layoutTurnout.getBlockBoundaries(); 9398 9399 turnoutSignalMastA.setTextField(layoutTurnout.getSignalAMastName()); 9400 turnoutSignalMastB.setTextField(layoutTurnout.getSignalBMastName()); 9401 turnoutSignalMastC.setTextField(layoutTurnout.getSignalCMastName()); 9402 turnoutSignalMastD.setTextField(layoutTurnout.getSignalDMastName()); 9403 9404 turnoutSignalMastA.setBoundaryLabel(turnoutBlocks[0]); 9405 turnoutSignalMastB.setBoundaryLabel(turnoutBlocks[1]); 9406 turnoutSignalMastC.setBoundaryLabel(turnoutBlocks[2]); 9407 turnoutSignalMastD.setBoundaryLabel(turnoutBlocks[3]); 9408 9409 signalMastTurnoutPanel.removeAll(); 9410 boolean boundaryFlag = false; 9411 if (turnoutBlocks[0] != null) { 9412 signalMastTurnoutPanel.add(turnoutSignalMastA.getDetailsPanel()); 9413 boundaryFlag = true; 9414 } 9415 if (turnoutBlocks[1] != null) { 9416 signalMastTurnoutPanel.add(turnoutSignalMastB.getDetailsPanel()); 9417 boundaryFlag = true; 9418 } 9419 if (turnoutBlocks[2] != null) { 9420 signalMastTurnoutPanel.add(turnoutSignalMastC.getDetailsPanel()); 9421 boundaryFlag = true; 9422 } 9423 if (turnoutBlocks[3] != null) { 9424 signalMastTurnoutPanel.add(turnoutSignalMastD.getDetailsPanel()); 9425 boundaryFlag = true; 9426 } 9427 if (!boundaryFlag) { 9428 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("SignalsError20")); 9429 } 9430 setSignalMastsAtTurnoutFrame.setPreferredSize(null); 9431 setSignalMastsAtTurnoutFrame.pack(); 9432 } //turnoutSignalMastsGetSaved 9433 9434 private void setSignalMastsDonePressed(ActionEvent a) { 9435 //process turnout name 9436 if (!getTurnoutMastInformation()) { 9437 return; 9438 } 9439 9440 //process signal head names 9441 SignalMast turnoutMast = getSignalMastFromEntry(turnoutSignalMastA.getText(), false, setSignalsAtTurnoutFrame); 9442 SignalMast turnoutMastB = getSignalMastFromEntry(turnoutSignalMastB.getText(), false, setSignalsAtTurnoutFrame); 9443 SignalMast turnoutMastC = getSignalMastFromEntry(turnoutSignalMastC.getText(), false, setSignalsAtTurnoutFrame); 9444 SignalMast turnoutMastD = getSignalMastFromEntry(turnoutSignalMastD.getText(), false, setSignalsAtTurnoutFrame); 9445 9446 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 9447 9448 //place signals as requested 9449 if (turnoutSignalMastA.addToPanel() && (turnoutMast != null)) { 9450 if (isSignalMastOnPanel(turnoutMast) 9451 && (turnoutMast != layoutTurnout.getSignalAMast())) { 9452 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9453 Bundle.getMessage("SignalsError6", 9454 new Object[]{turnoutSignalMastA.getText()}), 9455 Bundle.getMessage("ErrorTitle"), 9456 JmriJOptionPane.ERROR_MESSAGE); 9457 return; 9458 } else { 9459 removeSignalMastFromPanel(layoutTurnout.getSignalAMast()); 9460 SignalMastIcon l = new SignalMastIcon(layoutEditor); 9461 l.setSignalMast(turnoutSignalMastA.getText()); 9462 placingBlock(l, turnoutSignalMastA.isRightSelected(), 9463 0.0, layoutTurnout.getConnectA(), layoutTurnoutView.getCoordsA()); 9464 removeAssignment(turnoutMast); 9465 layoutTurnout.setSignalAMast(turnoutSignalMastA.getText()); 9466 needRedraw = true; 9467 } 9468 } else if (turnoutMast != null) { 9469 LayoutTurnout.Geometry assigned = isMastAssignedHere(turnoutMast, layoutTurnout); 9470 if (assigned == LayoutTurnout.Geometry.NONE) { 9471 if (isSignalMastOnPanel(turnoutMast) 9472 && isSignalMastAssignedAnywhere(turnoutMast)) { 9473 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9474 Bundle.getMessage("SignalsError8", 9475 new Object[]{turnoutSignalMastA.getText()}), 9476 Bundle.getMessage("ErrorTitle"), 9477 JmriJOptionPane.ERROR_MESSAGE); 9478 return; 9479 } else { 9480 removeSignalMastFromPanel(layoutTurnout.getSignalAMast()); 9481 removeAssignment(turnoutMast); 9482 layoutTurnout.setSignalAMast(turnoutSignalMastA.getText()); 9483 } 9484 //} else if (assigned != A1) { 9485 //need to figure out what to do in this case. 9486 } 9487 } else { 9488 removeSignalMastFromPanel(layoutTurnout.getSignalAMast()); 9489 layoutTurnout.setSignalAMast(""); 9490 } 9491 if ((turnoutSignalMastB.addToPanel()) && (turnoutMastB != null)) { 9492 if (isSignalMastOnPanel(turnoutMastB) 9493 && (turnoutMastB != layoutTurnout.getSignalBMast())) { 9494 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9495 Bundle.getMessage("SignalsError6", 9496 new Object[]{turnoutSignalMastB.getText()}), 9497 Bundle.getMessage("ErrorTitle"), 9498 JmriJOptionPane.ERROR_MESSAGE); 9499 return; 9500 } else { 9501 removeSignalMastFromPanel(layoutTurnout.getSignalBMast()); 9502 SignalMastIcon l = new SignalMastIcon(layoutEditor); 9503 l.setSignalMast(turnoutSignalMastB.getText()); 9504 placingBlock(l, turnoutSignalMastB.isRightSelected(), 9505 0.0, layoutTurnout.getConnectB(), layoutTurnoutView.getCoordsB()); 9506 removeAssignment(turnoutMastB); 9507 layoutTurnout.setSignalBMast(turnoutSignalMastB.getText()); 9508 needRedraw = true; 9509 } 9510 } else if (turnoutMastB != null) { 9511 LayoutTurnout.Geometry assigned = isMastAssignedHere(turnoutMastB, layoutTurnout); 9512 if (assigned == LayoutTurnout.Geometry.NONE) { 9513 if (isSignalMastOnPanel(turnoutMastB) 9514 && isSignalMastAssignedAnywhere(turnoutMastB)) { 9515 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9516 Bundle.getMessage("SignalsError8", 9517 new Object[]{turnoutSignalMastB.getText()}), 9518 Bundle.getMessage("ErrorTitle"), 9519 JmriJOptionPane.ERROR_MESSAGE); 9520 return; 9521 } else { 9522 removeSignalMastFromPanel(layoutTurnout.getSignalBMast()); 9523 removeAssignment(turnoutMastB); 9524 layoutTurnout.setSignalBMast(turnoutSignalMastB.getText()); 9525 } 9526 //} else if (assigned != A2) { 9527 //need to figure out what to do in this case. 9528 } 9529 } else { 9530 removeSignalMastFromPanel(layoutTurnout.getSignalBMast()); 9531 layoutTurnout.setSignalBMast(""); 9532 } 9533 if (turnoutMastC != null) { 9534 if (turnoutSignalMastC.addToPanel()) { 9535 if (isSignalMastOnPanel(turnoutMastC) 9536 && (turnoutMastC != layoutTurnout.getSignalCMast())) { 9537 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9538 Bundle.getMessage("SignalsError6", 9539 new Object[]{turnoutSignalMastC.getText()}), 9540 Bundle.getMessage("ErrorTitle"), 9541 JmriJOptionPane.ERROR_MESSAGE); 9542 return; 9543 } else { 9544 removeSignalMastFromPanel(layoutTurnout.getSignalCMast()); 9545 SignalMastIcon l = new SignalMastIcon(layoutEditor); 9546 l.setSignalMast(turnoutSignalMastC.getText()); 9547 placingBlock(l, turnoutSignalMastC.isRightSelected(), 9548 0.0, layoutTurnout.getConnectC(), layoutTurnoutView.getCoordsC()); 9549 removeAssignment(turnoutMastC); 9550 layoutTurnout.setSignalCMast(turnoutSignalMastC.getText()); 9551 needRedraw = true; 9552 } 9553 } else { 9554 LayoutTurnout.Geometry assigned = isMastAssignedHere(turnoutMastC, layoutTurnout); 9555 if (assigned == LayoutTurnout.Geometry.NONE) { 9556 if (isSignalMastOnPanel(turnoutMastC) 9557 && isSignalMastAssignedAnywhere(turnoutMastC)) { 9558 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9559 Bundle.getMessage("SignalsError8", 9560 new Object[]{turnoutSignalMastC.getText()}), 9561 Bundle.getMessage("ErrorTitle"), 9562 JmriJOptionPane.ERROR_MESSAGE); 9563 return; 9564 } else { 9565 removeSignalMastFromPanel(layoutTurnout.getSignalCMast()); 9566 removeAssignment(turnoutMastC); 9567 layoutTurnout.setSignalCMast(turnoutSignalMastC.getText()); 9568 } 9569 //} else if (assigned != A3) { 9570 //need to figure out what to do in this case. 9571 } 9572 } 9573 } else { 9574 removeSignalMastFromPanel(layoutTurnout.getSignalCMast()); 9575 layoutTurnout.setSignalCMast(""); 9576 } 9577 if (turnoutMastD != null) { 9578 if (turnoutSignalMastD.addToPanel()) { 9579 if (isSignalMastOnPanel(turnoutMastD) 9580 && (turnoutMastD != layoutTurnout.getSignalDMast())) { 9581 String signalHeadName = divergingSignalHeadComboBox.getSelectedItemDisplayName(); 9582 if (signalHeadName == null) { 9583 signalHeadName = ""; 9584 } 9585 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9586 Bundle.getMessage("SignalsError6", 9587 new Object[]{signalHeadName}), 9588 Bundle.getMessage("ErrorTitle"), 9589 JmriJOptionPane.ERROR_MESSAGE); 9590 return; 9591 } else { 9592 removeSignalMastFromPanel(layoutTurnout.getSignalDMast()); 9593 SignalMastIcon l = new SignalMastIcon(layoutEditor); 9594 l.setSignalMast(turnoutSignalMastD.getText()); 9595 placingBlock(l, turnoutSignalMastD.isRightSelected(), 9596 0.0, layoutTurnout.getConnectD(), layoutTurnoutView.getCoordsD()); 9597 removeAssignment(turnoutMastD); 9598 layoutTurnout.setSignalDMast(turnoutSignalMastD.getText()); 9599 needRedraw = true; 9600 } 9601 } else { 9602 LayoutTurnout.Geometry assigned = isMastAssignedHere(turnoutMastD, layoutTurnout); 9603 if (assigned == LayoutTurnout.Geometry.NONE) { 9604 if (isSignalMastOnPanel(turnoutMastD) 9605 && isSignalMastAssignedAnywhere(turnoutMastD)) { 9606 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9607 Bundle.getMessage("SignalsError8", 9608 new Object[]{turnoutSignalMastD.getText()}), 9609 Bundle.getMessage("ErrorTitle"), 9610 JmriJOptionPane.ERROR_MESSAGE); 9611 return; 9612 } else { 9613 removeSignalMastFromPanel(layoutTurnout.getSignalDMast()); 9614 removeAssignment(turnoutMastD); 9615 layoutTurnout.setSignalDMast(turnoutSignalMastD.getText()); 9616 } 9617 //} else if (assigned != B1) { 9618 //need to figure out what to do in this case. 9619 } 9620 } 9621 } else { 9622 removeSignalMastFromPanel(layoutTurnout.getSignalDMast()); 9623 layoutTurnout.setSignalDMast(""); 9624 } 9625 9626 //make sure this layout turnout is not linked to another 9627 layoutTurnout.setLinkType(LayoutTurnout.LinkType.NO_LINK); 9628 layoutTurnout.setLinkedTurnoutName(""); 9629 //finish up 9630 setSignalMastsAtTurnoutOpenFlag = false; 9631 setSignalMastsAtTurnoutFrame.setVisible(false); 9632 if (needRedraw) { 9633 layoutEditor.redrawPanel(); 9634 needRedraw = false; 9635 layoutEditor.setDirty(); 9636 } 9637 } //setSignalMastsDonePressed 9638 9639 9640 public final Set<SignalMast> usedMasts = new HashSet<>(); 9641 9642 public void createListUsedSignalMasts() { 9643 usedMasts.clear(); 9644 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 9645 //We allow the same sensor to be allocated in both directions. 9646 if (po != boundary) { 9647 if (po.getEastBoundSignalMast() != null) { 9648 usedMasts.add(po.getEastBoundSignalMast()); 9649 } 9650 if (po.getWestBoundSignalMast() != null) { 9651 usedMasts.add(po.getWestBoundSignalMast()); 9652 } 9653 } 9654 } 9655 9656 for (LayoutTurnout to : layoutEditor.getLayoutTurnoutsAndSlips()) { 9657 if (to.getSignalAMast() != null) { 9658 usedMasts.add(to.getSignalAMast()); 9659 } 9660 if (to.getSignalBMast() != null) { 9661 usedMasts.add(to.getSignalBMast()); 9662 } 9663 if (to.getSignalCMast() != null) { 9664 usedMasts.add(to.getSignalCMast()); 9665 } 9666 if (to.getSignalDMast() != null) { 9667 usedMasts.add(to.getSignalDMast()); 9668 } 9669 } 9670 for (LevelXing x : layoutEditor.getLevelXings()) { 9671 if (x.getSignalAMast() != null) { 9672 usedMasts.add(x.getSignalAMast()); 9673 } 9674 if (x.getSignalBMast() != null) { 9675 usedMasts.add(x.getSignalBMast()); 9676 } 9677 if (x.getSignalCMast() != null) { 9678 usedMasts.add(x.getSignalCMast()); 9679 } 9680 if (x.getSignalDMast() != null) { 9681 usedMasts.add(x.getSignalDMast()); 9682 } 9683 } 9684 for (LayoutTurntable lt : layoutEditor.getLayoutTurntables()) { 9685 if (lt.getBufferMast() != null) { 9686 usedMasts.add(lt.getBufferMast()); 9687 } 9688 if (lt.getExitSignalMast() != null) { 9689 usedMasts.add(lt.getExitSignalMast()); 9690 } 9691 for (LayoutTurntable.RayTrack ray : lt.getRayTrackList()) { 9692 if (ray.getApproachMast() != null) { 9693 usedMasts.add(ray.getApproachMast()); 9694 } 9695 } 9696 } 9697 for (LayoutTraverser lt : layoutEditor.getLayoutTraversers()) { 9698 if (lt.getBufferMast() != null) { 9699 usedMasts.add(lt.getBufferMast()); 9700 } 9701 if (lt.getExitSignalMast() != null) { 9702 usedMasts.add(lt.getExitSignalMast()); 9703 } 9704 for (LayoutTraverser.SlotTrack slot : lt.getSlotList()) { 9705 if (slot.getApproachMast() != null) { 9706 usedMasts.add(slot.getApproachMast()); 9707 } 9708 } 9709 } 9710 } //createListUsedSignalMasts 9711 9712 void refreshSignalMastAtTurnoutComboBox() { 9713 turnoutSignalMastsGetSaved(null); 9714 createListUsedSignalMasts(); 9715 9716 usedMasts.remove(turnoutSignalMastA.getBean()); 9717 usedMasts.remove(turnoutSignalMastB.getBean()); 9718 usedMasts.remove(turnoutSignalMastC.getBean()); 9719 usedMasts.remove(turnoutSignalMastD.getBean()); 9720 9721 turnoutSignalMastA.getCombo().setExcludedItems(usedMasts); 9722 turnoutSignalMastB.getCombo().setExcludedItems(usedMasts); 9723 turnoutSignalMastC.getCombo().setExcludedItems(usedMasts); 9724 turnoutSignalMastD.getCombo().setExcludedItems(usedMasts); 9725 } 9726 9727 private LayoutTurnout.Geometry isMastAssignedHere( 9728 @CheckForNull SignalMast mast, 9729 @CheckForNull LayoutTurnout lTurnout) { 9730 if ((mast == null) || (lTurnout == null)) { 9731 return LayoutTurnout.Geometry.NONE; 9732 } 9733 String sysName = mast.getSystemName(); 9734 String uName = mast.getUserName(); 9735 9736 String name = lTurnout.getSignalAMastName(); 9737 if (!name.isEmpty() && (name.equals(uName) || name.equals(sysName))) { 9738 return LayoutTurnout.Geometry.POINTA1; 9739 } 9740 name = lTurnout.getSignalBMastName(); 9741 if (!name.isEmpty() && (name.equals(uName) || name.equals(sysName))) { 9742 return LayoutTurnout.Geometry.POINTA2; 9743 } 9744 name = lTurnout.getSignalCMastName(); 9745 if (!name.isEmpty() && (name.equals(uName) || name.equals(sysName))) { 9746 return LayoutTurnout.Geometry.POINTA3; 9747 } 9748 name = lTurnout.getSignalDMastName(); 9749 if (!name.isEmpty() && (name.equals(uName) || name.equals(sysName))) { 9750 return LayoutTurnout.Geometry.POINTB1; 9751 } 9752 return LayoutTurnout.Geometry.NONE; 9753 } //isMastAssignedHere 9754 9755 public void removeAssignment(@Nonnull SignalMast mast) { 9756 String sName = mast.getSystemName(); 9757 String uName = mast.getUserName(); 9758 for (LayoutTurnout to : layoutEditor.getLayoutTurnouts()) { 9759 if ((to.getSignalAMastName().equals(sName) || ((uName != null) 9760 && (to.getSignalAMastName().equals(uName))))) { 9761 to.setSignalAMast(""); 9762 } 9763 if ((to.getSignalBMastName().equals(sName) || ((uName != null) 9764 && (to.getSignalBMastName().equals(uName))))) { 9765 to.setSignalBMast(""); 9766 } 9767 if ((to.getSignalCMastName().equals(sName) || ((uName != null) 9768 && (to.getSignalCMastName().equals(uName))))) { 9769 to.setSignalCMast(""); 9770 } 9771 if ((to.getSignalDMastName().equals(sName) || ((uName != null) 9772 && (to.getSignalDMastName().equals(uName))))) { 9773 to.setSignalDMast(""); 9774 } 9775 } 9776 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 9777 if (po.getEastBoundSignalMastName().equals(sName) || po.getEastBoundSignalMastName().equals(uName)) { 9778 po.setEastBoundSignalMast(""); 9779 } 9780 if (po.getWestBoundSignalMastName().equals(sName) || po.getWestBoundSignalMastName().equals(uName)) { 9781 po.setWestBoundSignalMast(""); 9782 } 9783 } 9784 for (LevelXing x : layoutEditor.getLevelXings()) { 9785 if ( (x.getSignalAMastName().equals(sName) || ((uName != null) 9786 && (x.getSignalAMastName().equals(uName))))) { 9787 x.setSignalAMast(""); 9788 } 9789 if ( (x.getSignalBMastName().equals(sName) || ((uName != null) 9790 && (x.getSignalBMastName().equals(uName))))) { 9791 x.setSignalBMast(""); 9792 } 9793 if ( (x.getSignalCMastName().equals(sName) || ((uName != null) 9794 && (x.getSignalCMastName().equals(uName))))) { 9795 x.setSignalCMast(""); 9796 } 9797 if ( (x.getSignalDMastName().equals(sName) || ((uName != null) 9798 && (x.getSignalDMastName().equals(uName))))) { 9799 x.setSignalDMast(""); 9800 } 9801 } 9802 } //removeAssignment 9803 9804 private boolean getTurnoutMastInformation() { 9805 turnout = null; 9806 layoutTurnout = null; 9807 String str = signalMastsTurnoutComboBox.getSelectedItemDisplayName(); 9808 if ((str == null) || str.isEmpty()) { 9809 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, Bundle.getMessage("SignalsError1") + "qqq", 9810 Bundle.getMessage("ErrorTitle"), 9811 JmriJOptionPane.ERROR_MESSAGE); 9812 return false; 9813 } 9814 turnout = InstanceManager.turnoutManagerInstance().getTurnout(str); 9815 if (turnout == null) { 9816 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9817 Bundle.getMessage("SignalsError2", 9818 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 9819 JmriJOptionPane.ERROR_MESSAGE); 9820 return false; 9821 } else { 9822 String uname = turnout.getUserName(); 9823 if ((uname == null) || uname.isEmpty() 9824 || !uname.equals(str)) { 9825 signalMastsTurnoutComboBox.setSelectedItem(turnout); 9826 } 9827 } 9828 layoutTurnout = layoutEditor.getFinder().findLayoutTurnoutByBean(turnout); 9829 9830 if (layoutTurnout == null) { 9831 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9832 Bundle.getMessage("SignalsError3", 9833 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 9834 JmriJOptionPane.ERROR_MESSAGE); 9835 return false; 9836 } 9837 return true; 9838 } 9839 9840 public void placingBlock(PositionableIcon icon, boolean isRightSide, 9841 double fromPoint, Object obj, Point2D p) { 9842 if (obj instanceof TrackSegment) { 9843 TrackSegment ts = (TrackSegment) obj; 9844 Point2D endPoint; 9845 if (ts.getConnect1() == layoutTurnout) { 9846 endPoint = layoutEditor.getCoords(ts.getConnect2(), ts.getType2()); 9847 } else { 9848 endPoint = layoutEditor.getCoords(ts.getConnect1(), ts.getType1()); 9849 } 9850 boolean isEast = false; 9851 if (MathUtil.equals(endPoint.getX(), p.getX())) { 9852 log.debug("X in both is the same"); 9853 if (endPoint.getY() < p.getY()) { 9854 log.debug("Y end point is less than our point"); 9855 isEast = true; 9856 } 9857 } else if (endPoint.getX() < p.getX()) { 9858 log.debug("end X point is less than our point"); 9859 isEast = true; 9860 } 9861 9862 log.debug("East set is {}", isEast); 9863 setIconOnPanel(ts, icon, isEast, p, endPoint, isRightSide, fromPoint); 9864 } 9865 } 9866 9867 public void placingBlockForTurntable(PositionableIcon icon, boolean isRightSide, 9868 double fromPoint, Object obj, Point2D p) { 9869 if (obj instanceof TrackSegment) { 9870 TrackSegment ts = (TrackSegment) obj; 9871 Point2D endPoint; 9872 // Determine the "other" end of the track segment by comparing coordinates 9873 // with the passed-in anchor point 'p'. This is more robust than checking object references. 9874 if (MathUtil.distance(layoutEditor.getCoords(ts.getConnect1(), ts.getType1()), p) < 1.0) { 9875 // connect1 is at our anchor point 'p', so the other end is connect2 9876 endPoint = layoutEditor.getCoords(ts.getConnect2(), ts.getType2()); 9877 } else { 9878 // connect2 is at our anchor point 'p', so the other end is connect1 9879 endPoint = layoutEditor.getCoords(ts.getConnect1(), ts.getType1()); 9880 } 9881 boolean isEast = false; 9882 if (MathUtil.equals(endPoint.getX(), p.getX())) { 9883 log.debug("X in both is the same"); 9884 if (endPoint.getY() < p.getY()) { 9885 log.debug("Y end point is less than our point"); 9886 isEast = true; 9887 } 9888 } else if (endPoint.getX() < p.getX()) { 9889 log.debug("end X point is less than our point"); 9890 isEast = true; 9891 } 9892 9893 log.debug("East set is {}", isEast); 9894 setIconOnPanel(ts, icon, isEast, p, endPoint, isRightSide, fromPoint); 9895 } 9896 } 9897 9898 private void setSignalMastsCancelPressed(ActionEvent a) { 9899 setSignalMastsAtTurnoutOpenFlag = false; 9900 setSignalMastsAtTurnoutFrame.setVisible(false); 9901 } 9902 9903 /*============================*\ 9904 |* setSignalMastsAtLayoutSlip *| 9905 \*============================*/ 9906 9907 //operational variables for Set SignalMast at Slip tool 9908 private JmriJFrame setSignalMastsAtLayoutSlipFrame = null; 9909 private boolean setSignalMastsAtLayoutSlipOpenFlag = false; 9910 private boolean setSignalMastsAtLayoutSlipFromMenuFlag = false; 9911 9912 private JButton getSavedSlipSignalMasts = null; 9913 private JButton setSlipSignalMastsDone = null; 9914 private JButton setSlipSignalMastsCancel = null; 9915 9916 private String[] slipBlocks = new String[4]; 9917 9918 private final NamedBeanComboBox<Block> slipSignalBlockAComboBox 9919 = new NamedBeanComboBox<>( 9920 InstanceManager.getDefault(BlockManager.class), 9921 null, DisplayOptions.DISPLAYNAME); 9922 private final NamedBeanComboBox<Block> slipSignalBlockBComboBox 9923 = new NamedBeanComboBox<>( 9924 InstanceManager.getDefault(BlockManager.class), 9925 null, DisplayOptions.DISPLAYNAME); 9926 private final NamedBeanComboBox<Block> slipSignalBlockCComboBox 9927 = new NamedBeanComboBox<>( 9928 InstanceManager.getDefault(BlockManager.class), 9929 null, DisplayOptions.DISPLAYNAME); 9930 private final NamedBeanComboBox<Block> slipSignalBlockDComboBox 9931 = new NamedBeanComboBox<>( 9932 InstanceManager.getDefault(BlockManager.class), 9933 null, DisplayOptions.DISPLAYNAME); 9934 9935 private JLabel slipSignalBlockANameLabel = null; 9936 private JLabel slipSignalBlockBNameLabel = null; 9937 private JLabel slipSignalBlockCNameLabel = null; 9938 private JLabel slipSignalBlockDNameLabel = null; 9939 9940 BeanDetails<SignalMast> slipSignalMastA; 9941 BeanDetails<SignalMast> slipSignalMastB; 9942 BeanDetails<SignalMast> slipSignalMastC; 9943 BeanDetails<SignalMast> slipSignalMastD; 9944 9945 JPanel signalMastLayoutSlipPanel = new JPanel(new FlowLayout()); 9946 9947 public void setSignalMastsAtSlipFromMenu(@Nonnull LayoutSlip slip, 9948 @Nonnull String[] blocks, @Nonnull JFrame theFrame) { 9949 layoutSlip = slip; 9950 layoutTurnout = slip; 9951 9952 BlockManager bm = InstanceManager.getDefault(BlockManager.class); 9953 slipSignalBlockAComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockName())); 9954 slipSignalBlockBComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockBName())); 9955 slipSignalBlockCComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockCName())); 9956 slipSignalBlockDComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockDName())); 9957 9958 slipBlocks = new String[4]; 9959 for (int i = 0; i < blocks.length; i++) { 9960 slipBlocks[i] = blocks[i]; 9961 } 9962 setSignalMastsAtLayoutSlipFromMenuFlag = true; 9963 setSignalMastsAtLayoutSlip(theFrame); 9964 } 9965 9966 //TODO: Add to Tools menu? 9967 public void setSignalMastsAtLayoutSlip(@Nonnull JFrame theFrame) { 9968 signalFrame = theFrame; 9969 9970 //Initialize if needed 9971 if (setSignalMastsAtLayoutSlipFrame == null) { 9972 setSignalMastsAtLayoutSlipOpenFlag = false; 9973 9974 slipSignalMastA = new BeanDetails<>("SignalMast", 9975 InstanceManager.getDefault(SignalMastManager.class)); 9976 slipSignalMastB = new BeanDetails<>("SignalMast", 9977 InstanceManager.getDefault(SignalMastManager.class)); 9978 slipSignalMastC = new BeanDetails<>("SignalMast", 9979 InstanceManager.getDefault(SignalMastManager.class)); 9980 slipSignalMastD = new BeanDetails<>("SignalMast", 9981 InstanceManager.getDefault(SignalMastManager.class)); 9982 9983 slipSignalMastA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 9984 slipSignalMastB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 9985 slipSignalMastC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 9986 slipSignalMastD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 9987 9988 setSignalMastsAtLayoutSlipFrame = new JmriJFrame(Bundle.getMessage("SignalMastsAtLayoutSlip"), false, true); 9989 oneFrameToRuleThemAll(setSignalMastsAtLayoutSlipFrame); 9990 setSignalMastsAtLayoutSlipFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 9991// setSignalMastsAtLayoutSlipFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtLayoutSlip", true); 9992 setSignalMastsAtLayoutSlipFrame.setLocation(70, 30); 9993 Container theContentPane = setSignalMastsAtLayoutSlipFrame.getContentPane(); 9994 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 9995 9996 JPanel panel11A = new JPanel(new FlowLayout()); 9997//note: this is just placeholder text; real text is set below 9998 slipSignalBlockANameLabel = new JLabel(" A "); 9999 panel11A.add(slipSignalBlockANameLabel); 10000 panel11A.add(slipSignalBlockAComboBox); 10001 slipSignalBlockAComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10002 theContentPane.add(panel11A); 10003 10004 JPanel panel11B = new JPanel(new FlowLayout()); 10005//note: this is just placeholder text; real text is set below 10006 slipSignalBlockBNameLabel = new JLabel(" B "); 10007 panel11B.add(slipSignalBlockBNameLabel); 10008 panel11B.add(slipSignalBlockBComboBox); 10009 slipSignalBlockBComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10010 theContentPane.add(panel11B); 10011 10012 JPanel panel11C = new JPanel(new FlowLayout()); 10013//note: this is just placeholder text; real text is set below 10014 slipSignalBlockCNameLabel = new JLabel(" C "); 10015 panel11C.add(slipSignalBlockCNameLabel); 10016 panel11C.add(slipSignalBlockCComboBox); 10017 slipSignalBlockCComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10018 theContentPane.add(panel11C); 10019 10020 JPanel panel11D = new JPanel(new FlowLayout()); 10021//note: this is just placeholder text; real text is set below 10022 slipSignalBlockDNameLabel = new JLabel(" D "); 10023 panel11D.add(slipSignalBlockDNameLabel); 10024 panel11D.add(slipSignalBlockDComboBox); 10025 slipSignalBlockDComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10026 theContentPane.add(panel11D); 10027 10028 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 10029 10030 JPanel panel2 = new JPanel(new FlowLayout()); 10031 JLabel shTitle = new JLabel(Bundle.getMessage("BeanNameSignalMast")); 10032 panel2.add(shTitle); 10033 panel2.add(new JLabel(" ")); 10034 panel2.add(getSavedSlipSignalMasts = new JButton(Bundle.getMessage("GetSaved"))); 10035 getSavedSlipSignalMasts.addActionListener(this::slipSignalMastsGetSaved); 10036 getSavedSlipSignalMasts.setToolTipText(Bundle.getMessage("GetSavedHint")); 10037 theContentPane.add(panel2); 10038 10039 signalMastLayoutSlipPanel.setLayout(new GridLayout(0, 2)); 10040 theContentPane.add(signalMastLayoutSlipPanel); 10041 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 10042 10043 JPanel panel6 = new JPanel(new FlowLayout()); 10044 10045 panel6.add(new JLabel(" ")); 10046 panel6.add(setSlipSignalMastsDone = new JButton(Bundle.getMessage("ButtonDone"))); 10047 setSlipSignalMastsDone.addActionListener(this::setSlipSignalMastsDonePressed); 10048 setSlipSignalMastsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 10049 panel6.add(setSlipSignalMastsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 10050 setSlipSignalMastsCancel.addActionListener(this::setSlipSignalMastsCancelPressed); 10051 setSlipSignalMastsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 10052 theContentPane.add(panel6); 10053 setSignalMastsAtLayoutSlipFrame.addWindowListener(new WindowAdapter() { 10054 @Override 10055 public void windowClosing(WindowEvent e) { 10056 setSlipSignalMastsCancelPressed(null); 10057 } 10058 }); 10059 } 10060 10061 //Unhide any excluded masts 10062 slipSignalMastA.getCombo().setExcludedItems(new HashSet<>()); 10063 slipSignalMastB.getCombo().setExcludedItems(new HashSet<>()); 10064 slipSignalMastC.getCombo().setExcludedItems(new HashSet<>()); 10065 slipSignalMastD.getCombo().setExcludedItems(new HashSet<>()); 10066 signalMastLayoutSlipPanel.removeAll(); 10067 10068 slipSignalBlockAComboBox.setVisible(!setSignalMastsAtLayoutSlipFromMenuFlag); 10069 slipSignalBlockBComboBox.setVisible(!setSignalMastsAtLayoutSlipFromMenuFlag); 10070 slipSignalBlockCComboBox.setVisible(!setSignalMastsAtLayoutSlipFromMenuFlag); 10071 slipSignalBlockDComboBox.setVisible(!setSignalMastsAtLayoutSlipFromMenuFlag); 10072 10073 if (setSignalMastsAtLayoutSlipFromMenuFlag) { 10074 slipSignalBlockANameLabel.setText(Bundle.getMessage("MakeLabel", 10075 Bundle.getMessage("BeanNameBlock") + " A " 10076 + Bundle.getMessage("Name")) 10077 + " " + layoutSlip.getBlockName()); 10078 slipSignalBlockBNameLabel.setText(Bundle.getMessage("MakeLabel", 10079 Bundle.getMessage("BeanNameBlock") + " B " 10080 + Bundle.getMessage("Name")) 10081 + " " + layoutSlip.getBlockBName()); 10082 slipSignalBlockCNameLabel.setText(Bundle.getMessage("MakeLabel", 10083 Bundle.getMessage("BeanNameBlock") + " C " 10084 + Bundle.getMessage("Name")) 10085 + " " + layoutSlip.getBlockCName()); 10086 slipSignalBlockDNameLabel.setText(Bundle.getMessage("MakeLabel", 10087 Bundle.getMessage("BeanNameBlock") + " D " 10088 + Bundle.getMessage("Name")) 10089 + " " + layoutSlip.getBlockDName()); 10090 refreshSignalMastAtSlipComboBox(); 10091 } else { 10092 slipSignalBlockANameLabel.setText(Bundle.getMessage("MakeLabel", 10093 Bundle.getMessage("BeanNameBlock") + " A " 10094 + Bundle.getMessage("Name"))); 10095 slipSignalBlockBNameLabel.setText(Bundle.getMessage("MakeLabel", 10096 Bundle.getMessage("BeanNameBlock") + " B " 10097 + Bundle.getMessage("Name"))); 10098 slipSignalBlockCNameLabel.setText(Bundle.getMessage("MakeLabel", 10099 Bundle.getMessage("BeanNameBlock") + " C " 10100 + Bundle.getMessage("Name"))); 10101 slipSignalBlockDNameLabel.setText(Bundle.getMessage("MakeLabel", 10102 Bundle.getMessage("BeanNameBlock") + " D " 10103 + Bundle.getMessage("Name"))); 10104 } 10105 10106 if (!setSignalMastsAtLayoutSlipOpenFlag) { 10107 setSignalMastsAtLayoutSlipFrame.setPreferredSize(null); 10108 setSignalMastsAtLayoutSlipFrame.pack(); 10109 setSignalMastsAtLayoutSlipOpenFlag = true; 10110 } 10111 setSignalMastsAtLayoutSlipFrame.setVisible(true); 10112 } 10113 10114 void refreshSignalMastAtSlipComboBox() { 10115 slipSignalMastsGetSaved(null); 10116 createListUsedSignalMasts(); 10117 10118 usedMasts.remove(slipSignalMastA.getBean()); 10119 usedMasts.remove(slipSignalMastB.getBean()); 10120 usedMasts.remove(slipSignalMastC.getBean()); 10121 usedMasts.remove(slipSignalMastD.getBean()); 10122 10123 slipSignalMastA.getCombo().setExcludedItems(usedMasts); 10124 slipSignalMastB.getCombo().setExcludedItems(usedMasts); 10125 slipSignalMastC.getCombo().setExcludedItems(usedMasts); 10126 slipSignalMastD.getCombo().setExcludedItems(usedMasts); 10127 } 10128 10129 private void slipSignalMastsGetSaved(ActionEvent a) { 10130 if (!getSlipMastInformation()) { 10131 return; 10132 } 10133 slipBlocks = layoutSlip.getBlockBoundaries(); 10134 10135 slipSignalMastA.setTextField(layoutSlip.getSignalAMastName()); 10136 slipSignalMastB.setTextField(layoutSlip.getSignalBMastName()); 10137 slipSignalMastC.setTextField(layoutSlip.getSignalCMastName()); 10138 slipSignalMastD.setTextField(layoutSlip.getSignalDMastName()); 10139 10140 slipSignalMastA.setBoundaryLabel(slipBlocks[0]); 10141 slipSignalMastB.setBoundaryLabel(slipBlocks[1]); 10142 slipSignalMastC.setBoundaryLabel(slipBlocks[2]); 10143 slipSignalMastD.setBoundaryLabel(slipBlocks[3]); 10144 10145 boolean boundaryFlag = false; 10146 signalMastLayoutSlipPanel.remove(slipSignalMastA.getDetailsPanel()); 10147 signalMastLayoutSlipPanel.remove(slipSignalMastB.getDetailsPanel()); 10148 signalMastLayoutSlipPanel.remove(slipSignalMastC.getDetailsPanel()); 10149 signalMastLayoutSlipPanel.remove(slipSignalMastD.getDetailsPanel()); 10150 if (slipBlocks[0] != null) { 10151 signalMastLayoutSlipPanel.add(slipSignalMastA.getDetailsPanel()); 10152 boundaryFlag = true; 10153 } 10154 if (slipBlocks[1] != null) { 10155 signalMastLayoutSlipPanel.add(slipSignalMastB.getDetailsPanel()); 10156 boundaryFlag = true; 10157 } 10158 if (slipBlocks[2] != null) { 10159 signalMastLayoutSlipPanel.add(slipSignalMastC.getDetailsPanel()); 10160 boundaryFlag = true; 10161 } 10162 if (slipBlocks[3] != null) { 10163 signalMastLayoutSlipPanel.add(slipSignalMastD.getDetailsPanel()); 10164 boundaryFlag = true; 10165 } 10166 if (!boundaryFlag) { 10167 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, "There are no block boundaries on this level crossing\nIt is therefore not possible to add Signal Masts to it"); 10168 } 10169 setSignalMastsAtLayoutSlipFrame.setPreferredSize(null); 10170 setSignalMastsAtLayoutSlipFrame.pack(); 10171 } 10172 10173 private boolean getSlipMastInformation() { 10174 if (!setSignalMastsAtLayoutSlipFromMenuFlag) { 10175 layoutSlip = null; 10176 List<LayoutSlip> layoutSlips = layoutEditor.getLayoutSlips(); 10177 if (layoutSlips.size() <= 0) { 10178 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10179 Bundle.getMessage("SignalsError15"), 10180 Bundle.getMessage("ErrorTitle"), 10181 JmriJOptionPane.ERROR_MESSAGE); 10182 return false; 10183 } else if (layoutSlips.size() == 1) { 10184 layoutSlip = layoutSlips.get(0); 10185 } else { 10186 LayoutBlock slipBlockA = null; 10187 //LayoutBlock slipBlockC = null; 10188 slipBlockA = getBlockFromEntry(xingBlockACComboBox); 10189 if (slipBlockA == null) { 10190 return false; 10191 } 10192 10193 int foundCount = 0; 10194 //make two block tests first 10195 for (LayoutSlip x : layoutEditor.getLayoutSlips()) { 10196 LayoutBlock xA = null; 10197 LayoutBlock xB = null; 10198 LayoutBlock xC = null; 10199 LayoutBlock xD = null; 10200 10201 LayoutBlock xAC = x.getLayoutBlock(); 10202 if (x.getConnectA() != null) { 10203 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 10204 } 10205 if (x.getConnectB() != null) { 10206 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 10207 } 10208 if (x.getConnectC() != null) { 10209 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 10210 } 10211 if (x.getConnectD() != null) { 10212 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 10213 } 10214 if (((xA != null) && (xC != null) && ((xA == slipBlockA) 10215 || (xC == slipBlockA))) 10216 || ((xB != null) && (xD != null) && ((xB == slipBlockA) 10217 || (xD == slipBlockA)))) { 10218 layoutSlip = x; 10219 foundCount++; 10220 } else if ((xAC != null) && (xAC == slipBlockA)) { 10221 layoutSlip = x; 10222 foundCount++; 10223 } 10224 } 10225 if (foundCount == 0) { 10226 //try one block test 10227 for (LayoutSlip x : layoutEditor.getLayoutSlips()) { 10228 if (slipBlockA == x.getLayoutBlock()) { 10229 layoutSlip = x; 10230 foundCount++; 10231 } 10232 } 10233 } 10234 if (foundCount > 1) { 10235 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10236 Bundle.getMessage("SignalsError16", 10237 new Object[]{" " + foundCount + " "}), 10238 Bundle.getMessage("ErrorTitle"), 10239 JmriJOptionPane.ERROR_MESSAGE); 10240 return false; 10241 } 10242 if (layoutSlip == null) { 10243 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10244 Bundle.getMessage("SignalsError17"), 10245 Bundle.getMessage("ErrorTitle"), 10246 JmriJOptionPane.ERROR_MESSAGE); 10247 return false; 10248 } 10249 } 10250 } 10251 return true; 10252 } 10253 10254 private void setSlipSignalMastsCancelPressed(ActionEvent a) { 10255 setSignalMastsAtLayoutSlipOpenFlag = false; 10256 setSignalMastsAtLayoutSlipFrame.setVisible(false); 10257 } 10258 10259 private void setSlipSignalMastsDonePressed(ActionEvent a) { 10260 if (!getSlipMastInformation()) { 10261 return; 10262 } 10263 10264 SignalMast aMast = getSignalMastFromEntry(slipSignalMastA.getText(), false, setSignalMastsAtLayoutSlipFrame); 10265 SignalMast bMast = getSignalMastFromEntry(slipSignalMastB.getText(), false, setSignalMastsAtLayoutSlipFrame); 10266 SignalMast cMast = getSignalMastFromEntry(slipSignalMastC.getText(), false, setSignalMastsAtLayoutSlipFrame); 10267 SignalMast dMast = getSignalMastFromEntry(slipSignalMastD.getText(), false, setSignalMastsAtLayoutSlipFrame); 10268 10269 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 10270 10271 //place or update signals as requested 10272 if ((aMast != null) && slipSignalMastA.addToPanel()) { 10273 if (isSignalMastOnPanel(aMast) 10274 && (aMast != layoutSlip.getSignalAMast())) { 10275 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10276 Bundle.getMessage("SignalMastsError6", 10277 new Object[]{slipSignalMastA.getText()}), 10278 Bundle.getMessage("ErrorTitle"), 10279 JmriJOptionPane.ERROR_MESSAGE); 10280 return; 10281 } else { 10282 removeSignalMastFromPanel(layoutSlip.getSignalAMast()); 10283 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10284 l.setSignalMast(slipSignalMastA.getText()); 10285 placingBlock(l, slipSignalMastA.isRightSelected(), 10286 0.0, layoutSlip.getConnectA(), layoutSlipView.getCoordsA()); 10287 removeAssignment(aMast); 10288 layoutSlip.setSignalAMast(slipSignalMastA.getText()); 10289 needRedraw = true; 10290 } 10291 } else if ((aMast != null) 10292 && (aMast != layoutSlip.getSignalAMast()) 10293 && (aMast != layoutSlip.getSignalBMast()) 10294 && (aMast != layoutSlip.getSignalCMast()) 10295 && (aMast != layoutSlip.getSignalDMast())) { 10296 if (isSignalMastOnPanel(aMast)) { 10297 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10298 Bundle.getMessage("SignalMastsError13", 10299 new Object[]{slipSignalMastA.getText()}), 10300 Bundle.getMessage("ErrorTitle"), 10301 JmriJOptionPane.ERROR_MESSAGE); 10302 return; 10303 } else { 10304 removeSignalMastFromPanel(layoutSlip.getSignalAMast()); 10305 removeAssignment(aMast); 10306 layoutSlip.setSignalAMast(slipSignalMastA.getText()); 10307 } 10308 } else if ((aMast != null) 10309 && ((aMast == layoutSlip.getSignalBMast()) 10310 || (aMast == layoutSlip.getSignalCMast()) 10311 || (aMast == layoutSlip.getSignalDMast()))) { 10312 //need to figure out what to do in this case. 10313 log.trace("need to figure out what to do in this case."); 10314 } else if (aMast == null) { 10315 removeSignalMastFromPanel(layoutSlip.getSignalAMast()); 10316 layoutSlip.setSignalAMast(""); 10317 } 10318 if ((bMast != null) && slipSignalMastB.addToPanel()) { 10319 if (isSignalMastOnPanel(bMast) 10320 && (bMast != layoutSlip.getSignalBMast())) { 10321 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10322 Bundle.getMessage("SignalMastsError6", 10323 new Object[]{slipSignalMastB.getText()}), 10324 Bundle.getMessage("ErrorTitle"), 10325 JmriJOptionPane.ERROR_MESSAGE); 10326 return; 10327 } else { 10328 removeSignalMastFromPanel(layoutSlip.getSignalBMast()); 10329 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10330 l.setSignalMast(slipSignalMastB.getText()); 10331 placingBlock(l, slipSignalMastB.isRightSelected(), 10332 0.0, layoutSlip.getConnectB(), layoutSlipView.getCoordsB()); 10333 removeAssignment(bMast); 10334 layoutSlip.setSignalBMast(slipSignalMastB.getText()); 10335 needRedraw = true; 10336 } 10337 } else if ((bMast != null) 10338 && (bMast != layoutSlip.getSignalAMast()) 10339 && (bMast != layoutSlip.getSignalBMast()) 10340 && (bMast != layoutSlip.getSignalCMast()) 10341 && (bMast != layoutSlip.getSignalDMast())) { 10342 if (isSignalMastOnPanel(bMast)) { 10343 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10344 Bundle.getMessage("SignalMastsError13", 10345 new Object[]{slipSignalMastB.getText()}), 10346 Bundle.getMessage("ErrorTitle"), 10347 JmriJOptionPane.ERROR_MESSAGE); 10348 return; 10349 } else { 10350 removeSignalMastFromPanel(layoutSlip.getSignalBMast()); 10351 removeAssignment(bMast); 10352 layoutSlip.setSignalBMast(slipSignalMastB.getText()); 10353 } 10354 } else if ((bMast != null) 10355 && ((bMast == layoutSlip.getSignalAMast()) 10356 || (bMast == layoutSlip.getSignalCMast()) 10357 || (bMast == layoutSlip.getSignalDMast()))) { 10358 //need to figure out what to do in this case. 10359 log.trace("need to figure out what to do in this case."); 10360 } else if (bMast == null) { 10361 removeSignalMastFromPanel(layoutSlip.getSignalBMast()); 10362 layoutSlip.setSignalBMast(""); 10363 } 10364 if ((cMast != null) && slipSignalMastC.addToPanel()) { 10365 if (isSignalMastOnPanel(cMast) 10366 && (cMast != layoutSlip.getSignalCMast())) { 10367 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10368 Bundle.getMessage("SignalMastsError6", 10369 new Object[]{slipSignalMastC.getText()}), 10370 Bundle.getMessage("ErrorTitle"), 10371 JmriJOptionPane.ERROR_MESSAGE); 10372 return; 10373 } else { 10374 removeSignalMastFromPanel(layoutSlip.getSignalCMast()); 10375 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10376 l.setSignalMast(slipSignalMastC.getText()); 10377 placingBlock(l, slipSignalMastA.isRightSelected(), 10378 0.0, layoutSlip.getConnectC(), layoutSlipView.getCoordsC()); 10379 removeAssignment(cMast); 10380 layoutSlip.setSignalCMast(slipSignalMastC.getText()); 10381 needRedraw = true; 10382 } 10383 } else if ((cMast != null) 10384 && (cMast != layoutSlip.getSignalAMast()) 10385 && (cMast != layoutSlip.getSignalBMast()) 10386 && (cMast != layoutSlip.getSignalCMast()) 10387 && (cMast != layoutSlip.getSignalDMast())) { 10388 if (isSignalMastOnPanel(cMast)) { 10389 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10390 Bundle.getMessage("SignalMastsError13", 10391 new Object[]{slipSignalMastC.getText()}), 10392 Bundle.getMessage("ErrorTitle"), 10393 JmriJOptionPane.ERROR_MESSAGE); 10394 return; 10395 } else { 10396 removeSignalMastFromPanel(layoutSlip.getSignalCMast()); 10397 removeAssignment(cMast); 10398 layoutSlip.setSignalCMast(slipSignalMastC.getText()); 10399 } 10400 } else if ((cMast != null) 10401 && ((cMast == layoutSlip.getSignalBMast()) 10402 || (cMast == layoutSlip.getSignalAMast()) 10403 || (cMast == layoutSlip.getSignalDMast()))) { 10404 //need to figure out what to do in this case. 10405 log.trace("need to figure out what to do in this case."); 10406 } else if (cMast == null) { 10407 removeSignalMastFromPanel(layoutSlip.getSignalCMast()); 10408 layoutSlip.setSignalCMast(""); 10409 } 10410 if ((dMast != null) && slipSignalMastD.addToPanel()) { 10411 if (isSignalMastOnPanel(dMast) 10412 && (dMast != layoutSlip.getSignalDMast())) { 10413 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10414 Bundle.getMessage("SignalMastsError6", 10415 new Object[]{slipSignalMastD.getText()}), 10416 Bundle.getMessage("ErrorTitle"), 10417 JmriJOptionPane.ERROR_MESSAGE); 10418 return; 10419 } else { 10420 removeSignalMastFromPanel(layoutSlip.getSignalDMast()); 10421 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10422 l.setSignalMast(slipSignalMastD.getText()); 10423 placingBlock(l, slipSignalMastD.isRightSelected(), 10424 0.0, layoutSlip.getConnectD(), layoutSlipView.getCoordsD()); 10425 removeAssignment(dMast); 10426 layoutSlip.setSignalDMast(slipSignalMastD.getText()); 10427 needRedraw = true; 10428 } 10429 } else if ((dMast != null) 10430 && (dMast != layoutSlip.getSignalAMast()) 10431 && (dMast != layoutSlip.getSignalBMast()) 10432 && (dMast != layoutSlip.getSignalCMast()) 10433 && (dMast != layoutSlip.getSignalDMast())) { 10434 if (isSignalMastOnPanel(dMast)) { 10435 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10436 Bundle.getMessage("SignalMastsError13", 10437 new Object[]{slipSignalMastD.getText()}), 10438 Bundle.getMessage("ErrorTitle"), 10439 JmriJOptionPane.ERROR_MESSAGE); 10440 return; 10441 } else { 10442 removeSignalMastFromPanel(layoutSlip.getSignalDMast()); 10443 removeAssignment(dMast); 10444 layoutSlip.setSignalDMast(slipSignalMastD.getText()); 10445 } 10446 } else if ((dMast != null) 10447 && ((dMast == layoutSlip.getSignalBMast()) 10448 || (dMast == layoutSlip.getSignalCMast()) 10449 || (dMast == layoutSlip.getSignalAMast()))) { 10450 //need to figure out what to do in this case. 10451 log.trace("need to figure out what to do in this case."); 10452 } else if (dMast == null) { 10453 removeSignalMastFromPanel(layoutSlip.getSignalDMast()); 10454 layoutSlip.setSignalDMast(""); 10455 } 10456 //setup logic if requested 10457 //finish up 10458 setSignalMastsAtLayoutSlipOpenFlag = false; 10459 setSignalMastsAtLayoutSlipFrame.setVisible(false); 10460 if (needRedraw) { 10461 layoutEditor.redrawPanel(); 10462 needRedraw = false; 10463 layoutEditor.setDirty(); 10464 } 10465 } 10466 10467 /*===========================*\ 10468 |* setSignalMastsAtLevelXing *| 10469 \*===========================*/ 10470 //operational variables for Set SignalMast at Level Crossing tool 10471 private JmriJFrame setSignalMastsAtLevelXingFrame = null; 10472 private boolean setSignalMastsAtLevelXingOpenFlag = false; 10473 private boolean setSignalMastsAtLevelXingFromMenuFlag = false; 10474 10475 private JLabel xingSignalBlockACNameLabel = null; 10476 private JLabel xingSignalBlockBDNameLabel = null; 10477 10478 private final NamedBeanComboBox<Block> xingBlockACComboBox = new NamedBeanComboBox<>( 10479 InstanceManager.getDefault(BlockManager.class), 10480 null, DisplayOptions.DISPLAYNAME); 10481 private final NamedBeanComboBox<Block> xingBlockBDComboBox = new NamedBeanComboBox<>( 10482 InstanceManager.getDefault(BlockManager.class), 10483 null, DisplayOptions.DISPLAYNAME); 10484 10485 private JButton getSavedXingSignalMasts = null; 10486 private JButton setXingSignalMastsDone = null; 10487 private JButton setXingSignalMastsCancel = null; 10488 10489 private String[] xingBlocks = new String[4]; 10490 10491 BeanDetails<SignalMast> xingSignalMastA; 10492 BeanDetails<SignalMast> xingSignalMastB; 10493 BeanDetails<SignalMast> xingSignalMastC; 10494 BeanDetails<SignalMast> xingSignalMastD; 10495 10496 JPanel signalMastLevelXingPanel = new JPanel(new FlowLayout()); 10497 10498 Border blackline = BorderFactory.createLineBorder(Color.black); 10499 10500 //display dialog for Set Signals at Level Crossing tool 10501 public void setSignalMastsAtLevelXingFromMenu(@Nonnull LevelXing xing, 10502 @Nonnull String[] blocks, 10503 @Nonnull JFrame theFrame) { 10504 levelXing = xing; 10505 BlockManager bm = InstanceManager.getDefault(BlockManager.class); 10506 xingBlockACComboBox.setSelectedItem(bm.getBlock(levelXing.getBlockNameAC())); 10507 xingBlockBDComboBox.setSelectedItem(bm.getBlock(levelXing.getBlockNameBD())); 10508 xingBlocks = new String[4]; 10509 for (int i = 0; i < blocks.length; i++) { 10510 xingBlocks[i] = blocks[i]; 10511 } 10512 setSignalMastsAtLevelXingFromMenuFlag = true; 10513 setSignalMastsAtLevelXing(theFrame); 10514 setSignalMastsAtLevelXingFromMenuFlag = false; 10515 } 10516 10517 //TODO: Add to Tools menu? 10518 public void setSignalMastsAtLevelXing(@Nonnull JFrame theFrame) { 10519 signalFrame = theFrame; 10520 10521 //Initialize if needed 10522 if (setSignalMastsAtLevelXingFrame == null) { 10523 setSignalMastsAtLevelXingOpenFlag = false; 10524 10525 xingSignalMastA = new BeanDetails<>("SignalMast", 10526 InstanceManager.getDefault(SignalMastManager.class 10527 )); 10528 xingSignalMastB = new BeanDetails<>("SignalMast", 10529 InstanceManager.getDefault(SignalMastManager.class 10530 )); 10531 xingSignalMastC = new BeanDetails<>("SignalMast", 10532 InstanceManager.getDefault(SignalMastManager.class 10533 )); 10534 xingSignalMastD = new BeanDetails<>("SignalMast", 10535 InstanceManager.getDefault(SignalMastManager.class 10536 )); 10537 10538 xingSignalMastA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 10539 xingSignalMastB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 10540 xingSignalMastC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 10541 xingSignalMastD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 10542 10543 setSignalMastsAtLevelXingFrame = new JmriJFrame(Bundle.getMessage("SignalMastsAtLevelXing"), false, true); 10544 oneFrameToRuleThemAll(setSignalMastsAtLevelXingFrame); 10545 setSignalMastsAtLevelXingFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 10546 setSignalMastsAtLevelXingFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtLevelXing", true); 10547 setSignalMastsAtLevelXingFrame.setLocation(70, 30); 10548 Container theContentPane = setSignalMastsAtLevelXingFrame.getContentPane(); 10549 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 10550 10551 JPanel panel11 = new JPanel(new FlowLayout()); 10552 xingSignalBlockACNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 10553 Bundle.getMessage("BeanNameBlock") + " AC " 10554 + Bundle.getMessage("Name"))); 10555 panel11.add(xingSignalBlockACNameLabel); 10556 panel11.add(xingBlockACComboBox); 10557 xingBlockACComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10558 theContentPane.add(panel11); 10559 10560 JPanel panel12 = new JPanel(new FlowLayout()); 10561 xingSignalBlockBDNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 10562 Bundle.getMessage("BeanNameBlock") + " BD " 10563 + Bundle.getMessage("Name"))); 10564 panel12.add(xingSignalBlockBDNameLabel); 10565 panel12.add(xingBlockBDComboBox); 10566 xingBlockBDComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10567 theContentPane.add(panel12); 10568 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 10569 10570 JPanel panel2 = new JPanel(new FlowLayout()); 10571 JLabel shTitle = new JLabel(Bundle.getMessage("BeanNameSignalMast")); 10572 panel2.add(shTitle); 10573 panel2.add(new JLabel(" ")); 10574 panel2.add(getSavedXingSignalMasts = new JButton(Bundle.getMessage("GetSaved"))); 10575 getSavedXingSignalMasts.addActionListener(this::xingSignalMastsGetSaved); 10576 getSavedXingSignalMasts.setToolTipText(Bundle.getMessage("GetSavedHint")); 10577 theContentPane.add(panel2); 10578 10579 signalMastLevelXingPanel.setLayout(new GridLayout(0, 2)); 10580 10581 theContentPane.add(signalMastLevelXingPanel); 10582 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 10583 10584 JPanel panel6 = new JPanel(new FlowLayout()); 10585 10586 panel6.add(new JLabel(" ")); 10587 panel6.add(setXingSignalMastsDone = new JButton(Bundle.getMessage("ButtonDone"))); 10588 setXingSignalMastsDone.addActionListener(this::setXingSignalMastsDonePressed); 10589 setXingSignalMastsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 10590 panel6.add(setXingSignalMastsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 10591 setXingSignalMastsCancel.addActionListener(this::setXingSignalMastsCancelPressed); 10592 setXingSignalMastsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 10593 theContentPane.add(panel6); 10594 setSignalMastsAtLevelXingFrame.addWindowListener(new WindowAdapter() { 10595 @Override 10596 public void windowClosing(WindowEvent e) { 10597 setXingSignalMastsCancelPressed(null); 10598 } 10599 }); 10600 } //if (setSignalMastsAtLevelXingFrame == null) 10601 10602 //Unhide any excluded masts 10603 xingSignalMastA.getCombo().setExcludedItems(new HashSet<>()); 10604 xingSignalMastB.getCombo().setExcludedItems(new HashSet<>()); 10605 xingSignalMastC.getCombo().setExcludedItems(new HashSet<>()); 10606 xingSignalMastD.getCombo().setExcludedItems(new HashSet<>()); 10607 signalMastLevelXingPanel.removeAll(); 10608 10609 if (setSignalMastsAtLevelXingFromMenuFlag) { 10610 xingBlockACComboBox.setVisible(false); 10611 xingBlockBDComboBox.setVisible(false); 10612 10613 xingSignalBlockACNameLabel.setText(Bundle.getMessage("MakeLabel", 10614 (Bundle.getMessage("BeanNameBlock") + " AC")) 10615 + " " + levelXing.getBlockNameAC()); 10616 xingSignalBlockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 10617 (Bundle.getMessage("BeanNameBlock") + " BD")) 10618 + " " + levelXing.getBlockNameBD()); 10619 10620 xingSignalMastA.setTextField(levelXing.getSignalAMastName()); 10621 xingSignalMastB.setTextField(levelXing.getSignalBMastName()); 10622 xingSignalMastC.setTextField(levelXing.getSignalCMastName()); 10623 xingSignalMastD.setTextField(levelXing.getSignalDMastName()); 10624 10625 xingSignalMastsGetSaved(null); 10626 refreshSignalMastAtXingComboBox(); 10627 } else { 10628 xingSignalBlockACNameLabel.setText(Bundle.getMessage("MakeLabel", 10629 Bundle.getMessage("BeanNameBlock") + " AC " 10630 + Bundle.getMessage("Name"))); 10631 xingSignalBlockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 10632 Bundle.getMessage("BeanNameBlock") + " BD " 10633 + Bundle.getMessage("Name"))); 10634 } 10635 10636 if (!setSignalMastsAtLevelXingOpenFlag) { 10637 setSignalMastsAtLevelXingFrame.setPreferredSize(null); 10638 setSignalMastsAtLevelXingFrame.pack(); 10639 setSignalMastsAtLevelXingOpenFlag = true; 10640 } 10641 setSignalMastsAtLevelXingFrame.setVisible(true); 10642 } //setSignalMastsAtLevelXing 10643 10644 void refreshSignalMastAtXingComboBox() { 10645 xingSignalMastsGetSaved(null); 10646 createListUsedSignalMasts(); 10647 10648 usedMasts.remove(xingSignalMastA.getBean()); 10649 usedMasts.remove(xingSignalMastB.getBean()); 10650 usedMasts.remove(xingSignalMastC.getBean()); 10651 usedMasts.remove(xingSignalMastD.getBean()); 10652 10653 xingSignalMastA.getCombo().setExcludedItems(usedMasts); 10654 xingSignalMastB.getCombo().setExcludedItems(usedMasts); 10655 xingSignalMastC.getCombo().setExcludedItems(usedMasts); 10656 xingSignalMastD.getCombo().setExcludedItems(usedMasts); 10657 } 10658 10659 private void xingSignalMastsGetSaved(ActionEvent a) { 10660 if (!getLevelCrossingMastInformation()) { 10661 return; 10662 } 10663 xingBlocks = levelXing.getBlockBoundaries(); 10664 10665 xingSignalMastA.setTextField(levelXing.getSignalAMastName()); 10666 xingSignalMastB.setTextField(levelXing.getSignalBMastName()); 10667 xingSignalMastC.setTextField(levelXing.getSignalCMastName()); 10668 xingSignalMastD.setTextField(levelXing.getSignalDMastName()); 10669 10670 xingSignalMastA.setBoundaryLabel(xingBlocks[0]); 10671 xingSignalMastB.setBoundaryLabel(xingBlocks[1]); 10672 xingSignalMastC.setBoundaryLabel(xingBlocks[2]); 10673 xingSignalMastD.setBoundaryLabel(xingBlocks[3]); 10674 10675 boolean boundaryFlag = false; 10676 signalMastLevelXingPanel.remove(xingSignalMastA.getDetailsPanel()); 10677 signalMastLevelXingPanel.remove(xingSignalMastB.getDetailsPanel()); 10678 signalMastLevelXingPanel.remove(xingSignalMastC.getDetailsPanel()); 10679 signalMastLevelXingPanel.remove(xingSignalMastD.getDetailsPanel()); 10680 if (xingBlocks[0] != null) { 10681 signalMastLevelXingPanel.add(xingSignalMastA.getDetailsPanel()); 10682 boundaryFlag = true; 10683 } 10684 if (xingBlocks[1] != null) { 10685 signalMastLevelXingPanel.add(xingSignalMastB.getDetailsPanel()); 10686 boundaryFlag = true; 10687 } 10688 if (xingBlocks[2] != null) { 10689 signalMastLevelXingPanel.add(xingSignalMastC.getDetailsPanel()); 10690 boundaryFlag = true; 10691 } 10692 if (xingBlocks[3] != null) { 10693 signalMastLevelXingPanel.add(xingSignalMastD.getDetailsPanel()); 10694 boundaryFlag = true; 10695 } 10696 if (!boundaryFlag) { 10697 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, "There are no block boundaries on this level crossing\nIt is therefore not possible to add Signal Masts to it"); 10698 } 10699 setSignalMastsAtLevelXingFrame.setPreferredSize(null); 10700 setSignalMastsAtLevelXingFrame.pack(); 10701 } //xingSignalMastsGetSaved 10702 10703 private boolean getLevelCrossingMastInformation() { 10704 if (!setSignalMastsAtLevelXingFromMenuFlag) { 10705 levelXing = null; 10706 List<LevelXing> levelXings = layoutEditor.getLevelXings(); 10707 if (levelXings.size() <= 0) { 10708 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10709 Bundle.getMessage("SignalsError15"), 10710 Bundle.getMessage("ErrorTitle"), 10711 JmriJOptionPane.ERROR_MESSAGE); 10712 return false; 10713 } else if (levelXings.size() == 1) { 10714 levelXing = levelXings.get(0); 10715 } else { 10716 LayoutBlock xingBlockA = null; 10717 LayoutBlock xingBlockC = null; 10718 xingBlockA = getBlockFromEntry(xingBlockACComboBox); 10719 if (xingBlockA == null) { 10720 return false; 10721 } 10722 10723 String theBlockName = xingBlockBDComboBox.getSelectedItemDisplayName(); 10724 if ((theBlockName != null) && !theBlockName.isEmpty()) { 10725 xingBlockC = getBlockFromEntry(xingBlockBDComboBox); 10726 if (xingBlockC == null) { 10727 return false; 10728 } 10729 } 10730 10731 int foundCount = 0; 10732 //make two block tests first 10733 if (xingBlockC != null) { 10734 for (LevelXing x : layoutEditor.getLevelXings()) { 10735 LayoutBlock xA = null; 10736 LayoutBlock xB = null; 10737 LayoutBlock xC = null; 10738 LayoutBlock xD = null; 10739 LayoutBlock xAC = x.getLayoutBlockAC(); 10740 LayoutBlock xBD = x.getLayoutBlockBD(); 10741 if (x.getConnectA() != null) { 10742 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 10743 } 10744 if (x.getConnectB() != null) { 10745 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 10746 } 10747 if (x.getConnectC() != null) { 10748 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 10749 } 10750 if (x.getConnectD() != null) { 10751 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 10752 } 10753 if (((xA != null) && (xC != null) && (((xA == xingBlockA) && (xC == xingBlockC)) 10754 || ((xA == xingBlockC) && (xC == xingBlockA)))) 10755 || ((xB != null) && (xD != null) && (((xB == xingBlockA) && (xD == xingBlockC)) 10756 || ((xB == xingBlockC) && (xD == xingBlockA))))) { 10757 levelXing = x; 10758 foundCount++; 10759 } else if ((xAC != null) && (xBD != null) && (((xAC == xingBlockA) && (xBD == xingBlockC)) 10760 || ((xAC == xingBlockC) && (xBD == xingBlockA)))) { 10761 levelXing = x; 10762 foundCount++; 10763 } 10764 } 10765 } 10766 if (foundCount == 0) { 10767 //try one block test 10768 for (LevelXing x : layoutEditor.getLevelXings()) { 10769 if ((xingBlockA == x.getLayoutBlockAC()) || (xingBlockA == x.getLayoutBlockBD())) { 10770 levelXing = x; 10771 foundCount++; 10772 } 10773 } 10774 } 10775 if (foundCount > 1) { 10776 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10777 Bundle.getMessage("SignalsError16", 10778 new Object[]{" " + foundCount + " "}), 10779 Bundle.getMessage("ErrorTitle"), 10780 JmriJOptionPane.ERROR_MESSAGE); 10781 return false; 10782 } 10783 if (levelXing == null) { 10784 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10785 Bundle.getMessage("SignalsError17"), 10786 Bundle.getMessage("ErrorTitle"), 10787 JmriJOptionPane.ERROR_MESSAGE); 10788 return false; 10789 } 10790 } 10791 } 10792 return true; 10793 } //getLevelCrossingMastInformation 10794 10795 private void setXingSignalMastsCancelPressed(ActionEvent a) { 10796 setSignalMastsAtLevelXingOpenFlag = false; 10797 setSignalMastsAtLevelXingFrame.setVisible(false); 10798 } 10799 10800 private void setXingSignalMastsDonePressed(ActionEvent a) { 10801 if (!getLevelCrossingMastInformation()) { 10802 return; 10803 } 10804 SignalMast aMast = getSignalMastFromEntry(xingSignalMastA.getText(), false, setSignalMastsAtLevelXingFrame); 10805 SignalMast bMast = getSignalMastFromEntry(xingSignalMastB.getText(), false, setSignalMastsAtLevelXingFrame); 10806 SignalMast cMast = getSignalMastFromEntry(xingSignalMastC.getText(), false, setSignalMastsAtLevelXingFrame); 10807 SignalMast dMast = getSignalMastFromEntry(xingSignalMastD.getText(), false, setSignalMastsAtLevelXingFrame); 10808 10809 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 10810 10811 //if ( !getXingSignalMastInformation() ) return; 10812 //place or update signals as requested 10813 if ((aMast != null) && xingSignalMastA.addToPanel()) { 10814 if (isSignalMastOnPanel(aMast) 10815 && (aMast != levelXing.getSignalAMast())) { 10816 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10817 Bundle.getMessage("SignalMastsError6", 10818 new Object[]{xingSignalMastA.getText()}), 10819 Bundle.getMessage("ErrorTitle"), 10820 JmriJOptionPane.ERROR_MESSAGE); 10821 return; 10822 } else { 10823 removeSignalMastFromPanel(levelXing.getSignalAMast()); 10824 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10825 l.setSignalMast(xingSignalMastA.getText()); 10826 placingBlock(l, xingSignalMastA.isRightSelected(), 0.0, levelXing.getConnectA(), levelXingView.getCoordsA()); 10827 removeAssignment(aMast); 10828 levelXing.setSignalAMast(xingSignalMastA.getText()); 10829 needRedraw = true; 10830 } 10831 } else if ((aMast != null) 10832 && (aMast != levelXing.getSignalAMast()) 10833 && (aMast != levelXing.getSignalBMast()) 10834 && (aMast != levelXing.getSignalCMast()) 10835 && (aMast != levelXing.getSignalDMast())) { 10836 if (isSignalMastOnPanel(aMast)) { 10837 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10838 Bundle.getMessage("SignalMastsError13", 10839 new Object[]{xingSignalMastA.getText()}), 10840 Bundle.getMessage("ErrorTitle"), 10841 JmriJOptionPane.ERROR_MESSAGE); 10842 return; 10843 } else { 10844 removeSignalMastFromPanel(levelXing.getSignalAMast()); 10845 removeAssignment(aMast); 10846 levelXing.setSignalAMast(xingSignalMastA.getText()); 10847 } 10848 } else if ((aMast != null) 10849 && ((aMast == levelXing.getSignalBMast()) 10850 || (aMast == levelXing.getSignalCMast()) 10851 || (aMast == levelXing.getSignalDMast()))) { 10852 //need to figure out what to do in this case. 10853 log.trace("need to figure out what to do in this case."); 10854 } else if (aMast == null) { 10855 removeSignalMastFromPanel(levelXing.getSignalAMast()); 10856 levelXing.setSignalAMast(""); 10857 } 10858 if ((bMast != null) && xingSignalMastB.addToPanel()) { 10859 if (isSignalMastOnPanel(bMast) 10860 && (bMast != levelXing.getSignalBMast())) { 10861 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10862 Bundle.getMessage("SignalMastsError6", 10863 new Object[]{xingSignalMastB.getText()}), 10864 Bundle.getMessage("ErrorTitle"), 10865 JmriJOptionPane.ERROR_MESSAGE); 10866 return; 10867 } else { 10868 removeSignalMastFromPanel(levelXing.getSignalBMast()); 10869 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10870 l.setSignalMast(xingSignalMastB.getText()); 10871 placingBlock(l, xingSignalMastB.isRightSelected(), 0.0, levelXing.getConnectB(), levelXingView.getCoordsB()); 10872 removeAssignment(bMast); 10873 levelXing.setSignalBMast(xingSignalMastB.getText()); 10874 needRedraw = true; 10875 } 10876 } else if ((bMast != null) 10877 && (bMast != levelXing.getSignalAMast()) 10878 && (bMast != levelXing.getSignalBMast()) 10879 && (bMast != levelXing.getSignalCMast()) 10880 && (bMast != levelXing.getSignalDMast())) { 10881 if (isSignalMastOnPanel(bMast)) { 10882 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10883 Bundle.getMessage("SignalMastsError13", 10884 new Object[]{xingSignalMastB.getText()}), 10885 Bundle.getMessage("ErrorTitle"), 10886 JmriJOptionPane.ERROR_MESSAGE); 10887 return; 10888 } else { 10889 removeSignalMastFromPanel(levelXing.getSignalBMast()); 10890 removeAssignment(bMast); 10891 levelXing.setSignalBMast(xingSignalMastB.getText()); 10892 } 10893 } else if ((bMast != null) 10894 && ((bMast == levelXing.getSignalAMast()) 10895 || (bMast == levelXing.getSignalCMast()) 10896 || (bMast == levelXing.getSignalBMast()) 10897 || (bMast == levelXing.getSignalDMast()))) { 10898 //need to figure out what to do in this case. 10899 log.trace("need to figure out what to do in this case."); 10900 } else if (bMast == null) { 10901 removeSignalMastFromPanel(levelXing.getSignalBMast()); 10902 levelXing.setSignalBMast(""); 10903 } 10904 if ((cMast != null) && xingSignalMastC.addToPanel()) { 10905 if (isSignalMastOnPanel(cMast) 10906 && (cMast != levelXing.getSignalCMast())) { 10907 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10908 Bundle.getMessage("SignalMastsError6", 10909 new Object[]{xingSignalMastC.getText()}), 10910 Bundle.getMessage("ErrorTitle"), 10911 JmriJOptionPane.ERROR_MESSAGE); 10912 return; 10913 } else { 10914 removeSignalMastFromPanel(levelXing.getSignalCMast()); 10915 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10916 l.setSignalMast(xingSignalMastC.getText()); 10917 placingBlock(l, xingSignalMastC.isRightSelected(), 0.0, levelXing.getConnectC(), levelXingView.getCoordsC()); 10918 removeAssignment(cMast); 10919 levelXing.setSignalCMast(xingSignalMastC.getText()); 10920 needRedraw = true; 10921 } 10922 } else if ((cMast != null) 10923 && (cMast != levelXing.getSignalAMast()) 10924 && (cMast != levelXing.getSignalBMast()) 10925 && (cMast != levelXing.getSignalCMast()) 10926 && (cMast != levelXing.getSignalDMast())) { 10927 if (isSignalMastOnPanel(cMast)) { 10928 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10929 Bundle.getMessage("SignalMastsError13", 10930 new Object[]{xingSignalMastC.getText()}), 10931 Bundle.getMessage("ErrorTitle"), 10932 JmriJOptionPane.ERROR_MESSAGE); 10933 return; 10934 } else { 10935 removeSignalMastFromPanel(levelXing.getSignalCMast()); 10936 removeAssignment(cMast); 10937 levelXing.setSignalCMast(xingSignalMastC.getText()); 10938 } 10939 } else if ((cMast != null) 10940 && ((cMast == levelXing.getSignalBMast()) 10941 || (cMast == levelXing.getSignalAMast()) 10942 || (cMast == levelXing.getSignalDMast()))) { 10943 //need to figure out what to do in this case. 10944 log.trace("need to figure out what to do in this case."); 10945 } else if (cMast == null) { 10946 removeSignalMastFromPanel(levelXing.getSignalCMast()); 10947 levelXing.setSignalCName(""); 10948 } 10949 if ((dMast != null) && xingSignalMastD.addToPanel()) { 10950 if (isSignalMastOnPanel(dMast) 10951 && (dMast != levelXing.getSignalDMast())) { 10952 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10953 Bundle.getMessage("SignalMastsError6", 10954 new Object[]{xingSignalMastD.getText()}), 10955 Bundle.getMessage("ErrorTitle"), 10956 JmriJOptionPane.ERROR_MESSAGE); 10957 return; 10958 } else { 10959 removeSignalMastFromPanel(levelXing.getSignalDMast()); 10960 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10961 l.setSignalMast(xingSignalMastD.getText()); 10962 placingBlock(l, xingSignalMastD.isRightSelected(), 0.0, levelXing.getConnectD(), levelXingView.getCoordsD()); 10963 removeAssignment(dMast); 10964 levelXing.setSignalDMast(xingSignalMastD.getText()); 10965 needRedraw = true; 10966 } 10967 } else if ((dMast != null) 10968 && (dMast != levelXing.getSignalAMast()) 10969 && (dMast != levelXing.getSignalBMast()) 10970 && (dMast != levelXing.getSignalCMast()) 10971 && (dMast != levelXing.getSignalDMast())) { 10972 if (isSignalMastOnPanel(dMast)) { 10973 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10974 Bundle.getMessage("SignalMastsError13", 10975 new Object[]{xingSignalMastD.getText()}), 10976 Bundle.getMessage("ErrorTitle"), 10977 JmriJOptionPane.ERROR_MESSAGE); 10978 return; 10979 } else { 10980 removeSignalMastFromPanel(levelXing.getSignalDMast()); 10981 removeAssignment(dMast); 10982 levelXing.setSignalDMast(xingSignalMastD.getText()); 10983 } 10984 } else if ((dMast != null) 10985 && ((dMast == levelXing.getSignalBMast()) 10986 || (dMast == levelXing.getSignalCMast()) 10987 || (dMast == levelXing.getSignalAMast()))) { 10988 //need to figure out what to do in this case. 10989 log.trace("need to figure out what to do in this case."); 10990 } else if (dMast == null) { 10991 removeSignalMastFromPanel(levelXing.getSignalDMast()); 10992 levelXing.setSignalDMast(""); 10993 } 10994 //setup logic if requested 10995 //finish up 10996 setSignalMastsAtLevelXingOpenFlag = false; 10997 setSignalMastsAtLevelXingFrame.setVisible(false); 10998 if (needRedraw) { 10999 layoutEditor.redrawPanel(); 11000 needRedraw = false; 11001 layoutEditor.setDirty(); 11002 } 11003 } //setXingSignalMastsDonePressed 11004 11005 /*=====================*\ 11006 |* setSensorsAtTurnout *| 11007 \*=====================*/ 11008 private JmriJFrame setSensorsAtTurnoutFrame = null; 11009 private boolean setSensorsAtTurnoutOpenFlag = false; 11010 private boolean setSensorsAtTurnoutFromMenuFlag = false; 11011 11012 private JFrame turnoutSensorFrame = null; 11013 private JLabel turnoutSensorNameLabel = null; 11014 11015 private final NamedBeanComboBox<Turnout> sensorsTurnoutComboBox 11016 = new NamedBeanComboBox<>( 11017 InstanceManager.turnoutManagerInstance(), 11018 null, DisplayOptions.DISPLAYNAME); 11019 11020 private JButton setSensorsDone; 11021 private JButton getSavedSensors; 11022 private JButton setSensorsCancel; 11023 private JButton changeSensorIcon = null; 11024 11025 private String[] turnoutSenBlocks = new String[4]; 11026 11027 BeanDetails<Sensor> turnoutSensorA; 11028 BeanDetails<Sensor> turnoutSensorB; 11029 BeanDetails<Sensor> turnoutSensorC; 11030 BeanDetails<Sensor> turnoutSensorD; 11031 11032 JPanel sensorTurnoutPanel = new JPanel(new FlowLayout()); 11033 11034 public void setSensorsAtTurnoutFromMenu(@Nonnull LayoutTurnout to, 11035 @Nonnull String[] blocks, 11036 @Nonnull MultiIconEditor theEditor, 11037 @Nonnull JFrame frame) { 11038 sensorIconEditor = theEditor; 11039 layoutTurnout = to; 11040 turnout = to.getTurnout(); 11041 sensorsTurnoutComboBox.setSelectedItem(turnout); 11042 turnoutSenBlocks = new String[4]; 11043 for (int i = 0; i < blocks.length; i++) { 11044 turnoutSenBlocks[i] = blocks[i]; 11045 } 11046 setSensorsAtTurnoutFromMenuFlag = true; 11047 setSensorsAtTurnout(frame); 11048 setSensorsAtTurnoutFromMenuFlag = false; 11049 } 11050 11051 //TODO: Add to Tools menu? 11052 public void setSensorsAtTurnout(@Nonnull JFrame frame) { 11053 turnoutSensorFrame = frame; 11054 11055 //Initialize if needed 11056 if (setSensorsAtTurnoutFrame == null) { 11057 setSensorsAtTurnoutOpenFlag = false; 11058 11059 turnoutSensorA = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); // NOI18N 11060 turnoutSensorB = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); // NOI18N 11061 turnoutSensorC = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); // NOI18N 11062 turnoutSensorD = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); // NOI18N 11063 11064 turnoutSensorA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 11065 turnoutSensorB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 11066 turnoutSensorC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 11067 turnoutSensorD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 11068 11069 setSensorsAtTurnoutFrame = new JmriJFrame(Bundle.getMessage("SensorsAtTurnout"), false, true); 11070 oneFrameToRuleThemAll(setSensorsAtTurnoutFrame); 11071 setSensorsAtTurnoutFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 11072// setSensorsAtTurnoutFrame.addHelpMenu("package.jmri.jmrit.display.SetSensorsAtTurnout", true); 11073 setSensorsAtTurnoutFrame.setLocation(70, 30); 11074 Container theContentPane = setSensorsAtTurnoutFrame.getContentPane(); 11075 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 11076 11077 JPanel panel1 = new JPanel(new FlowLayout()); 11078 11079 turnoutSensorNameLabel = new JLabel(Bundle.getMessage("BeanNameTurnout") + " " 11080 + Bundle.getMessage("Name")); 11081 panel1.add(turnoutSensorNameLabel); 11082 panel1.add(sensorsTurnoutComboBox); 11083 sensorsTurnoutComboBox.setToolTipText(Bundle.getMessage("SensorsTurnoutNameHint")); 11084 11085 theContentPane.add(panel1); 11086 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 11087 11088 JPanel panel2 = new JPanel(new FlowLayout()); 11089 JLabel shTitle = new JLabel(Bundle.getMessage("Sensors")); 11090 panel2.add(shTitle); 11091 panel2.add(new JLabel(" ")); 11092 panel2.add(getSavedSensors = new JButton(Bundle.getMessage("GetSaved"))); 11093 getSavedSensors.addActionListener(this::turnoutSensorsGetSaved); 11094 getSavedSensors.setToolTipText(Bundle.getMessage("GetSavedHint")); 11095 theContentPane.add(panel2); 11096 11097 sensorTurnoutPanel.setLayout(new GridLayout(0, 2)); //Content added as needed 11098 theContentPane.add(sensorTurnoutPanel); 11099 11100 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 11101 11102 JPanel panel6 = new JPanel(new FlowLayout()); 11103 panel6.add(changeSensorIcon = new JButton(Bundle.getMessage("ChangeSensorIcon"))); 11104 changeSensorIcon.addActionListener((ActionEvent e) -> turnoutSensorFrame.setVisible(true)); 11105 changeSensorIcon.setToolTipText(Bundle.getMessage("ChangeSensorIconHint")); 11106 panel6.add(new JLabel(" ")); 11107 panel6.add(setSensorsDone = new JButton(Bundle.getMessage("ButtonDone"))); 11108 setSensorsDone.addActionListener(this::setSensorsDonePressed); 11109 setSensorsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 11110 panel6.add(setSensorsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 11111 setSensorsCancel.addActionListener(this::setSensorsCancelPressed); 11112 setSensorsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 11113 theContentPane.add(panel6); 11114 setSensorsAtTurnoutFrame.addWindowListener(new WindowAdapter() { 11115 @Override 11116 public void windowClosing(WindowEvent e) { 11117 setSensorsCancelPressed(null); 11118 } 11119 }); 11120 } 11121 11122 sensorTurnoutPanel.removeAll(); 11123 11124 sensorsTurnoutComboBox.setVisible(!setSensorsAtTurnoutFromMenuFlag); 11125 11126 if (setSensorsAtTurnoutFromMenuFlag) { 11127 turnoutSensorNameLabel.setText(Bundle.getMessage("MakeLabel", 11128 Bundle.getMessage("BeanNameTurnout") 11129 + " " + Bundle.getMessage("Name")) 11130 + " " + layoutTurnout.getTurnoutName()); 11131 turnoutSensorsGetSaved(null); 11132 } else { 11133 turnoutSensorNameLabel.setText(Bundle.getMessage("BeanNameTurnout") + " " 11134 + Bundle.getMessage("Name")); 11135 } 11136 11137 if (!setSensorsAtTurnoutOpenFlag) { 11138 setSensorsAtTurnoutFrame.setPreferredSize(null); 11139 setSensorsAtTurnoutFrame.pack(); 11140 setSensorsAtTurnoutOpenFlag = true; 11141 } 11142 setSensorsAtTurnoutFrame.setVisible(true); 11143 } //setSensorsAtTurnout 11144 11145 private void turnoutSensorsGetSaved(ActionEvent a) { 11146 if (!getTurnoutSensorInformation()) { 11147 return; 11148 } 11149 turnoutSenBlocks = layoutTurnout.getBlockBoundaries(); 11150 11151 turnoutSensorA.setTextField(layoutTurnout.getSensorAName()); 11152 turnoutSensorB.setTextField(layoutTurnout.getSensorBName()); 11153 turnoutSensorC.setTextField(layoutTurnout.getSensorCName()); 11154 turnoutSensorD.setTextField(layoutTurnout.getSensorDName()); 11155 11156 turnoutSensorA.setBoundaryLabel(turnoutSenBlocks[0]); 11157 turnoutSensorB.setBoundaryLabel(turnoutSenBlocks[1]); 11158 turnoutSensorC.setBoundaryLabel(turnoutSenBlocks[2]); 11159 turnoutSensorD.setBoundaryLabel(turnoutSenBlocks[3]); 11160 11161 sensorTurnoutPanel.remove(turnoutSensorA.getDetailsPanel()); 11162 sensorTurnoutPanel.remove(turnoutSensorB.getDetailsPanel()); 11163 sensorTurnoutPanel.remove(turnoutSensorC.getDetailsPanel()); 11164 sensorTurnoutPanel.remove(turnoutSensorD.getDetailsPanel()); 11165 11166 boolean boundaryFlag = false; 11167 if (turnoutSenBlocks[0] != null) { 11168 sensorTurnoutPanel.add(turnoutSensorA.getDetailsPanel()); 11169 boundaryFlag = true; 11170 } 11171 if (turnoutSenBlocks[1] != null) { 11172 sensorTurnoutPanel.add(turnoutSensorB.getDetailsPanel()); 11173 boundaryFlag = true; 11174 } 11175 if (turnoutSenBlocks[2] != null) { 11176 sensorTurnoutPanel.add(turnoutSensorC.getDetailsPanel()); 11177 boundaryFlag = true; 11178 } 11179 if (turnoutSenBlocks[3] != null) { 11180 sensorTurnoutPanel.add(turnoutSensorD.getDetailsPanel()); 11181 boundaryFlag = true; 11182 } 11183 if (!boundaryFlag) { 11184 JmriJOptionPane.showMessageDialog(setSensorsAtTurnoutFrame, "There are no block boundaries on this turnout\nIt is therefore not possible to add Sensors to it"); 11185 } 11186 setSensorsAtTurnoutFrame.setPreferredSize(null); 11187 setSensorsAtTurnoutFrame.pack(); 11188 } //turnoutSensorsGetSaved 11189 11190 SensorIcon turnoutSensorBlockIcon; 11191 11192 private void setSensorsDonePressed(ActionEvent a) { 11193 log.trace("setSensorsDonePressed (turnouts)"); // NOI18N 11194 if (!getTurnoutSensorInformation()) { 11195 return; 11196 } 11197 11198 //process sensor names 11199 Sensor sensorA = getSensorFromEntry(turnoutSensorA.getText(), false, setSensorsAtTurnoutFrame); 11200 Sensor sensorB = getSensorFromEntry(turnoutSensorB.getText(), false, setSensorsAtTurnoutFrame); 11201 Sensor sensorC = getSensorFromEntry(turnoutSensorC.getText(), false, setSensorsAtTurnoutFrame); 11202 Sensor sensorD = getSensorFromEntry(turnoutSensorD.getText(), false, setSensorsAtTurnoutFrame); 11203 11204 Sensor currSensorA = layoutTurnout.getSensorA(); 11205 Sensor currSensorB = layoutTurnout.getSensorB(); 11206 Sensor currSensorC = layoutTurnout.getSensorC(); 11207 Sensor currSensorD = layoutTurnout.getSensorD(); 11208 11209 if (log.isTraceEnabled()) { 11210 log.trace("current sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 11211 (currSensorA == null) ? "- none- " : currSensorA.getDisplayName(), // NOI18N 11212 (currSensorB == null) ? "- none- " : currSensorB.getDisplayName(), // NOI18N 11213 (currSensorC == null) ? "- none- " : currSensorC.getDisplayName(), // NOI18N 11214 (currSensorD == null) ? "- none- " : currSensorD.getDisplayName()); // NOI18N 11215 log.trace("new sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 11216 (sensorA == null) ? "- none- " : sensorA.getDisplayName(), // NOI18N 11217 (sensorB == null) ? "- none- " : sensorB.getDisplayName(), // NOI18N 11218 (sensorC == null) ? "- none- " : sensorC.getDisplayName(), // NOI18N 11219 (sensorD == null) ? "- none- " : sensorD.getDisplayName()); // NOI18N 11220 } 11221 11222 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 11223 11224 //place/remove sensors as requested 11225 if (sensorA == null) { 11226 if (currSensorA != null && removeSensorFromPanel(currSensorA)) { 11227 layoutTurnout.setSensorA(null); 11228 } 11229 } else if (turnoutSensorA != null && layoutTurnout.getConnectA() != null) { 11230 setTurnoutSensor(layoutTurnout, sensorA, currSensorA, turnoutSensorA, layoutTurnout.getConnectA(), layoutTurnoutView.getCoordsA(), "A"); 11231 } 11232 11233 if (sensorB == null) { 11234 if (currSensorB != null && removeSensorFromPanel(currSensorB)) { 11235 layoutTurnout.setSensorB(null); 11236 } 11237 } else if (turnoutSensorB != null && layoutTurnout.getConnectB() != null) { 11238 setTurnoutSensor(layoutTurnout, sensorB, currSensorB, turnoutSensorB, layoutTurnout.getConnectB(), layoutTurnoutView.getCoordsB(), "B"); 11239 } 11240 11241 if (sensorC == null) { 11242 if (currSensorC != null && removeSensorFromPanel(currSensorC)) { 11243 layoutTurnout.setSensorC(null); 11244 } 11245 } else if (turnoutSensorC != null && layoutTurnout.getConnectC() != null) { 11246 setTurnoutSensor(layoutTurnout, sensorC, currSensorC, turnoutSensorC, layoutTurnout.getConnectC(), layoutTurnoutView.getCoordsC(), "C"); 11247 } 11248 11249 if (sensorD == null) { 11250 if (currSensorD != null && removeSensorFromPanel(currSensorD)) { 11251 layoutTurnout.setSensorD(null); 11252 } 11253 } else if (turnoutSensorD != null && layoutTurnout.getConnectD() != null) { 11254 setTurnoutSensor(layoutTurnout, sensorD, currSensorD, turnoutSensorD, layoutTurnout.getConnectD(), layoutTurnoutView.getCoordsD(), "D"); 11255 } 11256 11257 //make sure this layout turnout is not linked to another 11258 layoutTurnout.setLinkType(LayoutTurnout.LinkType.NO_LINK); 11259 layoutTurnout.setLinkedTurnoutName(""); 11260 11261 //finish up 11262 setSensorsAtTurnoutOpenFlag = false; 11263 setSensorsAtTurnoutFrame.setVisible(false); 11264 if (needRedraw) { 11265 layoutEditor.redrawPanel(); 11266 needRedraw = false; 11267 layoutEditor.setDirty(); 11268 } 11269 } //setSensorsDonePressed 11270 11271 /** 11272 * Attached a sensor to a turnout block boundary. Supports both 11273 * LayoutTurnout and LayoutSlip classes. 11274 * 11275 * @since 4.11.2 11276 * @param <T> The specific type, a subtype of LayoutTurnout 11277 * @param trackItem The turnout or slip that is being modified. 11278 * @param newSensor The sensor that is being added. 11279 * @param currSensor The sensor that might already be there, otherwise null. 11280 * @param beanDetail The BeanDetails object that contains the supporting 11281 * data. 11282 * @param connect The track segment that is attached to this point 11283 * @param coords The track componennt coordinates 11284 * @param position Which of the four points is being changed 11285 */ 11286 <T extends LayoutTurnout> void setTurnoutSensor(T trackItem, Sensor newSensor, Sensor currSensor, 11287 BeanDetails<? extends NamedBean> beanDetail, LayoutTrack connect, Point2D coords, String position) { 11288 if (currSensor == null) { 11289 if (!isSensorAssignedAnywhere(newSensor)) { 11290 log.trace("Add sensor '{}'", newSensor.getDisplayName()); // NOI18N 11291 switch (position) { 11292 case "A": // NOI18N 11293 trackItem.setSensorA(beanDetail.getText()); 11294 break; 11295 case "B": // NOI18N 11296 trackItem.setSensorB(beanDetail.getText()); 11297 break; 11298 case "C": // NOI18N 11299 trackItem.setSensorC(beanDetail.getText()); 11300 break; 11301 case "D": // NOI18N 11302 trackItem.setSensorD(beanDetail.getText()); 11303 break; 11304 default: 11305 break; 11306 } 11307 if (beanDetail.addToPanel()) { 11308 log.trace("Add icon for sensor '{}'", newSensor.getDisplayName()); // NOI18N 11309 placingBlock(getSensorIcon(beanDetail.getText()), 11310 beanDetail.isRightSelected(), 0.0, 11311 connect, coords); 11312 needRedraw = true; 11313 } 11314 } else { 11315 sensorAssignedElseWhere(newSensor); 11316 } 11317 } else if (currSensor == newSensor) { 11318 if (beanDetail.addToPanel()) { 11319 if (!isSensorOnPanel(newSensor)) { 11320 log.trace("Add icon for existing sensor '{}'", newSensor.getDisplayName()); // NOI18N 11321 placingBlock(getSensorIcon(beanDetail.getText()), 11322 beanDetail.isRightSelected(), 0.0, 11323 connect, coords); 11324 needRedraw = true; 11325 } 11326 } 11327 } else { 11328 if (!isSensorAssignedAnywhere(newSensor)) { 11329 if (removeSensorFromPanel(currSensor)) { 11330 log.trace("Replace sensor '{}' with sensor '{}'", // NOI18N 11331 currSensor.getDisplayName(), newSensor.getDisplayName()); 11332 switch (position) { 11333 case "A": // NOI18N 11334 trackItem.setSensorA(beanDetail.getText()); 11335 break; 11336 case "B": // NOI18N 11337 trackItem.setSensorB(beanDetail.getText()); 11338 break; 11339 case "C": // NOI18N 11340 trackItem.setSensorC(beanDetail.getText()); 11341 break; 11342 case "D": // NOI18N 11343 trackItem.setSensorD(beanDetail.getText()); 11344 break; 11345 default: 11346 break; 11347 } 11348 if (beanDetail.addToPanel()) { 11349 log.trace("Add icon for replacement sensor '{}'", // NOI18N 11350 newSensor.getDisplayName()); 11351 placingBlock(getSensorIcon(beanDetail.getText()), 11352 beanDetail.isRightSelected(), 0.0, 11353 connect, coords); 11354 needRedraw = true; 11355 } 11356 } 11357 } else { 11358 sensorAssignedElseWhere(newSensor); 11359 } 11360 } 11361 } 11362 11363 private boolean getTurnoutSensorInformation() { 11364 turnout = null; 11365 layoutTurnout = null; 11366 String str = sensorsTurnoutComboBox.getSelectedItemDisplayName(); 11367 if ((str == null) || str.isEmpty()) { 11368 JmriJOptionPane.showMessageDialog(setSensorsAtTurnoutFrame, Bundle.getMessage("SensorsError1"), 11369 Bundle.getMessage("ErrorTitle"), 11370 JmriJOptionPane.ERROR_MESSAGE); 11371 return false; 11372 } 11373 turnout = InstanceManager.turnoutManagerInstance().getTurnout(str); 11374 if (turnout == null) { 11375 JmriJOptionPane.showMessageDialog(setSensorsAtTurnoutFrame, 11376 Bundle.getMessage("SensorsError2", 11377 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 11378 JmriJOptionPane.ERROR_MESSAGE); 11379 return false; 11380 } else { 11381 String uname = turnout.getUserName(); 11382 if ((uname == null) || uname.isEmpty() 11383 || !uname.equals(str)) { 11384 sensorsTurnoutComboBox.setSelectedItem(turnout); 11385 } 11386 } 11387 layoutTurnout = layoutEditor.getFinder().findLayoutTurnoutByBean(turnout); 11388 if (layoutTurnout == null) { 11389 JmriJOptionPane.showMessageDialog(setSensorsAtTurnoutFrame, 11390 Bundle.getMessage("SensorsError3", 11391 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 11392 JmriJOptionPane.ERROR_MESSAGE); 11393 return false; 11394 } 11395 return true; 11396 } //getTurnoutSensorInformation 11397 11398 private void setSensorsCancelPressed(ActionEvent a) { 11399 setSensorsAtTurnoutOpenFlag = false; 11400 setSensorsAtTurnoutFrame.setVisible(false); 11401 } 11402 11403 /*=======================*\ 11404 |* setSensorsAtLevelXing *| 11405 \*=======================*/ 11406 //operational variables for Set Sensors at Level Crossing tool 11407 private JmriJFrame setSensorsAtLevelXingFrame = null; 11408 private boolean setSensorsAtLevelXingOpenFlag = false; 11409 private boolean setSensorsAtLevelXingFromMenuFlag = false; 11410 11411 private JLabel xingSensorsBlockACNameLabel = null; 11412 private JLabel xingSensorsBlockBDNameLabel = null; 11413 11414 private final NamedBeanComboBox<Block> xingSensorsBlockACComboBox 11415 = new NamedBeanComboBox<>( 11416 InstanceManager.getDefault(BlockManager.class), 11417 null, DisplayOptions.DISPLAYNAME); 11418 private final NamedBeanComboBox<Block> xingSensorsBlockBDComboBox 11419 = new NamedBeanComboBox<>( 11420 InstanceManager.getDefault(BlockManager.class), 11421 null, DisplayOptions.DISPLAYNAME); 11422 11423 private JButton getSavedXingSensors = null; 11424 private JButton setXingSensorsDone = null; 11425 private JButton setXingSensorsCancel = null; 11426 private JButton changeSensorXingIcon = null; 11427 JFrame sensorXingFrame = null; 11428 11429 private String[] xingSensorBlocks = new String[4]; 11430 11431 BeanDetails<Sensor> xingSensorA; 11432 BeanDetails<Sensor> xingSensorB; 11433 BeanDetails<Sensor> xingSensorC; 11434 BeanDetails<Sensor> xingSensorD; 11435 11436 JPanel sensorXingPanel = new JPanel(new FlowLayout()); 11437 11438 //display dialog for Set Signals at Level Crossing tool 11439 public void setSensorsAtLevelXingFromMenu(@Nonnull LevelXing xing, 11440 @Nonnull String[] blocks, 11441 @Nonnull MultiIconEditor theEditor, 11442 @Nonnull JFrame theFrame) { 11443 levelXing = xing; 11444 BlockManager bm = InstanceManager.getDefault(BlockManager.class); 11445 xingSensorsBlockACComboBox.setSelectedItem(bm.getBlock(levelXing.getBlockNameAC())); 11446 xingSensorsBlockBDComboBox.setSelectedItem(bm.getBlock(levelXing.getBlockNameBD())); 11447 for (int i = 0; i < blocks.length; i++) { 11448 xingSensorBlocks[i] = blocks[i]; 11449 } 11450 setSensorsAtLevelXingFromMenuFlag = true; 11451 setSensorsAtLevelXing(theEditor, theFrame); 11452 setSensorsAtLevelXingFromMenuFlag = false; 11453 } 11454 11455 //TODO: Add to Tools menu? 11456 public void setSensorsAtLevelXing(@Nonnull MultiIconEditor theEditor, 11457 @Nonnull JFrame theFrame) { 11458 sensorIconEditor = theEditor; 11459 sensorXingFrame = theFrame; 11460 11461 //Initialize if needed 11462 if (setSensorsAtLevelXingFrame == null) { 11463 setSensorsAtLevelXingOpenFlag = false; 11464 11465 xingSensorA = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11466 xingSensorB = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11467 xingSensorC = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11468 xingSensorD = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11469 11470 xingSensorA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 11471 xingSensorB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 11472 xingSensorC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 11473 xingSensorD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 11474 11475 setSensorsAtLevelXingFrame = new JmriJFrame(Bundle.getMessage("SensorsAtLevelXing"), false, true); 11476 oneFrameToRuleThemAll(setSensorsAtLevelXingFrame); 11477 setSensorsAtLevelXingFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 11478// setSensorsAtLevelXingFrame.addHelpMenu("package.jmri.jmrit.display.SetSensorsAtLevelXing", true); 11479 setSensorsAtLevelXingFrame.setLocation(70, 30); 11480 Container theContentPane = setSensorsAtLevelXingFrame.getContentPane(); 11481 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 11482 11483 JPanel panel11 = new JPanel(new FlowLayout()); 11484 11485 xingSensorsBlockACNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 11486 Bundle.getMessage("BeanNameBlock") + " AC " 11487 + Bundle.getMessage("Name"))); 11488 panel11.add(xingSensorsBlockACNameLabel); 11489 panel11.add(xingSensorsBlockACComboBox); 11490 xingSensorsBlockACComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 11491 theContentPane.add(panel11); 11492 11493 JPanel panel12 = new JPanel(new FlowLayout()); 11494 xingSensorsBlockBDNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 11495 Bundle.getMessage("BeanNameBlock") + " BD " 11496 + Bundle.getMessage("Name"))); 11497 panel12.add(xingSensorsBlockBDNameLabel); 11498 panel12.add(xingSensorsBlockBDComboBox); 11499 xingSensorsBlockBDComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 11500 theContentPane.add(panel12); 11501 11502 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 11503 11504 JPanel panel2 = new JPanel(new FlowLayout()); 11505 JLabel shTitle = new JLabel(Bundle.getMessage("BeanNameSensor")); 11506 panel2.add(shTitle); 11507 panel2.add(new JLabel(" ")); 11508 panel2.add(getSavedXingSensors = new JButton(Bundle.getMessage("GetSaved"))); 11509 getSavedXingSensors.addActionListener(this::xingSensorsGetSaved); 11510 getSavedXingSensors.setToolTipText(Bundle.getMessage("GetSavedHint")); 11511 theContentPane.add(panel2); 11512 11513 sensorXingPanel.setLayout(new GridLayout(0, 2)); 11514 theContentPane.add(sensorXingPanel); 11515 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 11516 11517 JPanel panel6 = new JPanel(new FlowLayout()); 11518 panel6.add(changeSensorXingIcon = new JButton(Bundle.getMessage("ChangeSensorIcon"))); 11519 changeSensorXingIcon.addActionListener((ActionEvent e) -> sensorXingFrame.setVisible(true)); 11520 changeSensorXingIcon.setToolTipText(Bundle.getMessage("ChangeSensorIconHint")); 11521 11522 panel6.add(new JLabel(" ")); 11523 panel6.add(setXingSensorsDone = new JButton(Bundle.getMessage("ButtonDone"))); 11524 setXingSensorsDone.addActionListener(this::setXingSensorsDonePressed); 11525 setXingSensorsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 11526 panel6.add(setXingSensorsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 11527 setXingSensorsCancel.addActionListener(this::setXingSensorsCancelPressed); 11528 setXingSensorsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 11529 theContentPane.add(panel6); 11530 setSensorsAtLevelXingFrame.addWindowListener(new WindowAdapter() { 11531 @Override 11532 public void windowClosing(WindowEvent e) { 11533 setXingSensorsCancelPressed(null); 11534 } 11535 }); 11536 } 11537 11538 sensorXingPanel.removeAll(); 11539 11540 xingSensorsBlockACComboBox.setVisible(!setSensorsAtLevelXingFromMenuFlag); 11541 xingSensorsBlockBDComboBox.setVisible(!setSensorsAtLevelXingFromMenuFlag); 11542 11543 if (setSensorsAtLevelXingFromMenuFlag) { 11544 xingSensorsBlockACNameLabel.setText(Bundle.getMessage("MakeLabel", 11545 Bundle.getMessage("BeanNameBlock") + " AC " 11546 + Bundle.getMessage("Name")) + " " + levelXing.getBlockNameAC()); 11547 xingSensorsBlockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 11548 Bundle.getMessage("BeanNameBlock") + " BD " 11549 + Bundle.getMessage("Name")) + " " + levelXing.getBlockNameBD()); 11550 11551 xingSensorA.setTextField(levelXing.getSensorAName()); 11552 xingSensorB.setTextField(levelXing.getSensorBName()); 11553 xingSensorC.setTextField(levelXing.getSensorCName()); 11554 xingSensorD.setTextField(levelXing.getSensorDName()); 11555 xingSensorsGetSaved(null); 11556 } else { 11557 xingSensorsBlockACNameLabel.setText(Bundle.getMessage("MakeLabel", 11558 Bundle.getMessage("BeanNameBlock") + " AC " 11559 + Bundle.getMessage("Name"))); 11560 xingSensorsBlockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 11561 Bundle.getMessage("BeanNameBlock") + " BD " 11562 + Bundle.getMessage("Name"))); 11563 } 11564 11565 if (!setSensorsAtLevelXingOpenFlag) { 11566 setSensorsAtLevelXingFrame.setPreferredSize(null); 11567 setSensorsAtLevelXingFrame.pack(); 11568 setSensorsAtLevelXingOpenFlag = true; 11569 } 11570 setSensorsAtLevelXingFrame.setVisible(true); 11571 } 11572 11573 private void xingSensorsGetSaved(ActionEvent a) { 11574 if (!getLevelCrossingSensorInformation()) { 11575 return; 11576 } 11577 11578 xingSensorBlocks = levelXing.getBlockBoundaries(); 11579 11580 xingSensorA.setTextField(levelXing.getSensorAName()); 11581 xingSensorB.setTextField(levelXing.getSensorBName()); 11582 xingSensorC.setTextField(levelXing.getSensorCName()); 11583 xingSensorD.setTextField(levelXing.getSensorDName()); 11584 11585 sensorXingPanel.remove(xingSensorA.getDetailsPanel()); 11586 sensorXingPanel.remove(xingSensorB.getDetailsPanel()); 11587 sensorXingPanel.remove(xingSensorC.getDetailsPanel()); 11588 sensorXingPanel.remove(xingSensorD.getDetailsPanel()); 11589 11590 xingSensorA.setBoundaryLabel(xingSensorBlocks[0]); 11591 xingSensorB.setBoundaryLabel(xingSensorBlocks[1]); 11592 xingSensorC.setBoundaryLabel(xingSensorBlocks[2]); 11593 xingSensorD.setBoundaryLabel(xingSensorBlocks[3]); 11594 11595 boolean boundaryFlag = false; 11596 if (xingSensorBlocks[0] != null) { 11597 sensorXingPanel.add(xingSensorA.getDetailsPanel()); 11598 boundaryFlag = true; 11599 } 11600 if (xingSensorBlocks[1] != null) { 11601 sensorXingPanel.add(xingSensorB.getDetailsPanel()); 11602 boundaryFlag = true; 11603 } 11604 if (xingSensorBlocks[2] != null) { 11605 sensorXingPanel.add(xingSensorC.getDetailsPanel()); 11606 boundaryFlag = true; 11607 } 11608 if (xingSensorBlocks[3] != null) { 11609 sensorXingPanel.add(xingSensorD.getDetailsPanel()); 11610 boundaryFlag = true; 11611 } 11612 if (!boundaryFlag) { 11613 JmriJOptionPane.showMessageDialog(setSensorsAtLevelXingFrame, Bundle.getMessage("NoBoundaryXingSensor")); 11614 } 11615 setSensorsAtLevelXingFrame.setPreferredSize(null); 11616 setSensorsAtLevelXingFrame.pack(); 11617 } 11618 11619 private boolean getLevelCrossingSensorInformation() { 11620 if (!setSensorsAtLevelXingFromMenuFlag) { 11621 levelXing = null; 11622 List<LevelXing> levelXings = layoutEditor.getLevelXings(); 11623 if (levelXings.size() <= 0) { 11624 JmriJOptionPane.showMessageDialog(setSensorsAtLevelXingFrame, 11625 Bundle.getMessage("SignalsError15"), 11626 Bundle.getMessage("ErrorTitle"), 11627 JmriJOptionPane.ERROR_MESSAGE); 11628 return false; 11629 } else if (levelXings.size() == 1) { 11630 levelXing = levelXings.get(0); 11631 } else { 11632 LayoutBlock xingSensorBlockA = null; 11633 LayoutBlock xingSensorBlockC = null; 11634 xingSensorBlockA = getBlockFromEntry(xingSensorsBlockACComboBox); 11635 if (xingSensorBlockA == null) { 11636 return false; 11637 } 11638 String theBlockName = xingSensorsBlockBDComboBox.getSelectedItemDisplayName(); 11639 if ((theBlockName != null) && !theBlockName.isEmpty()) { 11640 xingSensorBlockC = getBlockFromEntry(xingSensorsBlockBDComboBox); 11641 if (xingSensorBlockC == null) { 11642 return false; 11643 } 11644 } 11645 11646 int foundCount = 0; 11647 //make two block tests first 11648 if (xingSensorBlockC != null) { 11649 for (LevelXing x : layoutEditor.getLevelXings()) { 11650 LayoutBlock xA = null; 11651 LayoutBlock xB = null; 11652 LayoutBlock xC = null; 11653 LayoutBlock xD = null; 11654 LayoutBlock xAC = x.getLayoutBlockAC(); 11655 LayoutBlock xBD = x.getLayoutBlockBD(); 11656 if (x.getConnectA() != null) { 11657 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 11658 } 11659 if (x.getConnectB() != null) { 11660 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 11661 } 11662 if (x.getConnectC() != null) { 11663 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 11664 } 11665 if (x.getConnectD() != null) { 11666 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 11667 } 11668 if (((xA != null) && (xC != null) && (((xA == xingSensorBlockA) && (xC == xingSensorBlockC)) 11669 || ((xA == xingSensorBlockC) && (xC == xingSensorBlockA)))) 11670 || ((xB != null) && (xD != null) && (((xB == xingSensorBlockA) && (xD == xingSensorBlockC)) 11671 || ((xB == xingSensorBlockC) && (xD == xingSensorBlockA))))) { 11672 levelXing = x; 11673 foundCount++; 11674 } else if ((xAC != null) && (xBD != null) && (((xAC == xingSensorBlockA) && (xBD == xingSensorBlockC)) 11675 || ((xAC == xingSensorBlockC) && (xBD == xingSensorBlockA)))) { 11676 levelXing = x; 11677 foundCount++; 11678 } 11679 } 11680 } 11681 if (foundCount == 0) { 11682 //try one block test 11683 for (LevelXing x : layoutEditor.getLevelXings()) { 11684 if ((xingSensorBlockA == x.getLayoutBlockAC()) || (xingSensorBlockA == x.getLayoutBlockBD())) { 11685 levelXing = x; 11686 foundCount++; 11687 } 11688 } 11689 } 11690 if (foundCount > 1) { 11691 JmriJOptionPane.showMessageDialog(setSensorsAtLevelXingFrame, 11692 Bundle.getMessage("SignalsError16", 11693 new Object[]{" " + foundCount + " "}), 11694 Bundle.getMessage("ErrorTitle"), 11695 JmriJOptionPane.ERROR_MESSAGE); 11696 return false; 11697 } 11698 if (levelXing == null) { 11699 JmriJOptionPane.showMessageDialog(setSensorsAtLevelXingFrame, 11700 Bundle.getMessage("SignalsError17"), 11701 Bundle.getMessage("ErrorTitle"), 11702 JmriJOptionPane.ERROR_MESSAGE); 11703 return false; 11704 } 11705 } 11706 } 11707 return true; 11708 } 11709 11710 private void setXingSensorsCancelPressed(ActionEvent a) { 11711 setSensorsAtLevelXingOpenFlag = false; 11712 setSensorsAtLevelXingFrame.setVisible(false); 11713 } 11714 11715 private void setXingSensorsDonePressed(ActionEvent a) { 11716 log.trace("setXingSensorsDonePressed"); // NOI18N 11717 11718 if (!getLevelCrossingSensorInformation()) { 11719 return; 11720 } 11721 11722 Sensor aSensor = getSensorFromEntry(xingSensorA.getText(), false, setSensorsAtLevelXingFrame); 11723 Sensor bSensor = getSensorFromEntry(xingSensorB.getText(), false, setSensorsAtLevelXingFrame); 11724 Sensor cSensor = getSensorFromEntry(xingSensorC.getText(), false, setSensorsAtLevelXingFrame); 11725 Sensor dSensor = getSensorFromEntry(xingSensorD.getText(), false, setSensorsAtLevelXingFrame); 11726 11727 Sensor currSensorA = levelXing.getSensorA(); 11728 Sensor currSensorB = levelXing.getSensorB(); 11729 Sensor currSensorC = levelXing.getSensorC(); 11730 Sensor currSensorD = levelXing.getSensorD(); 11731 11732 if (log.isTraceEnabled()) { 11733 log.trace("current sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 11734 (currSensorA == null) ? "- none- " : currSensorA.getDisplayName(), // NOI18N 11735 (currSensorB == null) ? "- none- " : currSensorB.getDisplayName(), // NOI18N 11736 (currSensorC == null) ? "- none- " : currSensorC.getDisplayName(), // NOI18N 11737 (currSensorD == null) ? "- none- " : currSensorD.getDisplayName()); // NOI18N 11738 log.trace("new sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 11739 (aSensor == null) ? "- none- " : aSensor.getDisplayName(), // NOI18N 11740 (bSensor == null) ? "- none- " : bSensor.getDisplayName(), // NOI18N 11741 (cSensor == null) ? "- none- " : cSensor.getDisplayName(), // NOI18N 11742 (dSensor == null) ? "- none- " : dSensor.getDisplayName()); // NOI18N 11743 } 11744 11745 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 11746 // place/remove sensors as requested 11747 if (aSensor == null) { 11748 if (currSensorA != null && removeSensorFromPanel(currSensorA)) { 11749 levelXing.setSensorAName(null); 11750 } 11751 } else if (xingSensorA != null && levelXing.getConnectA() != null) { 11752 setLevelXingSensor(aSensor, currSensorA, xingSensorA, levelXing.getConnectA(), levelXingView.getCoordsA(), "A"); 11753 } 11754 11755 if (bSensor == null) { 11756 if (currSensorB != null && removeSensorFromPanel(currSensorB)) { 11757 levelXing.setSensorBName(null); 11758 } 11759 } else if (xingSensorB != null && levelXing.getConnectB() != null) { 11760 setLevelXingSensor(bSensor, currSensorB, xingSensorB, levelXing.getConnectB(), levelXingView.getCoordsB(), "B"); 11761 } 11762 11763 if (cSensor == null) { 11764 if (currSensorC != null && removeSensorFromPanel(currSensorC)) { 11765 levelXing.setSensorCName(null); 11766 } 11767 } else if (xingSensorC != null && levelXing.getConnectC() != null) { 11768 setLevelXingSensor(cSensor, currSensorC, xingSensorC, levelXing.getConnectC(), levelXingView.getCoordsC(), "C"); 11769 } 11770 11771 if (dSensor == null) { 11772 if (currSensorD != null && removeSensorFromPanel(currSensorD)) { 11773 levelXing.setSensorDName(null); 11774 } 11775 } else if (xingSensorD != null && levelXing.getConnectD() != null) { 11776 setLevelXingSensor(dSensor, currSensorD, xingSensorD, levelXing.getConnectD(), levelXingView.getCoordsD(), "D"); 11777 } 11778 11779 //setup logic if requested 11780 //finish up 11781 setSensorsAtLevelXingOpenFlag = false; 11782 setSensorsAtLevelXingFrame.setVisible(false); 11783 if (needRedraw) { 11784 layoutEditor.redrawPanel(); 11785 needRedraw = false; 11786 layoutEditor.setDirty(); 11787 } 11788 } 11789 11790 /** 11791 * Attached a sensor to a level crossing block boundary. 11792 * 11793 * @since 4.11.2 11794 * @param newSensor The sensor that is being added. 11795 * @param currSensor The sensor that might already be there, otherwise null. 11796 * @param beanDetail The BeanDetails object that contains the supporting 11797 * data. 11798 * @param connect The track segment that is attached to this point 11799 * @param coords The track componennt coordinates 11800 * @param position Which of the four points is being changed 11801 */ 11802 void setLevelXingSensor(Sensor newSensor, Sensor currSensor, BeanDetails<? extends NamedBean> beanDetail, 11803 LayoutTrack connect, Point2D coords, String position) { 11804 if (currSensor == null) { 11805 if (!isSensorAssignedAnywhere(newSensor)) { 11806 log.trace("Add sensor '{}'", newSensor.getDisplayName()); // NOI18N 11807 switch (position) { 11808 case "A": // NOI18N 11809 levelXing.setSensorAName(beanDetail.getText()); 11810 break; 11811 case "B": // NOI18N 11812 levelXing.setSensorBName(beanDetail.getText()); 11813 break; 11814 case "C": // NOI18N 11815 levelXing.setSensorCName(beanDetail.getText()); 11816 break; 11817 case "D": // NOI18N 11818 levelXing.setSensorDName(beanDetail.getText()); 11819 break; 11820 default: 11821 break; 11822 } 11823 if (beanDetail.addToPanel()) { 11824 log.trace("Add icon for sensor '{}'", newSensor.getDisplayName()); // NOI18N 11825 placingBlock(getSensorIcon(beanDetail.getText()), 11826 beanDetail.isRightSelected(), 0.0, connect, coords); 11827 needRedraw = true; 11828 } 11829 } else { 11830 sensorAssignedElseWhere(newSensor); 11831 } 11832 } else if (currSensor == newSensor) { 11833 if (beanDetail.addToPanel()) { 11834 if (!isSensorOnPanel(newSensor)) { 11835 log.trace("Add icon for existing sensor '{}'", newSensor.getDisplayName()); // NOI18N 11836 placingBlock(getSensorIcon(beanDetail.getText()), 11837 beanDetail.isRightSelected(), 0.0, connect, coords); 11838 needRedraw = true; 11839 } 11840 } 11841 } else { 11842 if (!isSensorAssignedAnywhere(newSensor)) { 11843 if (removeSensorFromPanel(currSensor)) { 11844 log.trace("Replace sensor '{}' with sensor '{}'", // NOI18N 11845 currSensor.getDisplayName(), newSensor.getDisplayName()); 11846 switch (position) { 11847 case "A": // NOI18N 11848 levelXing.setSensorAName(beanDetail.getText()); 11849 break; 11850 case "B": // NOI18N 11851 levelXing.setSensorBName(beanDetail.getText()); 11852 break; 11853 case "C": // NOI18N 11854 levelXing.setSensorCName(beanDetail.getText()); 11855 break; 11856 case "D": // NOI18N 11857 levelXing.setSensorDName(beanDetail.getText()); 11858 break; 11859 default: 11860 break; 11861 } 11862 if (beanDetail.addToPanel()) { 11863 log.trace("Add icon for replacement sensor '{}'", // NOI18N 11864 newSensor.getDisplayName()); 11865 placingBlock(getSensorIcon(beanDetail.getText()), 11866 beanDetail.isRightSelected(), 0.0, connect, coords); 11867 needRedraw = true; 11868 } 11869 } 11870 } else { 11871 sensorAssignedElseWhere(newSensor); 11872 } 11873 } 11874 } 11875 11876 private boolean getSimpleBlockInformation() { 11877 //might have to do something to trick it with an end bumper 11878 if (!setSignalMastsAtBlockBoundaryFromMenuFlag) { 11879 block1 = getBlockFromEntry(block1IDComboBox); 11880 if (block1 == null) { 11881 return false; 11882 } 11883 block2 = getBlockFromEntry(block2IDComboBox); 11884 boundary = null; 11885 //if block2 is undefined or same as block 1 11886 if (block2 == null || (block1 == block2)) { 11887 //find the 1st positionablePoint that's connect1'ed to block1 11888 for (PositionablePoint p : layoutEditor.getPositionablePoints()) { 11889 if (p.getType() == PositionablePoint.PointType.END_BUMPER) { 11890 if (p.getConnect1() != null && p.getConnect1().getLayoutBlock() == block1) { 11891 boundary = p; 11892 break; 11893 } 11894 } 11895 } 11896 } 11897 11898 //now we try to find an anchor that connected to blocks 1 and 2 11899 //(if this fails boundary will still be set to the pp set if 11900 //block2 was null or equal to block1 above.) 11901 for (PositionablePoint p : layoutEditor.getPositionablePoints()) { 11902 if (p.getType() != PositionablePoint.PointType.END_BUMPER) { 11903 LayoutBlock bA = null; 11904 LayoutBlock bB = null; 11905 if (p.getConnect1() != null) { 11906 bA = p.getConnect1().getLayoutBlock(); 11907 } 11908 if (p.getConnect2() != null) { 11909 bB = p.getConnect2().getLayoutBlock(); 11910 } 11911 if ((bA != null) && (bB != null) && (bA != bB)) { 11912 if (((bA == block1) && (bB == block2)) 11913 || ((bA == block2) && (bB == block1))) { 11914 boundary = p; 11915 break; 11916 } 11917 } 11918 } 11919 } 11920 //if all that failed... 11921 if (boundary == null) { 11922 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 11923 Bundle.getMessage("SignalsError7"), 11924 Bundle.getMessage("ErrorTitle"), 11925 JmriJOptionPane.ERROR_MESSAGE); 11926 return false; 11927 } 11928 } 11929 return true; 11930 } 11931 11932 /*==================*\ 11933 |* setSensorsAtSlip *| 11934 \*==================*/ 11935 //operational variables for Set Sensors at Slip tool 11936 private JmriJFrame setSensorsAtSlipFrame = null; 11937 private boolean setSensorsAtSlipOpenFlag = false; 11938 private boolean setSensorsAtSlipFromMenuFlag = false; 11939 11940 private JButton getSavedSlipSensors = null; 11941 private JButton setSlipSensorsDone = null; 11942 private JButton setSlipSensorsCancel = null; 11943 private JButton changeSensorSlipIcon = null; 11944 JFrame sensorSlipFrame = null; 11945 11946 private final NamedBeanComboBox<Block> slipSensorsBlockAComboBox 11947 = new NamedBeanComboBox<>( 11948 InstanceManager.getDefault(BlockManager.class), 11949 null, DisplayOptions.DISPLAYNAME); 11950 private final NamedBeanComboBox<Block> slipSensorsBlockBComboBox 11951 = new NamedBeanComboBox<>( 11952 InstanceManager.getDefault(BlockManager.class), 11953 null, DisplayOptions.DISPLAYNAME); 11954 private final NamedBeanComboBox<Block> slipSensorsBlockCComboBox 11955 = new NamedBeanComboBox<>( 11956 InstanceManager.getDefault(BlockManager.class), 11957 null, DisplayOptions.DISPLAYNAME); 11958 private final NamedBeanComboBox<Block> slipSensorsBlockDComboBox 11959 = new NamedBeanComboBox<>( 11960 InstanceManager.getDefault(BlockManager.class), 11961 null, DisplayOptions.DISPLAYNAME); 11962 11963 private String[] slipSensorBlocks = new String[4]; 11964 11965 BeanDetails<Sensor> slipSensorA; 11966 BeanDetails<Sensor> slipSensorB; 11967 BeanDetails<Sensor> slipSensorC; 11968 BeanDetails<Sensor> slipSensorD; 11969 11970 JPanel sensorSlipPanel = new JPanel(new FlowLayout()); 11971 11972 //display dialog for Set Signals at Level Crossing tool 11973 public void setSensorsAtSlipFromMenu(@Nonnull LayoutSlip slip, 11974 @Nonnull String[] blocks, 11975 @Nonnull MultiIconEditor theEditor, 11976 @Nonnull JFrame theFrame) { 11977 layoutSlip = slip; 11978 BlockManager bm = InstanceManager.getDefault(BlockManager.class); 11979 slipSensorsBlockAComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockName())); 11980 slipSensorsBlockBComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockBName())); 11981 slipSensorsBlockCComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockCName())); 11982 slipSensorsBlockDComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockDName())); 11983 for (int i = 0; i < blocks.length; i++) { 11984 slipSensorBlocks[i] = blocks[i]; 11985 } 11986 setSensorsAtSlipFromMenuFlag = true; 11987 setSensorsAtSlip(theEditor, theFrame); 11988 setSensorsAtSlipFromMenuFlag = false; 11989 } 11990 11991 //TODO: Add to Tools menu? 11992 public void setSensorsAtSlip(@Nonnull MultiIconEditor theEditor, 11993 @Nonnull JFrame theFrame) { 11994 sensorIconEditor = theEditor; 11995 sensorSlipFrame = theFrame; 11996 11997 //Initialize if needed 11998 if (setSensorsAtSlipFrame == null) { 11999 setSensorsAtSlipOpenFlag = false; 12000 12001 slipSensorA = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 12002 slipSensorB = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 12003 slipSensorC = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 12004 slipSensorD = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 12005 12006 slipSensorA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 12007 slipSensorB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 12008 slipSensorC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 12009 slipSensorD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 12010 12011 setSensorsAtSlipFrame = new JmriJFrame(Bundle.getMessage("SensorsAtSlip"), false, true); 12012 oneFrameToRuleThemAll(setSensorsAtSlipFrame); 12013 setSensorsAtSlipFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 12014// setSensorsAtSlipFrame.addHelpMenu("package.jmri.jmrit.display.SetSensorsAtLevelSlip", true); 12015 setSensorsAtSlipFrame.setLocation(70, 30); 12016 Container theContentPane = setSensorsAtSlipFrame.getContentPane(); 12017 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 12018 12019 JPanel panel11A = new JPanel(new FlowLayout()); 12020 slipSignalBlockANameLabel = new JLabel(Bundle.getMessage("MakeLabel", 12021 Bundle.getMessage("BeanNameBlock") + " A " 12022 + Bundle.getMessage("Name"))); 12023 panel11A.add(slipSignalBlockANameLabel); 12024 panel11A.add(slipSensorsBlockAComboBox); 12025 slipSensorsBlockAComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 12026 theContentPane.add(panel11A); 12027 12028 JPanel panel11B = new JPanel(new FlowLayout()); 12029 slipSignalBlockBNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 12030 Bundle.getMessage("BeanNameBlock") + " B " 12031 + Bundle.getMessage("Name"))); 12032 panel11B.add(slipSignalBlockBNameLabel); 12033 panel11B.add(slipSensorsBlockBComboBox); 12034 slipSensorsBlockBComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 12035 theContentPane.add(panel11B); 12036 12037 JPanel panel11C = new JPanel(new FlowLayout()); 12038 slipSignalBlockCNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 12039 Bundle.getMessage("BeanNameBlock") + " C " 12040 + Bundle.getMessage("Name"))); 12041 panel11C.add(slipSignalBlockCNameLabel); 12042 panel11C.add(slipSensorsBlockCComboBox); 12043 slipSensorsBlockCComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 12044 theContentPane.add(panel11C); 12045 12046 JPanel panel11D = new JPanel(new FlowLayout()); 12047 slipSignalBlockDNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 12048 Bundle.getMessage("BeanNameBlock") + " D " 12049 + Bundle.getMessage("Name"))); 12050 panel11D.add(slipSignalBlockDNameLabel); 12051 panel11D.add(slipSensorsBlockDComboBox); 12052 slipSensorsBlockDComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 12053 theContentPane.add(panel11D); 12054 12055 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12056 12057 JPanel panel2 = new JPanel(new FlowLayout()); 12058 JLabel shTitle = new JLabel(Bundle.getMessage("BeanNameSensor")); 12059 panel2.add(shTitle); 12060 panel2.add(new JLabel(" ")); 12061 panel2.add(getSavedSlipSensors = new JButton(Bundle.getMessage("GetSaved"))); 12062 getSavedSlipSensors.addActionListener(this::slipSensorsGetSaved); 12063 getSavedSlipSensors.setToolTipText(Bundle.getMessage("GetSavedHint")); 12064 theContentPane.add(panel2); 12065 12066 sensorSlipPanel.setLayout(new GridLayout(0, 2)); 12067 theContentPane.add(sensorSlipPanel); 12068 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12069 12070 JPanel panel6 = new JPanel(new FlowLayout()); 12071 panel6.add(changeSensorSlipIcon = new JButton(Bundle.getMessage("ChangeSensorIcon"))); 12072 changeSensorSlipIcon.addActionListener((ActionEvent e) -> sensorSlipFrame.setVisible(true)); 12073 changeSensorSlipIcon.setToolTipText(Bundle.getMessage("ChangeSensorIconHint")); 12074 12075 panel6.add(new JLabel(" ")); 12076 panel6.add(setSlipSensorsDone = new JButton(Bundle.getMessage("ButtonDone"))); 12077 setSlipSensorsDone.addActionListener(this::setSlipSensorsDonePressed); 12078 setSlipSensorsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 12079 panel6.add(setSlipSensorsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 12080 setSlipSensorsCancel.addActionListener(this::setSlipSensorsCancelPressed); 12081 setSlipSensorsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 12082 theContentPane.add(panel6); 12083 setSensorsAtSlipFrame.addWindowListener(new WindowAdapter() { 12084 @Override 12085 public void windowClosing(WindowEvent e) { 12086 setSlipSensorsCancelPressed(null); 12087 } 12088 }); 12089 } //if (setSensorsAtSlipFrame == null) 12090 12091 sensorSlipPanel.removeAll(); 12092 12093 slipSensorsBlockAComboBox.setVisible(!setSensorsAtSlipFromMenuFlag); 12094 slipSensorsBlockBComboBox.setVisible(!setSensorsAtSlipFromMenuFlag); 12095 slipSensorsBlockCComboBox.setVisible(!setSensorsAtSlipFromMenuFlag); 12096 slipSensorsBlockDComboBox.setVisible(!setSensorsAtSlipFromMenuFlag); 12097 12098 if (setSensorsAtSlipFromMenuFlag) { 12099 slipSignalBlockANameLabel.setText(Bundle.getMessage("MakeLabel", 12100 Bundle.getMessage("BeanNameBlock") + " A " 12101 + Bundle.getMessage("Name")) + " " + layoutSlip.getBlockName()); 12102 slipSignalBlockBNameLabel.setText(Bundle.getMessage("MakeLabel", 12103 Bundle.getMessage("BeanNameBlock") + " B " 12104 + Bundle.getMessage("Name")) + " " + layoutSlip.getBlockBName()); 12105 slipSignalBlockCNameLabel.setText(Bundle.getMessage("MakeLabel", 12106 Bundle.getMessage("BeanNameBlock") + " C " 12107 + Bundle.getMessage("Name")) + " " + layoutSlip.getBlockCName()); 12108 slipSignalBlockDNameLabel.setText(Bundle.getMessage("MakeLabel", 12109 Bundle.getMessage("BeanNameBlock") + " D " 12110 + Bundle.getMessage("Name")) + " " + layoutSlip.getBlockDName()); 12111 slipSensorsGetSaved(null); 12112 } else { 12113 slipSignalBlockANameLabel.setText(Bundle.getMessage("MakeLabel", 12114 Bundle.getMessage("BeanNameBlock") + " A " 12115 + Bundle.getMessage("Name"))); 12116 slipSignalBlockBNameLabel.setText(Bundle.getMessage("MakeLabel", 12117 Bundle.getMessage("BeanNameBlock") + " B " 12118 + Bundle.getMessage("Name"))); 12119 slipSignalBlockCNameLabel.setText(Bundle.getMessage("MakeLabel", 12120 Bundle.getMessage("BeanNameBlock") + " C " 12121 + Bundle.getMessage("Name"))); 12122 slipSignalBlockDNameLabel.setText(Bundle.getMessage("MakeLabel", 12123 Bundle.getMessage("BeanNameBlock") + " D " 12124 + Bundle.getMessage("Name"))); 12125 } 12126 12127 if (setSensorsAtSlipOpenFlag) { 12128 slipSensorsGetSaved(null); 12129 } else { 12130 setSensorsAtSlipFrame.setPreferredSize(null); 12131 setSensorsAtSlipFrame.setVisible(true); 12132 setSensorsAtSlipOpenFlag = true; 12133 } 12134 setSensorsAtSlipFrame.setPreferredSize(null); 12135 setSensorsAtSlipFrame.pack(); 12136 } 12137 12138 private void slipSensorsGetSaved(ActionEvent a) { 12139 if (!getSlipSensorInformation()) { 12140 return; 12141 } 12142 12143 slipSensorBlocks = layoutSlip.getBlockBoundaries(); 12144 12145 slipSensorA.setTextField(layoutSlip.getSensorAName()); 12146 slipSensorB.setTextField(layoutSlip.getSensorBName()); 12147 slipSensorC.setTextField(layoutSlip.getSensorCName()); 12148 slipSensorD.setTextField(layoutSlip.getSensorDName()); 12149 12150 sensorSlipPanel.remove(slipSensorA.getDetailsPanel()); 12151 sensorSlipPanel.remove(slipSensorB.getDetailsPanel()); 12152 sensorSlipPanel.remove(slipSensorC.getDetailsPanel()); 12153 sensorSlipPanel.remove(slipSensorD.getDetailsPanel()); 12154 12155 slipSensorA.setBoundaryLabel(slipSensorBlocks[0]); 12156 slipSensorB.setBoundaryLabel(slipSensorBlocks[1]); 12157 slipSensorC.setBoundaryLabel(slipSensorBlocks[2]); 12158 slipSensorD.setBoundaryLabel(slipSensorBlocks[3]); 12159 12160 boolean boundaryFlag = false; 12161 if (slipSensorBlocks[0] != null) { 12162 sensorSlipPanel.add(slipSensorA.getDetailsPanel()); 12163 boundaryFlag = true; 12164 } 12165 if (slipSensorBlocks[1] != null) { 12166 sensorSlipPanel.add(slipSensorB.getDetailsPanel()); 12167 boundaryFlag = true; 12168 } 12169 if (slipSensorBlocks[2] != null) { 12170 sensorSlipPanel.add(slipSensorC.getDetailsPanel()); 12171 boundaryFlag = true; 12172 } 12173 if (slipSensorBlocks[3] != null) { 12174 sensorSlipPanel.add(slipSensorD.getDetailsPanel()); 12175 boundaryFlag = true; 12176 } 12177 if (!boundaryFlag) { 12178 JmriJOptionPane.showMessageDialog(setSensorsAtSlipFrame, Bundle.getMessage("NoBoundarySlipSensor")); 12179 } 12180 setSensorsAtSlipFrame.setPreferredSize(null); 12181 setSensorsAtSlipFrame.pack(); 12182 } 12183 12184 private boolean getSlipSensorInformation() { 12185 if (!setSensorsAtSlipFromMenuFlag) { 12186 layoutSlip = null; 12187 List<LayoutSlip> layoutSlips = layoutEditor.getLayoutSlips(); 12188 if (layoutSlips.size() <= 0) { 12189 JmriJOptionPane.showMessageDialog(setSensorsAtSlipFrame, 12190 Bundle.getMessage("SignalsError15"), 12191 Bundle.getMessage("ErrorTitle"), 12192 JmriJOptionPane.ERROR_MESSAGE); 12193 return false; 12194 } else if (layoutSlips.size() == 1) { 12195 layoutSlip = layoutSlips.get(0); 12196 } else { 12197 LayoutBlock slipSensorBlockA = null; 12198 slipSensorBlockA = getBlockFromEntry(slipSensorsBlockAComboBox); 12199 if (slipSensorBlockA == null) { 12200 return false; 12201 } 12202 12203 int foundCount = 0; 12204 for (LayoutSlip x : layoutEditor.getLayoutSlips()) { 12205 LayoutBlock xA = null; 12206 LayoutBlock xB = null; 12207 LayoutBlock xC = null; 12208 LayoutBlock xD = null; 12209 12210 LayoutBlock xAC = x.getLayoutBlock(); 12211 if (x.getConnectA() != null) { 12212 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 12213 } 12214 if (x.getConnectB() != null) { 12215 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 12216 } 12217 if (x.getConnectC() != null) { 12218 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 12219 } 12220 if (x.getConnectD() != null) { 12221 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 12222 } 12223 if (((xA != null) && (xC != null) && ((xA == slipSensorBlockA) 12224 || (xC == slipSensorBlockA))) 12225 || ((xB != null) && (xD != null) && (((xB == slipSensorBlockA)) 12226 || ((xD == slipSensorBlockA))))) { 12227 layoutSlip = x; 12228 foundCount++; 12229 } else if ((xAC != null) && (xAC == slipSensorBlockA)) { 12230 layoutSlip = x; 12231 foundCount++; 12232 } 12233 } 12234 if (foundCount == 0) { 12235 //try one block test 12236 for (LayoutSlip x : layoutEditor.getLayoutSlips()) { 12237 if (slipSensorBlockA == x.getLayoutBlock()) { 12238 layoutSlip = x; 12239 foundCount++; 12240 } 12241 } 12242 } 12243 if (foundCount > 1) { 12244 JmriJOptionPane.showMessageDialog(setSensorsAtSlipFrame, 12245 Bundle.getMessage("SignalsError16", 12246 new Object[]{" " + foundCount + " "}), 12247 Bundle.getMessage("ErrorTitle"), 12248 JmriJOptionPane.ERROR_MESSAGE); 12249 return false; 12250 } 12251 if (layoutSlip == null) { 12252 JmriJOptionPane.showMessageDialog(setSensorsAtSlipFrame, 12253 Bundle.getMessage("SignalsError17"), 12254 Bundle.getMessage("ErrorTitle"), 12255 JmriJOptionPane.ERROR_MESSAGE); 12256 return false; 12257 } 12258 } 12259 } 12260 return true; 12261 } 12262 12263 private void setSlipSensorsCancelPressed(ActionEvent a) { 12264 setSensorsAtSlipOpenFlag = false; 12265 setSensorsAtSlipFrame.setVisible(false); 12266 } 12267 12268 private void setSlipSensorsDonePressed(ActionEvent a) { 12269 log.trace("setSlipSensorsDonePressed"); 12270 if (!getSlipSensorInformation()) { 12271 return; 12272 } 12273 12274 Sensor sensorA = getSensorFromEntry(slipSensorA.getText(), false, setSensorsAtSlipFrame); 12275 Sensor sensorB = getSensorFromEntry(slipSensorB.getText(), false, setSensorsAtSlipFrame); 12276 Sensor sensorC = getSensorFromEntry(slipSensorC.getText(), false, setSensorsAtSlipFrame); 12277 Sensor sensorD = getSensorFromEntry(slipSensorD.getText(), false, setSensorsAtSlipFrame); 12278 12279 Sensor currSensorA = layoutSlip.getSensorA(); 12280 Sensor currSensorB = layoutSlip.getSensorB(); 12281 Sensor currSensorC = layoutSlip.getSensorC(); 12282 Sensor currSensorD = layoutSlip.getSensorD(); 12283 12284 if (log.isTraceEnabled()) { 12285 log.trace("current sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 12286 (currSensorA == null) ? "- none- " : currSensorA.getDisplayName(), // NOI18N 12287 (currSensorB == null) ? "- none- " : currSensorB.getDisplayName(), // NOI18N 12288 (currSensorC == null) ? "- none- " : currSensorC.getDisplayName(), // NOI18N 12289 (currSensorD == null) ? "- none- " : currSensorD.getDisplayName()); // NOI18N 12290 log.trace("new sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 12291 (sensorA == null) ? "- none- " : sensorA.getDisplayName(), // NOI18N 12292 (sensorB == null) ? "- none- " : sensorB.getDisplayName(), // NOI18N 12293 (sensorC == null) ? "- none- " : sensorC.getDisplayName(), // NOI18N 12294 (sensorD == null) ? "- none- " : sensorD.getDisplayName()); // NOI18N 12295 } 12296 12297 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 12298 12299 //place/remove sensors as requested 12300 if (sensorA == null) { 12301 if (currSensorA != null && removeSensorFromPanel(currSensorA)) { 12302 layoutSlip.setSensorA(null); 12303 } 12304 } else if (slipSensorA != null && layoutSlip.getConnectA() != null) { 12305 setTurnoutSensor(layoutSlip, sensorA, currSensorA, slipSensorA, layoutSlip.getConnectA(), layoutSlipView.getCoordsA(), "A"); 12306 } 12307 12308 if (sensorB == null) { 12309 if (currSensorB != null && removeSensorFromPanel(currSensorB)) { 12310 layoutSlip.setSensorB(null); 12311 } 12312 } else if (slipSensorB != null && layoutSlip.getConnectB() != null) { 12313 setTurnoutSensor(layoutSlip, sensorB, currSensorB, slipSensorB, layoutSlip.getConnectB(), layoutSlipView.getCoordsB(), "B"); 12314 } 12315 12316 if (sensorC == null) { 12317 if (currSensorC != null && removeSensorFromPanel(currSensorC)) { 12318 layoutSlip.setSensorC(null); 12319 } 12320 } else if (slipSensorC != null && layoutSlip.getConnectC() != null) { 12321 setTurnoutSensor(layoutSlip, sensorC, currSensorC, slipSensorC, layoutSlip.getConnectC(), layoutSlipView.getCoordsC(), "C"); 12322 } 12323 12324 if (sensorD == null) { 12325 if (currSensorD != null && removeSensorFromPanel(currSensorD)) { 12326 layoutSlip.setSensorD(null); 12327 } 12328 } else if (slipSensorD != null && layoutSlip.getConnectD() != null) { 12329 setTurnoutSensor(layoutSlip, sensorD, currSensorD, slipSensorD, layoutSlip.getConnectD(), layoutSlipView.getCoordsD(), "D"); 12330 } 12331 12332 //setup logic if requested 12333 //finish up 12334 setSensorsAtSlipOpenFlag = false; 12335 setSensorsAtSlipFrame.setVisible(false); 12336 if (needRedraw) { 12337 layoutEditor.redrawPanel(); 12338 needRedraw = false; 12339 layoutEditor.setDirty(); 12340 12341 } 12342 } 12343 12344 static class BeanDetails<B extends NamedBean> { 12345 12346 private final String bundleName; 12347 private final String beanString; 12348 private final JLabel textLabel; 12349 12350 private final String boundaryLabelText = Bundle.getMessage("BoundaryOf"); 12351 private final JLabel boundaryLabel = new JLabel(boundaryLabelText); 12352 12353 private final Manager<B> manager; 12354 12355 private final JPanel detailsPanel = new JPanel(new FlowLayout()); 12356 private final JRadioButton addBeanCheck = new JRadioButton(Bundle.getMessage("DoNotPlace")); 12357 private final JRadioButton left = new JRadioButton(Bundle.getMessage("LeftHandSide")); 12358 private final JRadioButton right = new JRadioButton(Bundle.getMessage("RightHandSide")); 12359 private final ButtonGroup buttonGroup = new ButtonGroup(); 12360 private final NamedBeanComboBox<B> beanCombo; 12361 12362 private final JLabel boundaryBlocks = new JLabel(); 12363 12364 private final Border blackline = BorderFactory.createLineBorder(Color.black); 12365 12366 BeanDetails(@Nonnull String beanType, @Nonnull Manager<B> manager) { 12367 beanCombo = new NamedBeanComboBox<>(manager); 12368 beanCombo.setAllowNull(true); 12369 JComboBoxUtil.setupComboBoxMaxRows(beanCombo); 12370 //I18N translate from type (Sensor) to BeanNameSensor 12371 //to use NamedBeanBundle property 12372 if ("Sensor".equals(beanType)) { 12373 bundleName = "BeanNameSensor"; 12374 } else if ("SignalMast".equals(beanType)) { 12375 bundleName = "BeanNameSignalMast"; 12376 } else { 12377 log.error("Unexpected value for BeanDetails: '{}'", beanType); 12378 bundleName = beanType; 12379 } 12380 beanString = Bundle.getMessage(bundleName); 12381 textLabel = new JLabel(beanString); 12382 this.manager = manager; 12383 //this.beanType = beanType; 12384 12385 buttonGroup.add(addBeanCheck); 12386 buttonGroup.add(left); 12387 buttonGroup.add(right); 12388 addBeanCheck.setSelected(true); 12389 12390 boundaryBlocks.setAlignmentX(Component.CENTER_ALIGNMENT); 12391 boundaryBlocks.setOpaque(false); 12392 detailsPanel.setLayout(new BorderLayout()); 12393 detailsPanel.setBorder(BorderFactory.createTitledBorder(blackline, Bundle.getMessage("BlockBoundary"))); 12394 boundaryLabel.setAlignmentX(Component.CENTER_ALIGNMENT); 12395 12396 JPanel boundaryDetails = new JPanel(new FlowLayout()); 12397 boundaryDetails.setOpaque(false); 12398 boundaryDetails.setLayout(new BoxLayout(boundaryDetails, BoxLayout.Y_AXIS)); 12399 boundaryDetails.add(boundaryLabel); 12400 boundaryDetails.add(boundaryBlocks); 12401 12402 detailsPanel.add(boundaryDetails, BorderLayout.PAGE_START); 12403 detailsPanel.add(addIconPanel(), BorderLayout.CENTER); 12404 detailsPanel.add(positionLeftRight(), BorderLayout.PAGE_END); 12405 } 12406 12407 protected void setTextField(String value) { 12408 beanCombo.setSelectedItem(manager.getNamedBean(value)); 12409 } 12410 12411 protected String getText() { 12412 return beanCombo.getSelectedItemDisplayName(); 12413 } 12414 12415 protected B getBean() { 12416 return beanCombo.getSelectedItem(); 12417 } 12418 12419 protected JPanel getDetailsPanel() { 12420 return detailsPanel; 12421 } 12422 12423 protected boolean addToPanel() { 12424 return !addBeanCheck.isSelected(); 12425 } 12426 12427 protected boolean isRightSelected() { 12428 return right.isSelected(); 12429 } 12430 12431 protected void setBoundaryTitle(String text) { 12432 detailsPanel.setBorder(BorderFactory.createTitledBorder(blackline, text)); 12433 } 12434 12435 protected void setBoundaryLabelText(String text) { 12436 boundaryLabel.setText(text); 12437 } 12438 12439 protected void setBoundaryLabel(String label) { 12440 boundaryBlocks.setText(label); 12441 } 12442 12443 protected NamedBeanComboBox<B> getCombo() { 12444 return beanCombo; 12445 } 12446 12447 protected JPanel positionLeftRight() { 12448 JPanel placementPanel = new JPanel(); 12449 placementPanel.setBorder(BorderFactory.createTitledBorder( 12450 blackline, 12451 Bundle.getMessage("PlaceItem", new Object[]{beanString}))); 12452 12453 placementPanel.setLayout(new BoxLayout(placementPanel, BoxLayout.Y_AXIS)); 12454 placementPanel.setOpaque(false); 12455 placementPanel.add(addBeanCheck); 12456 placementPanel.add(left); 12457 placementPanel.add(right); 12458 addBeanCheck.setOpaque(false); 12459 left.setOpaque(false); 12460 right.setOpaque(false); 12461 12462 addBeanCheck.setToolTipText(Bundle.getMessage("PlaceItemToolTip", 12463 new Object[]{beanString})); 12464 12465 right.setToolTipText(Bundle.getMessage("PlaceRightToolTip", 12466 new Object[]{beanString})); 12467 12468 left.setToolTipText(Bundle.getMessage("PlaceLeftToolTip", 12469 new Object[]{beanString})); 12470 return placementPanel; 12471 } 12472 12473 protected JPanel addIconPanel() { 12474 JPanel addBeanPanel = new JPanel(new FlowLayout()); 12475 addBeanPanel.setOpaque(false); 12476 addBeanPanel.add(textLabel); 12477 textLabel.setOpaque(false); 12478 addBeanPanel.add(beanCombo); 12479 return addBeanPanel; 12480 } 12481 } 12482 12483 /*==================*\ 12484 |* setSignalsAtSlip *| 12485 \*==================*/ 12486//operational variables for Set Signals at slip tool 12487 private JmriJFrame setSignalsAtSlipFrame = null; 12488 private boolean setSignalsAtSlipOpenFlag = false; 12489 private boolean setSignalsAtSlipFromMenuFlag = false; 12490 12491 private final JComboBox<String> slipNameComboBox = new JComboBox<>(); 12492 12493 private final NamedBeanComboBox<SignalHead> a1SlipSignalHeadComboBox 12494 = new NamedBeanComboBox<>( 12495 InstanceManager.getDefault(SignalHeadManager.class), 12496 null, DisplayOptions.DISPLAYNAME); 12497 private final NamedBeanComboBox<SignalHead> a2SlipSignalHeadComboBox 12498 = new NamedBeanComboBox<>( 12499 InstanceManager.getDefault(SignalHeadManager.class), 12500 null, DisplayOptions.DISPLAYNAME); 12501 private final NamedBeanComboBox<SignalHead> b1SlipSignalHeadComboBox 12502 = new NamedBeanComboBox<>( 12503 InstanceManager.getDefault(SignalHeadManager.class), 12504 null, DisplayOptions.DISPLAYNAME); 12505 private final NamedBeanComboBox<SignalHead> b2SlipSignalHeadComboBox 12506 = new NamedBeanComboBox<>( 12507 InstanceManager.getDefault(SignalHeadManager.class), 12508 null, DisplayOptions.DISPLAYNAME); 12509 private final NamedBeanComboBox<SignalHead> c1SlipSignalHeadComboBox 12510 = new NamedBeanComboBox<>( 12511 InstanceManager.getDefault(SignalHeadManager.class), 12512 null, DisplayOptions.DISPLAYNAME); 12513 private final NamedBeanComboBox<SignalHead> c2SlipSignalHeadComboBox 12514 = new NamedBeanComboBox<>( 12515 InstanceManager.getDefault(SignalHeadManager.class), 12516 null, DisplayOptions.DISPLAYNAME); 12517 private final NamedBeanComboBox<SignalHead> d1SlipSignalHeadComboBox 12518 = new NamedBeanComboBox<>( 12519 InstanceManager.getDefault(SignalHeadManager.class), 12520 null, DisplayOptions.DISPLAYNAME); 12521 private final NamedBeanComboBox<SignalHead> d2SlipSignalHeadComboBox 12522 = new NamedBeanComboBox<>( 12523 InstanceManager.getDefault(SignalHeadManager.class), 12524 null, DisplayOptions.DISPLAYNAME); 12525 12526 private final JCheckBox setA1SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12527 private final JCheckBox setupA1SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12528 private final JCheckBox setA2SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12529 private final JCheckBox setupA2SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12530 private final JCheckBox setB1SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12531 private final JCheckBox setupB1SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12532 private final JCheckBox setB2SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12533 private final JCheckBox setupB2SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12534 private final JCheckBox setC1SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12535 private final JCheckBox setupC1SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12536 private final JCheckBox setC2SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12537 private final JCheckBox setupC2SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12538 private final JCheckBox setD1SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12539 private final JCheckBox setupD1SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12540 private final JCheckBox setD2SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12541 private final JCheckBox setupD2SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12542 12543 private JButton setSlipSignalsDone = null; 12544 private JButton setSlipSignalsCancel = null; 12545 private LayoutSlip layoutSlip = null; 12546 12547 private SignalHead a1SlipHead = null; 12548 private SignalHead a2SlipHead = null; 12549 private SignalHead b1SlipHead = null; 12550 private SignalHead b2SlipHead = null; 12551 private SignalHead c1SlipHead = null; 12552 private SignalHead c2SlipHead = null; 12553 private SignalHead d1SlipHead = null; 12554 private SignalHead d2SlipHead = null; 12555 12556 private JPanel dblSlipC2SigPanel; 12557 private JPanel dblSlipB2SigPanel; 12558 12559 public void setSignalsAtSlipFromMenu(@Nonnull LayoutSlip ls, 12560 @Nonnull MultiIconEditor theEditor, @Nonnull JFrame theFrame) { 12561 layoutSlip = ls; 12562 a1SlipSignalHeadComboBox.setSelectedItem(null); 12563 a2SlipSignalHeadComboBox.setSelectedItem(null); 12564 b1SlipSignalHeadComboBox.setSelectedItem(null); 12565 b2SlipSignalHeadComboBox.setSelectedItem(null); 12566 c1SlipSignalHeadComboBox.setSelectedItem(null); 12567 c2SlipSignalHeadComboBox.setSelectedItem(null); 12568 d1SlipSignalHeadComboBox.setSelectedItem(null); 12569 d2SlipSignalHeadComboBox.setSelectedItem(null); 12570 12571 setSignalsAtSlipFromMenuFlag = true; 12572 setSignalsAtSlip(theEditor, theFrame); 12573 setSignalsAtSlipFromMenuFlag = false; 12574 } 12575 12576 public void setSignalsAtSlip(@Nonnull MultiIconEditor theEditor, 12577 @Nonnull JFrame theFrame) { 12578 signalIconEditor = theEditor; 12579 signalFrame = theFrame; 12580 12581 //Initialize if needed 12582 if (setSignalsAtSlipFrame == null) { 12583 setSignalsAtSlipOpenFlag = false; 12584 setSignalsAtSlipFrame = new JmriJFrame(Bundle.getMessage("SignalsAtSlip"), false, true); 12585 oneFrameToRuleThemAll(setSignalsAtSlipFrame); 12586 setSignalsAtSlipFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 12587 setSignalsAtSlipFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtSlip", true); 12588 setSignalsAtSlipFrame.setLocation(70, 30); 12589 Container theContentPane = setSignalsAtSlipFrame.getContentPane(); 12590 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 12591 12592 JPanel panel1 = new JPanel(new FlowLayout()); 12593 JLabel turnout1NameLabel = new JLabel(Bundle.getMessage("Slip") + " " 12594 + Bundle.getMessage("Name")); 12595 panel1.add(turnout1NameLabel); 12596 panel1.add(slipNameComboBox); 12597 for (LayoutSlip slip : layoutEditor.getLayoutSlips()) { 12598 slipNameComboBox.addItem(slip.getDisplayName()); 12599 } 12600 12601 slipNameComboBox.insertItemAt("", 0); 12602 12603 if (layoutSlip != null) { 12604 slipNameComboBox.setSelectedItem(layoutSlip.getDisplayName()); 12605 getSlipTurnoutSignalsGetSaved(null); 12606 } else { 12607 slipNameComboBox.setSelectedIndex(0); 12608 } 12609 slipNameComboBox.addActionListener((ActionEvent e) -> { 12610 for (LayoutSlip slip : layoutEditor.getLayoutSlips()) { 12611 if (slip.getDisplayName().equals(slipNameComboBox.getSelectedItem())) { 12612 //slip1NameField.setText(slip.getDisplayName()); 12613 getSlipTurnoutSignalsGetSaved(e); 12614 boolean enable = (slip.getSlipType() == LayoutSlip.TurnoutType.DOUBLE_SLIP); 12615 dblSlipC2SigPanel.setVisible(enable); 12616 dblSlipB2SigPanel.setVisible(enable); 12617 setSignalsAtSlipFrame.pack(); 12618 return; 12619 } 12620 } 12621 }); 12622 theContentPane.add(panel1); 12623 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12624 12625 JPanel panel2a = new JPanel(new FlowLayout()); 12626 panel2a.add(new JLabel(" ")); 12627 panel2a.add(setPlaceAllHeads); 12628 setPlaceAllHeads.setToolTipText(Bundle.getMessage("PlaceAllHeadsHint")); 12629 setPlaceAllHeads.addActionListener((ActionEvent e) -> { 12630 boolean isSelected = setPlaceAllHeads.isSelected(); 12631 //(de)select all checkboxes 12632 setA1SlipHead.setSelected(isSelected); 12633 setA2SlipHead.setSelected(isSelected); 12634 setB1SlipHead.setSelected(isSelected); 12635 setB2SlipHead.setSelected(isSelected); 12636 setC1SlipHead.setSelected(isSelected); 12637 setC2SlipHead.setSelected(isSelected); 12638 setD1SlipHead.setSelected(isSelected); 12639 setD2SlipHead.setSelected(isSelected); 12640 }); 12641 panel2a.add(new JLabel(" ")); 12642 panel2a.add(setupAllLogic); 12643 setupAllLogic.setToolTipText(Bundle.getMessage("SetAllLogicHint")); 12644 setupAllLogic.addActionListener((ActionEvent e) -> { 12645 boolean isSelected = setupAllLogic.isSelected(); 12646 //(de)select all checkboxes 12647 setupA1SlipLogic.setSelected(isSelected); 12648 setupA2SlipLogic.setSelected(isSelected); 12649 setupB1SlipLogic.setSelected(isSelected); 12650 setupB2SlipLogic.setSelected(isSelected); 12651 setupC1SlipLogic.setSelected(isSelected); 12652 setupC2SlipLogic.setSelected(isSelected); 12653 setupD1SlipLogic.setSelected(isSelected); 12654 setupD2SlipLogic.setSelected(isSelected); 12655 }); 12656 theContentPane.add(panel2a); 12657 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12658 12659 //Signal heads located at turnout 1 12660 JPanel panel21x = new JPanel(new FlowLayout()); 12661 panel21x.add(new JLabel(Bundle.getMessage("SignalLocated") 12662 + " " + Bundle.getMessage("BeanNameTurnout") + " 1 - " 12663 + Bundle.getMessage("ContinuingTrack"))); 12664 theContentPane.add(panel21x); 12665 12666 JPanel panel21 = new JPanel(new FlowLayout()); 12667 panel21.add(new JLabel(Bundle.getMessage("MakeLabel", 12668 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12669 + Bundle.getMessage("ContinuingTrack")))); 12670 panel21.add(a1SlipSignalHeadComboBox); 12671 theContentPane.add(panel21); 12672 a1SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12673 12674 JPanel panel22 = new JPanel(new FlowLayout()); 12675 panel22.add(new JLabel(Bundle.getMessage("OrBoth") + " 2 " + Bundle.getMessage("Tracks)") + " ")); 12676 panel22.add(setA1SlipHead); 12677 setA1SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12678 panel22.add(new JLabel(" ")); 12679 panel22.add(setupA1SlipLogic); 12680 setupA1SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12681 theContentPane.add(panel22); 12682 12683 JPanel panel23 = new JPanel(new FlowLayout()); 12684 panel23.add(new JLabel(Bundle.getMessage("MakeLabel", 12685 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12686 + Bundle.getMessage("DivergingTrack")))); 12687 panel23.add(a2SlipSignalHeadComboBox); 12688 theContentPane.add(panel23); 12689 a2SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12690 12691 JPanel panel24 = new JPanel(new FlowLayout()); 12692 panel24.add(new JLabel(" ")); 12693 panel24.add(setA2SlipHead); 12694 setA2SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12695 panel24.add(new JLabel(" ")); 12696 panel24.add(setupA2SlipLogic); 12697 setupA2SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12698 theContentPane.add(panel24); 12699 12700 JPanel panel31x = new JPanel(new FlowLayout()); 12701 panel31x.add(new JLabel(Bundle.getMessage("SignalLocated") 12702 + " " + Bundle.getMessage("BeanNameTurnout") + " 1 - " 12703 + Bundle.getMessage("DivergingTrack"))); 12704 theContentPane.add(panel31x); 12705 12706 JPanel panel31 = new JPanel(new FlowLayout()); 12707 panel31.add(new JLabel(Bundle.getMessage("MakeLabel", 12708 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12709 + Bundle.getMessage("ContinuingTrack")))); 12710 panel31.add(b1SlipSignalHeadComboBox); 12711 theContentPane.add(panel31); 12712 b1SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12713 12714 JPanel panel32 = new JPanel(new FlowLayout()); 12715 panel32.add(new JLabel(Bundle.getMessage("OrBoth") + " 2 " + Bundle.getMessage("Tracks)") + " ")); 12716 panel32.add(setB1SlipHead); 12717 setB1SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12718 panel32.add(new JLabel(" ")); 12719 panel32.add(setupB1SlipLogic); 12720 setupB1SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12721 theContentPane.add(panel32); 12722 12723 dblSlipB2SigPanel = new JPanel(new FlowLayout()); 12724 dblSlipB2SigPanel.setLayout(new BoxLayout(dblSlipB2SigPanel, BoxLayout.Y_AXIS)); 12725 12726 JPanel panel33 = new JPanel(new FlowLayout()); 12727 panel33.add(new JLabel(Bundle.getMessage("MakeLabel", 12728 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12729 + Bundle.getMessage("DivergingTrack")))); 12730 panel33.add(b2SlipSignalHeadComboBox); 12731 dblSlipB2SigPanel.add(panel33); 12732 b2SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12733 12734 JPanel panel34 = new JPanel(new FlowLayout()); 12735 panel34.add(new JLabel(" ")); 12736 panel34.add(setB2SlipHead); 12737 setB2SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12738 panel34.add(new JLabel(" ")); 12739 panel34.add(setupB2SlipLogic); 12740 setupB2SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12741 dblSlipB2SigPanel.add(panel34); 12742 12743 theContentPane.add(dblSlipB2SigPanel); 12744 dblSlipB2SigPanel.setVisible(false); 12745 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12746 //Signal heads located at turnout 2 12747 12748 JPanel panel41x = new JPanel(new FlowLayout()); 12749 panel41x.add(new JLabel(Bundle.getMessage("SignalLocated") 12750 + " " + Bundle.getMessage("BeanNameTurnout") + " 2 - " 12751 + Bundle.getMessage("ContinuingTrack"))); 12752 theContentPane.add(panel41x); 12753 12754 JPanel panel41 = new JPanel(new FlowLayout()); 12755 panel41.add(new JLabel(Bundle.getMessage("MakeLabel", 12756 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12757 + Bundle.getMessage("ContinuingTrack")))); 12758 panel41.add(c1SlipSignalHeadComboBox); 12759 theContentPane.add(panel41); 12760 c1SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12761 12762 JPanel panel42 = new JPanel(new FlowLayout()); 12763 panel42.add(new JLabel(Bundle.getMessage("OrBoth") + " 1 " + Bundle.getMessage("Tracks)") + " ")); 12764 panel42.add(setC1SlipHead); 12765 setC1SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12766 panel42.add(new JLabel(" ")); 12767 panel42.add(setupC1SlipLogic); 12768 setupC1SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12769 theContentPane.add(panel42); 12770 dblSlipC2SigPanel = new JPanel(new FlowLayout()); 12771 dblSlipC2SigPanel.setLayout(new BoxLayout(dblSlipC2SigPanel, BoxLayout.Y_AXIS)); 12772 12773 JPanel panel43 = new JPanel(new FlowLayout()); 12774 panel43.add(new JLabel(Bundle.getMessage("MakeLabel", 12775 Bundle.getMessage("ProtectsTurnout") + " 1 - " 12776 + Bundle.getMessage("DivergingTrack")))); 12777 panel43.add(c2SlipSignalHeadComboBox); 12778 dblSlipC2SigPanel.add(panel43); 12779 c2SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12780 12781 JPanel panel44 = new JPanel(new FlowLayout()); 12782 panel44.add(new JLabel(" ")); 12783 panel44.add(setC2SlipHead); 12784 setC2SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12785 panel44.add(new JLabel(" ")); 12786 panel44.add(setupC2SlipLogic); 12787 setupC2SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12788 dblSlipC2SigPanel.add(panel44); 12789 theContentPane.add(dblSlipC2SigPanel); 12790 12791 JPanel panel51x = new JPanel(new FlowLayout()); 12792 panel51x.add(new JLabel(Bundle.getMessage("SignalLocated") 12793 + " " + Bundle.getMessage("BeanNameTurnout") + " 2 - " 12794 + Bundle.getMessage("DivergingTrack"))); 12795 theContentPane.add(panel51x); 12796 12797 JPanel panel51 = new JPanel(new FlowLayout()); 12798 panel51.add(new JLabel(Bundle.getMessage("MakeLabel", 12799 Bundle.getMessage("ProtectsTurnout") + " 1 - " 12800 + Bundle.getMessage("ContinuingTrack")))); 12801 panel51.add(d1SlipSignalHeadComboBox); 12802 theContentPane.add(panel51); 12803 d1SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12804 12805 JPanel panel52 = new JPanel(new FlowLayout()); 12806 panel52.add(new JLabel(Bundle.getMessage("OrBoth") + " 1 " + Bundle.getMessage("Tracks)") + " ")); 12807 panel52.add(setD1SlipHead); 12808 setD1SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12809 panel52.add(new JLabel(" ")); 12810 panel52.add(setupD1SlipLogic); 12811 setupD1SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12812 theContentPane.add(panel52); 12813 12814 JPanel panel53 = new JPanel(new FlowLayout()); 12815 panel53.add(new JLabel(Bundle.getMessage("MakeLabel", 12816 Bundle.getMessage("ProtectsTurnout") + " 1 - " 12817 + Bundle.getMessage("DivergingTrack")))); 12818 panel53.add(d2SlipSignalHeadComboBox); 12819 theContentPane.add(panel53); 12820 d2SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12821 12822 JPanel panel54 = new JPanel(new FlowLayout()); 12823 panel54.add(new JLabel(" ")); 12824 panel54.add(setD2SlipHead); 12825 setD2SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12826 panel54.add(new JLabel(" ")); 12827 panel54.add(setupD2SlipLogic); 12828 setupD2SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12829 theContentPane.add(panel54); 12830 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12831 12832 JPanel panel6 = new JPanel(new FlowLayout()); 12833 panel6.add(changeTToTSignalIcon = new JButton(Bundle.getMessage("ChangeSignalIcon"))); 12834 changeTToTSignalIcon.addActionListener((ActionEvent e) -> signalFrame.setVisible(true)); 12835 changeTToTSignalIcon.setToolTipText(Bundle.getMessage("ChangeSignalIconHint")); 12836 panel6.add(new JLabel(" ")); 12837 panel6.add(setSlipSignalsDone = new JButton(Bundle.getMessage("ButtonDone"))); 12838 setSlipSignalsDone.addActionListener(this::setSlipSignalsDonePressed); 12839 setSlipSignalsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 12840 panel6.add(setSlipSignalsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 12841 setSlipSignalsCancel.addActionListener(this::setSlipSignalsCancelPressed); 12842 setSlipSignalsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 12843 theContentPane.add(panel6); 12844 setSignalsAtSlipFrame.addWindowListener(new WindowAdapter() { 12845 @Override 12846 public void windowClosing(WindowEvent e) { 12847 setSlipSignalsCancelPressed(null); 12848 } 12849 }); 12850 } 12851 setPlaceAllHeads.setSelected(false); 12852 setupAllLogic.setSelected(false); 12853 12854 boolean enable = (layoutSlip != null 12855 && layoutSlip.getSlipType() == LayoutSlip.TurnoutType.DOUBLE_SLIP); 12856 dblSlipC2SigPanel.setVisible(enable); 12857 dblSlipB2SigPanel.setVisible(enable); 12858 12859 if (setSignalsAtSlipFromMenuFlag) { 12860 getSlipTurnoutSignalsGetSaved(null); 12861 } 12862 12863 if (!setSignalsAtSlipOpenFlag) { 12864 setSignalsAtSlipFrame.setPreferredSize(null); 12865 setSignalsAtSlipFrame.pack(); 12866 setSignalsAtSlipOpenFlag = true; 12867 } 12868 setSignalsAtSlipFrame.setVisible(true); 12869 } 12870 12871 private void getSlipTurnoutSignalsGetSaved(ActionEvent a) { 12872 if (!getSlipTurnoutInformation()) { 12873 return; 12874 } 12875 a1SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalA1()); 12876 a2SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalA2()); 12877 b1SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalB1()); 12878 b2SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalB2()); 12879 c1SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalC1()); 12880 c2SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalC2()); 12881 d1SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalD1()); 12882 d2SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalD2()); 12883 } 12884 12885 private void setSlipSignalsCancelPressed(ActionEvent a) { 12886 setSignalsAtSlipOpenFlag = false; 12887 setSignalsAtSlipFrame.setVisible(false); 12888 } 12889 12890 private boolean getSlipTurnoutInformation() { 12891 turnout1 = null; 12892 turnout2 = null; 12893 layoutSlip = null; 12894 for (LayoutSlip ls : layoutEditor.getLayoutSlips()) { 12895 if (ls.getDisplayName().equals(slipNameComboBox.getSelectedItem())) { 12896 layoutSlip = ls; 12897 break; 12898 } 12899 } 12900 if (layoutSlip == null) { 12901 return false; 12902 } 12903 String str = layoutSlip.getDisplayName(); 12904 12905 turnout1 = layoutSlip.getTurnout(); 12906 if (turnout1 == null) { 12907 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12908 Bundle.getMessage("SignalsError2", 12909 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 12910 JmriJOptionPane.ERROR_MESSAGE); 12911 return false; 12912 } 12913 turnout2 = layoutSlip.getTurnoutB(); 12914 if (turnout2 == null) { 12915 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12916 Bundle.getMessage("SignalsError2", 12917 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 12918 JmriJOptionPane.ERROR_MESSAGE); 12919 return false; 12920 } 12921 return true; 12922 } 12923 12924 private void setSlipSignalsDonePressed(ActionEvent a) { 12925 if (!getSlipTurnoutInformation()) { 12926 return; 12927 } 12928 if (!getSlipSignalHeadInformation()) { 12929 return; 12930 } 12931 12932 //place signal icons if requested, and assign signal heads to this turnout 12933 String signalHeadName = a1SlipSignalHeadComboBox.getSelectedItemDisplayName(); 12934 if (signalHeadName == null) { 12935 signalHeadName = ""; 12936 } 12937 if (setA1SlipHead.isSelected()) { 12938 if (isHeadOnPanel(a1SlipHead) 12939 && (a1SlipHead != getHeadFromName(layoutSlip.getSignalB1Name()))) { 12940 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12941 Bundle.getMessage("SignalsError6", 12942 new Object[]{signalHeadName}), 12943 Bundle.getMessage("ErrorTitle"), 12944 JmriJOptionPane.ERROR_MESSAGE); 12945 return; 12946 } else { 12947 removeSignalHeadFromPanel(layoutSlip.getSignalA1Name()); 12948 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 12949 placeA1Slip(signalHeadName); 12950 } else { 12951 placeB1Slip(signalHeadName); 12952 } 12953 removeAssignment(a1SlipHead); 12954 layoutSlip.setSignalA1Name(signalHeadName); 12955 needRedraw = true; 12956 } 12957 } else { 12958 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a1SlipHead, layoutSlip); 12959 if (assigned == LayoutTurnout.Geometry.NONE) { 12960 if (isHeadOnPanel(a1SlipHead) 12961 && isHeadAssignedAnywhere(a1SlipHead)) { 12962 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12963 Bundle.getMessage("SignalsError8", 12964 new Object[]{signalHeadName}), 12965 Bundle.getMessage("ErrorTitle"), 12966 JmriJOptionPane.ERROR_MESSAGE); 12967 return; 12968 } else { 12969 removeSignalHeadFromPanel(layoutSlip.getSignalB1Name()); 12970 removeAssignment(a1SlipHead); 12971 layoutSlip.setSignalA1Name(signalHeadName); 12972 } 12973 //} else if (assigned != B1) { 12974 //need to figure out what to do in this case - assigned to a different position on the same turnout. 12975 } 12976 } 12977 12978 signalHeadName = a2SlipSignalHeadComboBox.getSelectedItemDisplayName(); 12979 if (signalHeadName == null) { 12980 signalHeadName = ""; 12981 } 12982 if ((a2SlipHead != null) && setA2SlipHead.isSelected()) { 12983 if (isHeadOnPanel(a2SlipHead) 12984 && (a2SlipHead != getHeadFromName(layoutSlip.getSignalB2Name()))) { 12985 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12986 Bundle.getMessage("SignalsError6", 12987 new Object[]{signalHeadName}), 12988 Bundle.getMessage("ErrorTitle"), 12989 JmriJOptionPane.ERROR_MESSAGE); 12990 return; 12991 } else { 12992 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 12993 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 12994 placeA2Slip(signalHeadName); 12995 } else { 12996 placeB2Slip(signalHeadName); 12997 } 12998 removeAssignment(a2SlipHead); 12999 layoutSlip.setSignalA2Name(signalHeadName); 13000 needRedraw = true; 13001 } 13002 } else if (a2SlipHead != null) { 13003 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a2SlipHead, layoutSlip); 13004 if (assigned == LayoutTurnout.Geometry.NONE) { 13005 if (isHeadOnPanel(a2SlipHead) 13006 && isHeadAssignedAnywhere(a2SlipHead)) { 13007 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13008 Bundle.getMessage("SignalsError8", 13009 new Object[]{signalHeadName}), 13010 Bundle.getMessage("ErrorTitle"), 13011 JmriJOptionPane.ERROR_MESSAGE); 13012 return; 13013 } else { 13014 removeSignalHeadFromPanel(layoutSlip.getSignalA2Name()); 13015 removeAssignment(a2SlipHead); 13016 layoutSlip.setSignalA2Name(signalHeadName); 13017 } 13018 //} else if (assigned != B2) { 13019 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13020 } 13021 } else { //a2SlipHead known to be null here 13022 removeSignalHeadFromPanel(layoutSlip.getSignalA2Name()); 13023 layoutSlip.setSignalB2Name(""); 13024 } 13025 13026 signalHeadName = b1SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13027 if (signalHeadName == null) { 13028 signalHeadName = ""; 13029 } 13030 if (setB1SlipHead.isSelected()) { 13031 if (isHeadOnPanel(b1SlipHead) 13032 && (b1SlipHead != getHeadFromName(layoutSlip.getSignalC1Name()))) { 13033 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13034 Bundle.getMessage("SignalsError6", 13035 new Object[]{signalHeadName}), 13036 Bundle.getMessage("ErrorTitle"), 13037 JmriJOptionPane.ERROR_MESSAGE); 13038 return; 13039 } else { 13040 removeSignalHeadFromPanel(layoutSlip.getSignalB1Name()); 13041 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13042 placeB1Slip(signalHeadName); 13043 } else { 13044 placeA1Slip(signalHeadName); 13045 } 13046 removeAssignment(b1SlipHead); 13047 layoutSlip.setSignalB1Name(signalHeadName); 13048 needRedraw = true; 13049 } 13050 } else { 13051 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b1SlipHead, layoutSlip); 13052 if (assigned == LayoutTurnout.Geometry.NONE) { 13053 if (isHeadOnPanel(b1SlipHead) 13054 && isHeadAssignedAnywhere(b1SlipHead)) { 13055 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13056 Bundle.getMessage("SignalsError8", 13057 new Object[]{signalHeadName}), 13058 Bundle.getMessage("ErrorTitle"), 13059 JmriJOptionPane.ERROR_MESSAGE); 13060 return; 13061 } else { 13062 removeSignalHeadFromPanel(layoutSlip.getSignalB1Name()); 13063 removeAssignment(b1SlipHead); 13064 layoutSlip.setSignalB1Name(signalHeadName); 13065 } 13066 //} else if (assigned != C1) { 13067 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13068 } 13069 } 13070 13071 if (layoutSlip.getTurnoutType() == LayoutSlip.TurnoutType.DOUBLE_SLIP) { 13072 signalHeadName = b2SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13073 if (signalHeadName == null) { 13074 signalHeadName = ""; 13075 } 13076 if ((b2SlipHead != null) && setB2SlipHead.isSelected()) { 13077 if (isHeadOnPanel(b2SlipHead) 13078 && (b2SlipHead != getHeadFromName(layoutSlip.getSignalC2Name()))) { 13079 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13080 Bundle.getMessage("SignalsError6", 13081 new Object[]{signalHeadName}), 13082 Bundle.getMessage("ErrorTitle"), 13083 JmriJOptionPane.ERROR_MESSAGE); 13084 return; 13085 } else { 13086 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 13087 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13088 placeB2Slip(signalHeadName); 13089 } else { 13090 placeA2Slip(signalHeadName); 13091 } 13092 removeAssignment(b2SlipHead); 13093 layoutSlip.setSignalB2Name(signalHeadName); 13094 needRedraw = true; 13095 } 13096 } else if (b2SlipHead != null) { 13097 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b2SlipHead, layoutSlip); 13098 if (assigned == LayoutTurnout.Geometry.NONE) { 13099 if (isHeadOnPanel(b2SlipHead) 13100 && isHeadAssignedAnywhere(b2SlipHead)) { 13101 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13102 Bundle.getMessage("SignalsError8", 13103 new Object[]{signalHeadName}), 13104 Bundle.getMessage("ErrorTitle"), 13105 JmriJOptionPane.ERROR_MESSAGE); 13106 return; 13107 } else { 13108 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 13109 removeAssignment(b2SlipHead); 13110 layoutSlip.setSignalB2Name(signalHeadName); 13111 } 13112 //} else if (assigned != C2) { 13113 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13114 } 13115 } else { //b2SlipHead known to be null here 13116 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 13117 layoutSlip.setSignalB2Name(""); 13118 } 13119 } else { 13120 if (b2SlipHead != null) { 13121 BlockBossLogic.getStoppedObject(layoutSlip.getSignalB2Name()); 13122 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 13123 layoutSlip.setSignalB2Name(""); 13124 b2SlipHead = null; 13125 } 13126 } 13127 13128 //signal heads on turnout 2 13129 signalHeadName = c1SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13130 if (signalHeadName == null) { 13131 signalHeadName = ""; 13132 } 13133 if (setC1SlipHead.isSelected()) { 13134 if (isHeadOnPanel(c1SlipHead) 13135 && (c1SlipHead != getHeadFromName(layoutSlip.getSignalB1Name()))) { 13136 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13137 Bundle.getMessage("SignalsError6", 13138 new Object[]{signalHeadName}), 13139 Bundle.getMessage("ErrorTitle"), 13140 JmriJOptionPane.ERROR_MESSAGE); 13141 return; 13142 } else { 13143 removeSignalHeadFromPanel(layoutSlip.getSignalC1Name()); 13144 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13145 placeC1Slip(signalHeadName); 13146 } else { 13147 placeD1Slip(signalHeadName); 13148 } 13149 removeAssignment(c1SlipHead); 13150 layoutSlip.setSignalC1Name(signalHeadName); 13151 needRedraw = true; 13152 } 13153 } else { 13154 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c1SlipHead, layoutSlip); 13155 if (assigned == LayoutTurnout.Geometry.NONE) { 13156 if (isHeadOnPanel(c1SlipHead) 13157 && isHeadAssignedAnywhere(c1SlipHead)) { 13158 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13159 Bundle.getMessage("SignalsError8", 13160 new Object[]{signalHeadName}), 13161 Bundle.getMessage("ErrorTitle"), 13162 JmriJOptionPane.ERROR_MESSAGE); 13163 return; 13164 } else { 13165 removeSignalHeadFromPanel(layoutSlip.getSignalC1Name()); 13166 removeAssignment(c1SlipHead); 13167 layoutSlip.setSignalC1Name(signalHeadName); 13168 } 13169 //} else if (assigned != B1) { 13170 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13171 } 13172 } 13173 13174 if (layoutSlip.getTurnoutType() == LayoutSlip.TurnoutType.DOUBLE_SLIP) { 13175 signalHeadName = c2SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13176 if (signalHeadName == null) { 13177 signalHeadName = ""; 13178 } 13179 if ((c2SlipHead != null) && setC2SlipHead.isSelected()) { 13180 if (isHeadOnPanel(c2SlipHead) 13181 && (c2SlipHead != getHeadFromName(layoutSlip.getSignalB2Name()))) { 13182 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13183 Bundle.getMessage("SignalsError6", 13184 new Object[]{signalHeadName}), 13185 Bundle.getMessage("ErrorTitle"), 13186 JmriJOptionPane.ERROR_MESSAGE); 13187 return; 13188 } else { 13189 removeSignalHeadFromPanel(layoutSlip.getSignalC2Name()); 13190 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13191 placeC2Slip(signalHeadName); 13192 } else { 13193 placeD2Slip(signalHeadName); 13194 } 13195 removeAssignment(c2SlipHead); 13196 layoutSlip.setSignalC2Name(signalHeadName); 13197 needRedraw = true; 13198 } 13199 } else if (c2SlipHead != null) { 13200 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c2SlipHead, layoutSlip); 13201 if (assigned == LayoutTurnout.Geometry.NONE) { 13202 if (isHeadOnPanel(c2SlipHead) 13203 && isHeadAssignedAnywhere(c2SlipHead)) { 13204 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13205 Bundle.getMessage("SignalsError8", 13206 new Object[]{signalHeadName}), 13207 Bundle.getMessage("ErrorTitle"), 13208 JmriJOptionPane.ERROR_MESSAGE); 13209 return; 13210 } else { 13211 removeSignalHeadFromPanel(layoutSlip.getSignalC2Name()); 13212 removeAssignment(c2SlipHead); 13213 layoutSlip.setSignalC2Name(signalHeadName); 13214 } 13215 //} else if (assigned != B2) { 13216 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13217 } 13218 } else { //c2SlipHead known to be null here 13219 removeSignalHeadFromPanel(layoutSlip.getSignalC2Name()); 13220 layoutSlip.setSignalC2Name(""); 13221 } 13222 } else { 13223 if (c2SlipHead != null) { 13224 BlockBossLogic.getStoppedObject(layoutSlip.getSignalC2Name()); 13225 removeSignalHeadFromPanel(layoutSlip.getSignalC2Name()); 13226 layoutSlip.setSignalC2Name(""); 13227 c2SlipHead = null; 13228 } 13229 } 13230 13231 signalHeadName = d1SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13232 if (signalHeadName == null) { 13233 signalHeadName = ""; 13234 } 13235 if (setD1SlipHead.isSelected()) { 13236 if (isHeadOnPanel(d1SlipHead) 13237 && (d1SlipHead != getHeadFromName(layoutSlip.getSignalC1Name()))) { 13238 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13239 Bundle.getMessage("SignalsError6", 13240 new Object[]{signalHeadName}), 13241 Bundle.getMessage("ErrorTitle"), 13242 JmriJOptionPane.ERROR_MESSAGE); 13243 return; 13244 } else { 13245 removeSignalHeadFromPanel(layoutSlip.getSignalD1Name()); 13246 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13247 placeD1Slip(signalHeadName); 13248 } else { 13249 placeC1Slip(signalHeadName); 13250 } 13251 removeAssignment(d1SlipHead); 13252 layoutSlip.setSignalD1Name(signalHeadName); 13253 needRedraw = true; 13254 } 13255 } else { 13256 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d1SlipHead, layoutSlip); 13257 if (assigned == LayoutTurnout.Geometry.NONE) { 13258 if (isHeadOnPanel(d1SlipHead) 13259 && isHeadAssignedAnywhere(d1SlipHead)) { 13260 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13261 Bundle.getMessage("SignalsError8", 13262 new Object[]{signalHeadName}), 13263 Bundle.getMessage("ErrorTitle"), 13264 JmriJOptionPane.ERROR_MESSAGE); 13265 return; 13266 } else { 13267 removeSignalHeadFromPanel(layoutSlip.getSignalD1Name()); 13268 removeAssignment(d1SlipHead); 13269 layoutSlip.setSignalD1Name(signalHeadName); 13270 } 13271 //} else if (assigned != C1) { 13272 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13273 } 13274 } 13275 13276 signalHeadName = d2SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13277 if (signalHeadName == null) { 13278 signalHeadName = ""; 13279 } 13280 if ((d2SlipHead != null) && setD2SlipHead.isSelected()) { 13281 if (isHeadOnPanel(d2SlipHead) 13282 && (d2SlipHead != getHeadFromName(layoutSlip.getSignalC2Name()))) { 13283 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13284 Bundle.getMessage("SignalsError6", 13285 new Object[]{signalHeadName}), 13286 Bundle.getMessage("ErrorTitle"), 13287 JmriJOptionPane.ERROR_MESSAGE); 13288 return; 13289 } else { 13290 removeSignalHeadFromPanel(layoutSlip.getSignalD2Name()); 13291 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13292 placeD2Slip(signalHeadName); 13293 } else { 13294 placeC2Slip(signalHeadName); 13295 } 13296 removeAssignment(d2SlipHead); 13297 layoutSlip.setSignalD2Name(signalHeadName); 13298 needRedraw = true; 13299 } 13300 } else if (d2SlipHead != null) { 13301 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d2SlipHead, layoutSlip); 13302 if (assigned == LayoutTurnout.Geometry.NONE) { 13303 if (isHeadOnPanel(d2SlipHead) 13304 && isHeadAssignedAnywhere(d2SlipHead)) { 13305 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13306 Bundle.getMessage("SignalsError8", 13307 new Object[]{signalHeadName}), 13308 Bundle.getMessage("ErrorTitle"), 13309 JmriJOptionPane.ERROR_MESSAGE); 13310 return; 13311 } else { 13312 removeSignalHeadFromPanel(layoutSlip.getSignalD2Name()); 13313 removeAssignment(d2SlipHead); 13314 layoutSlip.setSignalD2Name(signalHeadName); 13315 } 13316 //} else if (assigned != C2) { 13317 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13318 } 13319 } else { //d2SlipHead known to be null here 13320 removeSignalHeadFromPanel(layoutSlip.getSignalD2Name()); 13321 layoutSlip.setSignalD2Name(""); 13322 } 13323 //setup logic if requested 13324 if (setupA1SlipLogic.isSelected() || setupA2SlipLogic.isSelected()) { 13325 setLogicSlip(a1SlipHead, (TrackSegment) layoutSlip.getConnectC(), a2SlipHead, 13326 (TrackSegment) layoutSlip.getConnectD(), setupA1SlipLogic.isSelected(), 13327 setupA2SlipLogic.isSelected(), layoutSlip, layoutSlip.getTurnout(), 13328 layoutSlip.getTurnoutB(), LayoutTurnout.STATE_AC, LayoutTurnout.STATE_AD, 0); 13329 } 13330 if (setupB1SlipLogic.isSelected() || setupB2SlipLogic.isSelected()) { 13331 setLogicSlip(b1SlipHead, (TrackSegment) layoutSlip.getConnectD(), b2SlipHead, 13332 (TrackSegment) layoutSlip.getConnectC(), setupB1SlipLogic.isSelected(), 13333 setupB2SlipLogic.isSelected(), layoutSlip, layoutSlip.getTurnout(), 13334 layoutSlip.getTurnoutB(), LayoutTurnout.STATE_BD, LayoutTurnout.STATE_BC, 2); 13335 } 13336 if (setupC1SlipLogic.isSelected() || setupC2SlipLogic.isSelected()) { 13337 setLogicSlip(c1SlipHead, (TrackSegment) layoutSlip.getConnectA(), c2SlipHead, 13338 (TrackSegment) layoutSlip.getConnectB(), setupC1SlipLogic.isSelected(), 13339 setupC2SlipLogic.isSelected(), layoutSlip, layoutSlip.getTurnoutB(), 13340 layoutSlip.getTurnout(), LayoutTurnout.STATE_AC, LayoutTurnout.STATE_BC, 4); 13341 } 13342 if (setupD1SlipLogic.isSelected() || setupD2SlipLogic.isSelected()) { 13343 setLogicSlip(d1SlipHead, (TrackSegment) layoutSlip.getConnectB(), d2SlipHead, 13344 (TrackSegment) layoutSlip.getConnectA(), setupD1SlipLogic.isSelected(), 13345 setupD2SlipLogic.isSelected(), layoutSlip, layoutSlip.getTurnoutB(), 13346 layoutSlip.getTurnout(), LayoutTurnout.STATE_BD, LayoutTurnout.STATE_AD, 6); 13347 } 13348 //finish up 13349 setSignalsAtSlipOpenFlag = false; 13350 setSignalsAtSlipFrame.setVisible(false); 13351 13352 if (needRedraw) { 13353 layoutEditor.redrawPanel(); 13354 needRedraw = false; 13355 layoutEditor.setDirty(); 13356 } 13357 } //setSlipSignalsDonePressed 13358 13359 private boolean getSlipSignalHeadInformation() { 13360 a1SlipHead = getSignalHeadFromEntry(a1SlipSignalHeadComboBox, true, setSignalsAtSlipFrame); 13361 if (a1SlipHead == null) { 13362 return false; 13363 } 13364 a2SlipHead = getSignalHeadFromEntry(a2SlipSignalHeadComboBox, false, setSignalsAtSlipFrame); 13365 13366 b1SlipHead = getSignalHeadFromEntry(b1SlipSignalHeadComboBox, true, setSignalsAtSlipFrame); 13367 if (b1SlipHead == null) { 13368 return false; 13369 } 13370 b2SlipHead = getSignalHeadFromEntry(b2SlipSignalHeadComboBox, false, setSignalsAtSlipFrame); 13371 13372 c1SlipHead = getSignalHeadFromEntry(c1SlipSignalHeadComboBox, true, setSignalsAtSlipFrame); 13373 if (c1SlipHead == null) { 13374 return false; 13375 } 13376 c2SlipHead = getSignalHeadFromEntry(c2SlipSignalHeadComboBox, false, setSignalsAtSlipFrame); 13377 13378 d1SlipHead = getSignalHeadFromEntry(d1SlipSignalHeadComboBox, true, setSignalsAtSlipFrame); 13379 if (d1SlipHead == null) { 13380 return false; 13381 } 13382 d2SlipHead = getSignalHeadFromEntry(d2SlipSignalHeadComboBox, false, setSignalsAtSlipFrame); 13383 13384 return true; 13385 } 13386 13387 private void placeA1Slip(String signalHeadName) { 13388 //place head near the continuing track of turnout 1 13389 //placingBlock(getSignalHeadIcon(signalHeadName), false, 0.0, layoutSlip.getConnectA(), layoutSlip.getCoordsA()); 13390 if (testIcon == null) { 13391 testIcon = signalIconEditor.getIcon(0); 13392 } 13393 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13394 13395 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13396 Point2D coordsA = layoutSlipView.getCoordsA(); 13397 Point2D coordsD = layoutSlipView.getCoordsD(); 13398 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13399 13400 double aDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsA, coordsCenter)); 13401 double dDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsCenter)); 13402 double diffDirDEG = MathUtil.diffAngleDEG(aDirDEG, dDirDEG); 13403 double shiftX = 0.0; 13404 if (diffDirDEG < 0.0) { 13405 shiftX -= shift * Math.cos(Math.toRadians(diffDirDEG)); 13406 } 13407 Point2D delta = new Point2D.Double(shiftX, -shift); 13408 13409 delta = MathUtil.rotateDEG(delta, aDirDEG); 13410 Point2D where = MathUtil.add(coordsA, delta); 13411 setSignalHeadOnPanel(aDirDEG, signalHeadName, where); 13412 } 13413 13414 private void placeA2Slip(String signalHeadName) { 13415 //SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 13416 //placingBlock(l, false, (4 + l.getHeight()), layoutSlip.getConnectA(), layoutSlip.getCoordsA()); 13417 if (testIcon == null) { 13418 testIcon = signalIconEditor.getIcon(0); 13419 } 13420 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13421 13422 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13423 Point2D coordsA = layoutSlipView.getCoordsA(); 13424 Point2D coordsD = layoutSlipView.getCoordsD(); 13425 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13426 13427 double aDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsA, coordsCenter)); 13428 double dDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsCenter)); 13429 double diffDirDEG = MathUtil.diffAngleDEG(aDirDEG, dDirDEG); 13430 double shiftX = 2.0 * shift; 13431 if (diffDirDEG < 0.0) { 13432 shiftX -= shift * Math.cos(Math.toRadians(diffDirDEG)); 13433 } 13434 Point2D delta = new Point2D.Double(shiftX, -shift); 13435 13436 delta = MathUtil.rotateDEG(delta, aDirDEG); 13437 Point2D where = MathUtil.add(coordsA, delta); 13438 setSignalHeadOnPanel(aDirDEG, signalHeadName, where); 13439 } 13440 13441 private void placeB1Slip(String signalHeadName) { 13442 //placingBlock(getSignalHeadIcon(signalHeadName), true, 0.0, layoutSlip.getConnectB(), layoutSlip.getCoordsB()); 13443 if (testIcon == null) { 13444 testIcon = signalIconEditor.getIcon(0); 13445 } 13446 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13447 13448 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13449 Point2D coordsB = layoutSlipView.getCoordsB(); 13450 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13451 13452 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 13453 13454 Point2D delta = new Point2D.Double(+shift, -shift); 13455 delta = MathUtil.rotateDEG(delta, bDirDEG); 13456 Point2D where = MathUtil.add(coordsB, delta); 13457 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 13458 } 13459 13460 private void placeB2Slip(String signalHeadName) { 13461 //SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 13462 //placingBlock(l, true, (4 + l.getHeight()), layoutSlip.getConnectB(), layoutSlip.getCoordsB()); 13463 if (testIcon == null) { 13464 testIcon = signalIconEditor.getIcon(0); 13465 } 13466 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13467 13468 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13469 Point2D coordsB = layoutSlipView.getCoordsB(); 13470 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13471 13472 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 13473 13474 Point2D delta = new Point2D.Double(-shift, -shift); 13475 delta = MathUtil.rotateDEG(delta, bDirDEG); 13476 Point2D where = MathUtil.add(coordsB, delta); 13477 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 13478 } 13479 13480 private void placeC1Slip(String signalHeadName) { 13481 //placingBlock(getSignalHeadIcon(signalHeadName), false, 0.0, layoutSlip.getConnectC(), layoutSlip.getCoordsC()); 13482 if (testIcon == null) { 13483 testIcon = signalIconEditor.getIcon(0); 13484 } 13485 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13486 13487 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13488 Point2D coordsB = layoutSlipView.getCoordsB(); 13489 Point2D coordsC = layoutSlipView.getCoordsC(); 13490 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13491 13492 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 13493 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 13494 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 13495 double shiftX = 0.0; 13496 if (diffDirDEG < 0.0) { 13497 shiftX -= shift * Math.cos(Math.toRadians(diffDirDEG)); 13498 } 13499 Point2D delta = new Point2D.Double(shiftX, -shift); 13500 13501 delta = MathUtil.rotateDEG(delta, cDirDEG); 13502 Point2D where = MathUtil.add(coordsC, delta); 13503 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 13504 } 13505 13506 private void placeC2Slip(String signalHeadName) { 13507 //SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 13508 //placingBlock(l, false, (4 + l.getHeight()), layoutSlip.getConnectC(), layoutSlip.getCoordsC()); 13509 if (testIcon == null) { 13510 testIcon = signalIconEditor.getIcon(0); 13511 } 13512 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13513 13514 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13515 Point2D coordsB = layoutSlipView.getCoordsB(); 13516 Point2D coordsC = layoutSlipView.getCoordsC(); 13517 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13518 13519 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 13520 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 13521 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 13522 double shiftX = 2.0 * shift; 13523 if (diffDirDEG < 0.0) { 13524 shiftX -= shift * Math.cos(Math.toRadians(diffDirDEG)); 13525 } 13526 Point2D delta = new Point2D.Double(shiftX, -shift); 13527 13528 delta = MathUtil.rotateDEG(delta, cDirDEG); 13529 Point2D where = MathUtil.add(coordsC, delta); 13530 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 13531 } 13532 13533 private void placeD1Slip(String signalHeadName) { 13534 //placingBlock(getSignalHeadIcon(signalHeadName), true, 0.0, layoutSlip.getConnectD(), layoutSlip.getCoordsD()); 13535 if (testIcon == null) { 13536 testIcon = signalIconEditor.getIcon(0); 13537 } 13538 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13539 13540 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13541 Point2D coordsD = layoutSlipView.getCoordsD(); 13542 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13543 13544 double dDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsCenter)); 13545 13546 Point2D delta = new Point2D.Double(+shift, -shift); 13547 delta = MathUtil.rotateDEG(delta, dDirDEG); 13548 Point2D where = MathUtil.add(coordsD, delta); 13549 setSignalHeadOnPanel(dDirDEG, signalHeadName, where); 13550 } 13551 13552 private void placeD2Slip(String signalHeadName) { 13553 //SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 13554 //placingBlock(l, true, (4 + l.getHeight()), layoutSlip.getConnectD(), layoutSlip.getCoordsD()); 13555 if (testIcon == null) { 13556 testIcon = signalIconEditor.getIcon(0); 13557 } 13558 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13559 13560 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13561 Point2D coordsD = layoutSlipView.getCoordsD(); 13562 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13563 13564 double dDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsCenter)); 13565 13566 Point2D delta = new Point2D.Double(-shift, -shift); 13567 delta = MathUtil.rotateDEG(delta, dDirDEG); 13568 Point2D where = MathUtil.add(coordsD, delta); 13569 setSignalHeadOnPanel(dDirDEG, signalHeadName, where); 13570 } 13571 13572 private void setLogicSlip(SignalHead head, TrackSegment track1, SignalHead secondHead, TrackSegment track2, 13573 boolean setup1, boolean setup2, 13574 LayoutSlip slip, Turnout nearTurnout, Turnout farTurnout, 13575 int continueState, int divergeState, int number) { 13576 //initialize common components and ensure all is defined 13577 LayoutBlock connectorBlock = slip.getLayoutBlock(); 13578 Sensor connectorOccupancy = null; 13579 if (connectorBlock == null) { 13580 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13581 Bundle.getMessage("InfoMessage6"), 13582 Bundle.getMessage("MessageTitle"), 13583 JmriJOptionPane.INFORMATION_MESSAGE); 13584 return; 13585 } 13586 connectorOccupancy = connectorBlock.getOccupancySensor(); 13587 if (connectorOccupancy == null) { 13588 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13589 Bundle.getMessage("InfoMessage4", 13590 new Object[]{connectorBlock.getUserName()}), 13591 Bundle.getMessage("MessageTitle"), 13592 JmriJOptionPane.INFORMATION_MESSAGE); 13593 return; 13594 } 13595 13596 int nearState = layoutSlip.getTurnoutState(nearTurnout, continueState); 13597 int farState = layoutSlip.getTurnoutState(farTurnout, continueState); 13598 13599 //setup signal head for continuing track of far turnout (or both tracks of far turnout) 13600 if ((track1 == null) && setup1) { 13601 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13602 Bundle.getMessage("InfoMessage7"), 13603 Bundle.getMessage("MessageTitle"), 13604 JmriJOptionPane.INFORMATION_MESSAGE); 13605 return; 13606 } 13607 Sensor occupancy = null; 13608 SignalHead nextHead = null; 13609 if ((track1 != null) && setup1) { 13610 LayoutBlock block = track1.getLayoutBlock(); 13611 if (block == null) { 13612 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13613 Bundle.getMessage("InfoMessage6"), 13614 Bundle.getMessage("MessageTitle"), 13615 JmriJOptionPane.INFORMATION_MESSAGE); 13616 return; 13617 } 13618 occupancy = block.getOccupancySensor(); 13619 if (occupancy == null) { 13620 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13621 Bundle.getMessage("InfoMessage4", 13622 new Object[]{block.getUserName()}), 13623 Bundle.getMessage("MessageTitle"), 13624 JmriJOptionPane.INFORMATION_MESSAGE); 13625 return; 13626 } 13627 //need to sort this out??? 13628 nextHead = getNextSignalFromObject(track1, slip, 13629 head.getSystemName(), setSignalsAtSlipFrame); 13630 if ((nextHead == null) && (!reachedEndBumper())) { 13631 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13632 Bundle.getMessage("InfoMessage5", 13633 new Object[]{block.getUserName()}), 13634 Bundle.getMessage("MessageTitle"), 13635 JmriJOptionPane.INFORMATION_MESSAGE); 13636 return; 13637 } 13638 if (secondHead != null) { 13639 //this head signals only the continuing track of the far turnout 13640 if (!initializeBlockBossLogic(head.getDisplayName())) { 13641 return; 13642 } 13643 logic.setMode(BlockBossLogic.TRAILINGMAIN); 13644 if (farState == Turnout.THROWN) { 13645 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 13646 } 13647 logic.setTurnout(farTurnout.getDisplayName()); 13648 logic.setSensor1(occupancy.getDisplayName()); 13649 if (occupancy != connectorOccupancy) { 13650 logic.setSensor2(connectorOccupancy.getDisplayName()); 13651 } 13652 if (nextHead != null) { 13653 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 13654 } 13655 if (auxSignal != null) { 13656 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 13657 } 13658 String nearSensorName = setupNearLogixSlip(nearTurnout, nearState, head, farTurnout, farState, slip, number); 13659 addNearSensorToSlipLogic(nearSensorName); 13660 finalizeBlockBossLogic(); 13661 } 13662 } 13663 if ((secondHead != null) && !setup2) { 13664 return; 13665 } 13666 SignalHead savedAuxSignal = auxSignal; 13667 if (track2 == null) { 13668 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13669 Bundle.getMessage("InfoMessage7"), 13670 Bundle.getMessage("MessageTitle"), 13671 JmriJOptionPane.INFORMATION_MESSAGE); 13672 return; 13673 } 13674 LayoutBlock block2 = track2.getLayoutBlock(); 13675 if (block2 == null) { 13676 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13677 Bundle.getMessage("InfoMessage6"), 13678 Bundle.getMessage("MessageTitle"), 13679 JmriJOptionPane.INFORMATION_MESSAGE); 13680 return; 13681 } 13682 Sensor occupancy2 = block2.getOccupancySensor(); 13683 if (occupancy2 == null) { 13684 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13685 Bundle.getMessage("InfoMessage4", 13686 new Object[]{block2.getUserName()}), 13687 Bundle.getMessage("MessageTitle"), 13688 JmriJOptionPane.INFORMATION_MESSAGE); 13689 return; 13690 } 13691 SignalHead nextHead2 = null; 13692 if (secondHead != null) { 13693 nextHead2 = getNextSignalFromObject(track2, 13694 slip, secondHead.getSystemName(), setSignalsAtSlipFrame); 13695 if ((nextHead2 == null) && (!reachedEndBumper())) { 13696 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13697 Bundle.getMessage("InfoMessage5", 13698 new Object[]{block2.getUserName()}), 13699 Bundle.getMessage("MessageTitle"), 13700 JmriJOptionPane.INFORMATION_MESSAGE); 13701 return; 13702 } 13703 } 13704 if ((secondHead == null) && (track1 != null) && setup1) { 13705 if (!initializeBlockBossLogic(head.getDisplayName())) { 13706 return; 13707 } 13708 logic.setMode(BlockBossLogic.FACING); 13709 logic.setTurnout(farTurnout.getDisplayName()); 13710 if (occupancy != null) { 13711 logic.setWatchedSensor1(occupancy.getDisplayName()); 13712 } 13713 logic.setWatchedSensor2(occupancy2.getDisplayName()); 13714 logic.setSensor2(connectorOccupancy.getDisplayName()); 13715 if (nextHead != null) { 13716 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 13717 } 13718 if (savedAuxSignal != null) { 13719 logic.setWatchedSignal1Alt(savedAuxSignal.getDisplayName()); 13720 } 13721 if (nextHead2 != null) { 13722 logic.setWatchedSignal2(nextHead2.getDisplayName()); 13723 } 13724 if (auxSignal != null) { 13725 logic.setWatchedSignal2Alt(auxSignal.getDisplayName()); 13726 } 13727 String nearSensorName = setupNearLogixSlip(nearTurnout, nearState, head, farTurnout, farState, slip, number + 1); 13728 addNearSensorToSlipLogic(nearSensorName); 13729 logic.setLimitSpeed2(true); 13730 finalizeBlockBossLogic(); 13731 } else if ((secondHead != null) && setup2) { 13732 if (!initializeBlockBossLogic(secondHead.getDisplayName())) { 13733 return; 13734 } 13735 nearState = layoutSlip.getTurnoutState(nearTurnout, divergeState); 13736 farState = layoutSlip.getTurnoutState(farTurnout, divergeState); 13737 13738 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 13739 if (farState == Turnout.CLOSED) { 13740 logic.setMode(BlockBossLogic.TRAILINGMAIN); 13741 logic.setLimitSpeed1(true); 13742 } else { 13743 logic.setLimitSpeed2(true); 13744 } 13745 logic.setTurnout(farTurnout.getDisplayName()); 13746 logic.setSensor1(occupancy2.getDisplayName()); 13747 if (occupancy2 != connectorOccupancy) { 13748 logic.setSensor2(connectorOccupancy.getDisplayName()); 13749 } 13750 if (nextHead2 != null) { 13751 logic.setWatchedSignal1(nextHead2.getDisplayName(), false); 13752 } 13753 if (auxSignal != null) { 13754 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 13755 } 13756 String nearSensorName = setupNearLogixSlip(nearTurnout, nearState, secondHead, farTurnout, farState, slip, number + 1); 13757 addNearSensorToSlipLogic(nearSensorName); 13758 finalizeBlockBossLogic(); 13759 } 13760 } //setLogicSlip 13761 13762 private String setupNearLogixSlip(Turnout turn, int nearState, 13763 SignalHead head, Turnout farTurn, int farState, LayoutSlip slip, int number) { 13764 String turnoutName = turn.getDisplayName(); 13765 String farTurnoutName = farTurn.getDisplayName(); 13766 13767 String logixPrefix = InstanceManager.getDefault(jmri.LogixManager.class).getSystemNamePrefix(); 13768 String pref = InstanceManager.getDefault(jmri.LogixManager.class).getSystemPrefix(); 13769 String logixName = logixPrefix + ":IX_LAYOUTSLIP:" + slip.getId(); 13770 String sensorName = pref + "S:" + logixName + "C" + number; 13771 try { 13772 InstanceManager.sensorManagerInstance().provideSensor(sensorName); 13773 } catch (IllegalArgumentException ex) { 13774 log.error("Trouble creating sensor {} while setting up Logix.", sensorName); 13775 return ""; 13776 } 13777 boolean newConditional = false; 13778 Logix x = InstanceManager.getDefault(LogixManager.class 13779 ).getBySystemName(logixName); 13780 13781 if (x == null) { 13782 x = InstanceManager.getDefault(LogixManager.class 13783 ).createNewLogix(logixName, ""); 13784 newConditional = true; 13785 if (x == null) { 13786 log.error("Trouble creating logix {} while setting up signal logic.", logixName); 13787 return ""; 13788 } 13789 x.setComment("Layout Slip, Signalhead logic"); 13790 } 13791 x.deActivateLogix(); 13792 String cName = logixName + "C" + number; 13793 13794 Conditional c = InstanceManager.getDefault(ConditionalManager.class 13795 ).getBySystemName(cName); 13796 13797 if (c == null) { 13798 c = InstanceManager.getDefault(ConditionalManager.class 13799 ). 13800 createNewConditional(cName, ""); 13801 newConditional = true; 13802 if (c == null) { 13803 log.error("Trouble creating conditional {} while setting up Logix.", cName); 13804 return ""; 13805 } 13806 } 13807 Conditional.Type type = Conditional.Type.TURNOUT_THROWN; 13808 if (nearState == Turnout.CLOSED) { 13809 type = Conditional.Type.TURNOUT_CLOSED; 13810 } 13811 ArrayList<ConditionalVariable> variableList = new ArrayList<>(); 13812 variableList.add(new ConditionalVariable(false, Conditional.Operator.AND, 13813 type, turnoutName, true)); 13814 13815 type = Conditional.Type.TURNOUT_THROWN; 13816 if (farState == Turnout.CLOSED) { 13817 type = Conditional.Type.TURNOUT_CLOSED; 13818 } 13819 variableList.add(new ConditionalVariable(false, Conditional.Operator.AND, 13820 type, farTurnoutName, true)); 13821 c.setStateVariables(variableList); 13822 ArrayList<ConditionalAction> actionList = new ArrayList<>(); 13823 actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE, 13824 Conditional.Action.SET_SENSOR, sensorName, 13825 Sensor.INACTIVE, "")); 13826 actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_FALSE, 13827 Conditional.Action.SET_SENSOR, sensorName, 13828 Sensor.ACTIVE, "")); 13829 c.setAction(actionList); //string data 13830 if (newConditional) { 13831 x.addConditional(cName, -1); 13832 } 13833 x.activateLogix(); 13834 return sensorName; 13835 } //setupNearLogixSlip 13836 13837 /* 13838 * Adds the sensor specified to the open BlockBossLogic, provided it is not already there and 13839 * provided there is an open slot. If 'name' is null or empty, returns without doing anything. 13840 */ 13841 private void addNearSensorToSlipLogic(String name) { 13842 if ((name != null) && !name.isEmpty()) { 13843 //return if a sensor by this name is already present 13844 if (logic.getSensor1() != null && logic.getSensor1().equals(name)) { 13845 return; 13846 } 13847 if (logic.getSensor2() != null && logic.getSensor2().equals(name)) { 13848 return; 13849 } 13850 if (logic.getSensor3() != null && logic.getSensor3().equals(name)) { 13851 return; 13852 } 13853 if (logic.getSensor4() != null && logic.getSensor4().equals(name)) { 13854 return; 13855 } 13856 if (logic.getSensor5() != null && logic.getSensor5().equals(name)) { 13857 return; 13858 } 13859 //add in the first available slot 13860 if (logic.getSensor1() == null) { 13861 logic.setSensor1(name); 13862 } else if (logic.getSensor2() == null) { 13863 logic.setSensor2(name); 13864 } else if (logic.getSensor3() == null) { 13865 logic.setSensor3(name); 13866 } else if (logic.getSensor4() == null) { 13867 logic.setSensor4(name); 13868 } else if (logic.getSensor5() == null) { 13869 logic.setSensor5(name); 13870 } else { 13871 log.error("Error - could not add sensor to SSL for signal head {}", logic.getDrivenSignal()); 13872 } 13873 } 13874 } 13875 13876 /** 13877 * get a signal head icon for the given signal head 13878 * 13879 * @param signalName name of a signal head. 13880 * @return a SignalHeadIcon for the signal. 13881 */ 13882 @CheckReturnValue 13883 public SignalHeadIcon getSignalHeadIcon(@Nonnull String signalName) { 13884 if (signalIconEditor == null) { 13885 signalIconEditor = layoutEditor.getLayoutEditorToolBarPanel().signalIconEditor; 13886 } 13887 SignalHeadIcon l = new SignalHeadIcon(layoutEditor); 13888 l.setSignalHead(signalName); 13889 l.setIcon("SignalHeadStateRed", signalIconEditor.getIcon(0)); 13890 l.setIcon("SignalHeadStateFlashingRed", signalIconEditor.getIcon(1)); 13891 l.setIcon("SignalHeadStateYellow", signalIconEditor.getIcon(2)); 13892 l.setIcon("SignalHeadStateFlashingYellow", signalIconEditor.getIcon(3)); 13893 l.setIcon("SignalHeadStateGreen", signalIconEditor.getIcon(4)); 13894 l.setIcon("SignalHeadStateFlashingGreen", signalIconEditor.getIcon(5)); 13895 l.setIcon("SignalHeadStateDark", signalIconEditor.getIcon(6)); 13896 l.setIcon("SignalHeadStateHeld", signalIconEditor.getIcon(7)); 13897 l.setIcon("SignalHeadStateLunar", signalIconEditor.getIcon(8)); 13898 l.setIcon("SignalHeadStateFlashingLunar", signalIconEditor.getIcon(9)); 13899 l.rotate(90); 13900 return l; 13901 } 13902 13903 //convenience strings 13904 private final String eastString = Bundle.getMessage("East"); 13905 private final String westString = Bundle.getMessage("West"); 13906 private final String continuingString = Bundle.getMessage("Continuing"); 13907 private final String divergingString = Bundle.getMessage("Diverging"); 13908 private final String throatString = Bundle.getMessage("Throat"); 13909 private final String throatContinuingString = Bundle.getMessage("ThroatContinuing"); 13910 private final String throatDivergingString = Bundle.getMessage("ThroatDiverging"); 13911 13912 private final String divergingAString = Bundle.getMessage("Diverging_", "A"); 13913 private final String divergingBString = Bundle.getMessage("Diverging_", "B"); 13914 13915 protected Boolean addLayoutTurnoutSignalHeadInfoToMenu( 13916 @Nonnull String inTurnoutNameA, @Nonnull String inTurnoutNameB, 13917 @Nonnull JMenu inMenu) { 13918 Boolean result = false; //assume failure (pessimist!) 13919 13920 //lookup turnouts 13921 turnout = turnout1 = turnoutA = InstanceManager.turnoutManagerInstance().getTurnout(inTurnoutNameA); 13922 turnout2 = turnoutB = InstanceManager.turnoutManagerInstance().getTurnout(inTurnoutNameB); 13923 //map those to layout turnouts (if possible) 13924 for (LayoutTurnout lt : layoutEditor.getLayoutTurnouts()) { 13925 Turnout to = lt.getTurnout(); 13926 if (to != null) { 13927 String uname = to.getUserName(); 13928 String sname = to.getSystemName(); 13929 if (!inTurnoutNameA.isEmpty() && (sname.equals(inTurnoutNameA) || ((uname != null) && uname.equals(inTurnoutNameA)))) { 13930 layoutTurnout = layoutTurnout1 = layoutTurnoutA = lt; 13931 } 13932 if (!inTurnoutNameB.isEmpty() && (sname.equals(inTurnoutNameB) || ((uname != null) && uname.equals(inTurnoutNameB)))) { 13933 layoutTurnout2 = layoutTurnoutB = lt; 13934 } 13935 } 13936 } 13937 13938 int before_mcc = inMenu.getMenuComponentCount(); 13939 if (before_mcc != 0) { 13940 inMenu.add(new JSeparator()); 13941 } 13942 LayoutTurnout.LinkType linkType = layoutTurnout.getLinkType(); 13943 if ((layoutTurnout.getTurnoutType() == LayoutTurnout.TurnoutType.DOUBLE_XOVER) 13944 || (layoutTurnout.getTurnoutType() == LayoutTurnout.TurnoutType.RH_XOVER) 13945 || (layoutTurnout.getTurnoutType() == LayoutTurnout.TurnoutType.LH_XOVER)) { 13946 JMenuItem jmi = inMenu.add(Bundle.getMessage("Crossover")); 13947 jmi.setEnabled(false); 13948 inMenu.add(new JSeparator()); 13949 before_mcc += 2; 13950 addInfoToMenu("A " + continuingString, layoutTurnout.getSignalA1Name(), inMenu); 13951 addInfoToMenu("A " + divergingString, layoutTurnout.getSignalA2Name(), inMenu); 13952 addInfoToMenu("B " + continuingString, layoutTurnout.getSignalB1Name(), inMenu); 13953 addInfoToMenu("B " + divergingString, layoutTurnout.getSignalB2Name(), inMenu); 13954 addInfoToMenu("C " + continuingString, layoutTurnout.getSignalC1Name(), inMenu); 13955 addInfoToMenu("C " + divergingString, layoutTurnout.getSignalC2Name(), inMenu); 13956 addInfoToMenu("D " + continuingString, layoutTurnout.getSignalD1Name(), inMenu); 13957 addInfoToMenu("D " + divergingString, layoutTurnout.getSignalD2Name(), inMenu); 13958 } else if (linkType == LayoutTurnout.LinkType.NO_LINK) { 13959 JMenuItem jmi = inMenu.add(Bundle.getMessage("BeanNameTurnout")); 13960 jmi.setEnabled(false); 13961 inMenu.add(new JSeparator()); 13962 before_mcc += 2; 13963 addInfoToMenu(throatContinuingString, layoutTurnout.getSignalA1Name(), inMenu); 13964 addInfoToMenu(throatDivergingString, layoutTurnout.getSignalA2Name(), inMenu); 13965 addInfoToMenu(continuingString, layoutTurnout.getSignalB1Name(), inMenu); 13966 addInfoToMenu(divergingString, layoutTurnout.getSignalC1Name(), inMenu); 13967 } else if (linkType == LayoutTurnout.LinkType.THROAT_TO_THROAT) { 13968 String menuString = Bundle.getMessage("ThroatToThroat") + " ("; 13969 menuString += Bundle.getMessage("BeanNameTurnout") + ", " + Bundle.getMessage("BeanNameRoute"); 13970 menuString += ", " + Bundle.getMessage("BeanNameSignalHead") + ":)"; 13971 JMenuItem jmi = inMenu.add(menuString); 13972 jmi.setEnabled(false); 13973 inMenu.add(new JSeparator()); 13974 before_mcc += 2; 13975 addInfoToMenu(eastString + ", " + continuingString + ", " + continuingString, layoutTurnout1.getSignalB1Name(), inMenu); 13976 addInfoToMenu(eastString + ", " + continuingString + ", " + divergingString, layoutTurnout1.getSignalB2Name(), inMenu); 13977 addInfoToMenu(eastString + ", " + divergingString + ", " + continuingString, layoutTurnout1.getSignalC1Name(), inMenu); 13978 addInfoToMenu(eastString + ", " + divergingString + ", " + divergingString, layoutTurnout1.getSignalC2Name(), inMenu); 13979 addInfoToMenu(westString + ", " + continuingString + ", " + continuingString, layoutTurnout2.getSignalB1Name(), inMenu); 13980 addInfoToMenu(westString + ", " + continuingString + ", " + divergingString, layoutTurnout2.getSignalB2Name(), inMenu); 13981 addInfoToMenu(westString + ", " + divergingString + ", " + continuingString, layoutTurnout2.getSignalC1Name(), inMenu); 13982 addInfoToMenu(westString + ", " + divergingString + ", " + divergingString, layoutTurnout2.getSignalC2Name(), inMenu); 13983 } else if (linkType == LayoutTurnout.LinkType.FIRST_3_WAY) { 13984 JMenuItem jmi = inMenu.add(Bundle.getMessage("ThreeWay")); 13985 jmi.setEnabled(false); 13986 inMenu.add(new JSeparator()); 13987 before_mcc += 2; 13988 addInfoToMenu(throatString + " " + continuingString, layoutTurnoutA.getSignalA1Name(), inMenu); 13989 addInfoToMenu(throatString + " " + divergingAString, layoutTurnoutA.getSignalA2Name(), inMenu); 13990 addInfoToMenu(throatString + " " + divergingBString, layoutTurnoutA.getSignalA3Name(), inMenu); 13991 addInfoToMenu(continuingString, layoutTurnoutA.getSignalC1Name(), inMenu); 13992 addInfoToMenu(divergingAString, layoutTurnoutB.getSignalB1Name(), inMenu); 13993 addInfoToMenu(divergingBString, layoutTurnoutB.getSignalC1Name(), inMenu); 13994 } else if (linkType == LayoutTurnout.LinkType.SECOND_3_WAY) { 13995 JMenuItem jmi = inMenu.add(Bundle.getMessage("ThreeWay")); 13996 jmi.setEnabled(false); 13997 inMenu.add(new JSeparator()); 13998 before_mcc += 2; 13999 addInfoToMenu(throatString + " " + continuingString, layoutTurnoutB.getSignalA1Name(), inMenu); 14000 addInfoToMenu(throatString + " " + divergingAString, layoutTurnoutB.getSignalA2Name(), inMenu); 14001 addInfoToMenu(throatString + " " + divergingBString, layoutTurnoutB.getSignalA3Name(), inMenu); 14002 addInfoToMenu(continuingString, layoutTurnoutB.getSignalC1Name(), inMenu); 14003 addInfoToMenu(divergingAString, layoutTurnoutA.getSignalB1Name(), inMenu); 14004 addInfoToMenu(divergingBString, layoutTurnoutA.getSignalC1Name(), inMenu); 14005 } 14006 int after_mcc = inMenu.getMenuComponentCount(); 14007 if (before_mcc != after_mcc) { 14008 inMenu.add(new JSeparator()); 14009 result = true; //it's GOOD! 14010 } 14011 return result; 14012 } //addLayoutTurnoutSignalHeadInfoToMenu 14013 14014 protected Boolean addBlockBoundarySignalHeadInfoToMenu( 14015 @Nonnull PositionablePoint inPositionablePoint, 14016 @Nonnull JMenu inMenu) { 14017 Boolean result = false; //assume failure (pessimist!) 14018 14019 int before_mcc = inMenu.getMenuComponentCount(); 14020 if (before_mcc != 0) { 14021 inMenu.add(new JSeparator()); 14022 } 14023 14024 JMenuItem jmi = inMenu.add(Bundle.getMessage("BlockBoundary")); 14025 jmi.setEnabled(false); 14026 inMenu.add(new JSeparator()); 14027 before_mcc += 2; 14028 14029 addInfoToMenu(Bundle.getMessage("East/SouthBound"), inPositionablePoint.getEastBoundSignal(), inMenu); 14030 addInfoToMenu(Bundle.getMessage("West/NorthBound"), inPositionablePoint.getWestBoundSignal(), inMenu); 14031 14032 int after_mcc = inMenu.getMenuComponentCount(); 14033 if (before_mcc != after_mcc) { 14034 inMenu.add(new JSeparator()); 14035 result = true; //it's GOOD! 14036 } 14037 14038 return result; 14039 } 14040 14041 protected Boolean addLevelXingSignalHeadInfoToMenu( 14042 @Nonnull LevelXing inLevelXing, 14043 @Nonnull JMenu inMenu) { 14044 Boolean result = false; //assume failure (pessimist!) 14045 14046 int before_mcc = inMenu.getMenuComponentCount(); 14047 if (before_mcc != 0) { 14048 inMenu.add(new JSeparator()); 14049 } 14050 14051 JMenuItem jmi = inMenu.add(Bundle.getMessage("LevelCrossing")); 14052 jmi.setEnabled(false); 14053 inMenu.add(new JSeparator()); 14054 before_mcc += 2; 14055 14056 addInfoToMenu(Bundle.getMessage("MakeLabel", 14057 Bundle.getMessage("TrackXConnect", "A")), 14058 inLevelXing.getSignalAName(), inMenu); 14059 addInfoToMenu(Bundle.getMessage("MakeLabel", 14060 Bundle.getMessage("TrackXConnect", "B")), 14061 inLevelXing.getSignalBName(), inMenu); 14062 addInfoToMenu(Bundle.getMessage("MakeLabel", 14063 Bundle.getMessage("TrackXConnect", "C")), 14064 inLevelXing.getSignalCName(), inMenu); 14065 addInfoToMenu(Bundle.getMessage("MakeLabel", 14066 Bundle.getMessage("TrackXConnect", "D")), 14067 inLevelXing.getSignalDName(), inMenu); 14068 14069 int after_mcc = inMenu.getMenuComponentCount(); 14070 if (before_mcc != after_mcc) { 14071 inMenu.add(new JSeparator()); 14072 result = true; //it's GOOD! 14073 } 14074 14075 return result; 14076 } 14077 14078 protected Boolean addLayoutSlipSignalHeadInfoToMenu( 14079 @Nonnull LayoutTurnout inLayoutTurnout, 14080 @Nonnull JMenu inMenu) { 14081 Boolean result = false; //assume failure (pessimist!) 14082 14083 int before_mcc = inMenu.getMenuComponentCount(); 14084 if (before_mcc != 0) { 14085 inMenu.add(new JSeparator()); 14086 } 14087 14088 JMenuItem jmi = inMenu.add(Bundle.getMessage("Slip")); 14089 jmi.setEnabled(false); 14090 inMenu.add(new JSeparator()); 14091 before_mcc += 2; 14092 14093 addInfoToMenu("A " + continuingString, inLayoutTurnout.getSignalA1Name(), inMenu); 14094 addInfoToMenu("A " + divergingString, inLayoutTurnout.getSignalA2Name(), inMenu); 14095 addInfoToMenu("B " + continuingString, inLayoutTurnout.getSignalB1Name(), inMenu); 14096 addInfoToMenu("B " + divergingString, inLayoutTurnout.getSignalB2Name(), inMenu); 14097 addInfoToMenu("C " + continuingString, inLayoutTurnout.getSignalC1Name(), inMenu); 14098 addInfoToMenu("C " + divergingString, inLayoutTurnout.getSignalC2Name(), inMenu); 14099 addInfoToMenu("D " + continuingString, inLayoutTurnout.getSignalD1Name(), inMenu); 14100 addInfoToMenu("D " + divergingString, inLayoutTurnout.getSignalD2Name(), inMenu); 14101 14102 int after_mcc = inMenu.getMenuComponentCount(); 14103 if (before_mcc != after_mcc) { 14104 inMenu.add(new JSeparator()); 14105 result = true; //it's GOOD! 14106 } 14107 14108 return result; 14109 } 14110 14111 private void addInfoToMenu(@CheckForNull String title, 14112 @CheckForNull String info, @Nonnull JMenu menu) { 14113 if ((title != null) && !title.isEmpty() && (info != null) && !info.isEmpty()) { 14114 addInfoToMenu(title + ": " + info, menu); 14115 } 14116 } 14117 14118 private void addInfoToMenu(@CheckForNull String info, @Nonnull JMenu menu) { 14119 if ((info != null) && !info.isEmpty()) { 14120 JMenuItem jmi = new JMenuItem(info); 14121 jmi.setEnabled(false); 14122 menu.add(jmi); 14123 } 14124 } 14125 14126 private void oneFrameToRuleThemAll(@Nonnull JmriJFrame goodFrame) { 14127 setSensorsAtBlockBoundaryFrame = closeIfNotFrame(goodFrame, setSensorsAtBlockBoundaryFrame); 14128 setSensorsAtLevelXingFrame = closeIfNotFrame(goodFrame, setSensorsAtLevelXingFrame); 14129 setSensorsAtSlipFrame = closeIfNotFrame(goodFrame, setSensorsAtSlipFrame); 14130 setSensorsAtTurnoutFrame = closeIfNotFrame(goodFrame, setSensorsAtTurnoutFrame); 14131 setSignalMastsAtBlockBoundaryFrame = closeIfNotFrame(goodFrame, setSignalMastsAtBlockBoundaryFrame); 14132 setSignalMastsAtLayoutSlipFrame = closeIfNotFrame(goodFrame, setSignalMastsAtLayoutSlipFrame); 14133 setSignalMastsAtLevelXingFrame = closeIfNotFrame(goodFrame, setSignalMastsAtLevelXingFrame); 14134 setSignalMastsAtTurnoutFrame = closeIfNotFrame(goodFrame, setSignalMastsAtTurnoutFrame); 14135 setSignalsAt3WayTurnoutFrame = closeIfNotFrame(goodFrame, setSignalsAt3WayTurnoutFrame); 14136 setSignalsAtBlockBoundaryFrame = closeIfNotFrame(goodFrame, setSignalsAtBlockBoundaryFrame); 14137 setSignalsAtLevelXingFrame = closeIfNotFrame(goodFrame, setSignalsAtLevelXingFrame); 14138 setSignalsAtSlipFrame = closeIfNotFrame(goodFrame, setSignalsAtSlipFrame); 14139 setSignalsAtThroatToThroatTurnoutsFrame = closeIfNotFrame(goodFrame, setSignalsAtThroatToThroatTurnoutsFrame); 14140 setSignalsAtTurnoutFrame = closeIfNotFrame(goodFrame, setSignalsAtTurnoutFrame); 14141 setSignalsAtXoverTurnoutFrame = closeIfNotFrame(goodFrame, setSignalsAtXoverTurnoutFrame); 14142 } 14143 14144 private JmriJFrame closeIfNotFrame(@Nonnull JmriJFrame goodFrame, @CheckForNull JmriJFrame badFrame) { 14145 JmriJFrame result = badFrame; 14146 if ((badFrame != null) && (goodFrame != badFrame)) { 14147 badFrame.setVisible(false); 14148 badFrame.dispose(); 14149 result = null; 14150 } 14151 return result; 14152 } 14153 14154 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutEditorTools.class); 14155}