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 */ 043final public 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 } //createListUsedSignalMasts 9698 9699 void refreshSignalMastAtTurnoutComboBox() { 9700 turnoutSignalMastsGetSaved(null); 9701 createListUsedSignalMasts(); 9702 9703 usedMasts.remove(turnoutSignalMastA.getBean()); 9704 usedMasts.remove(turnoutSignalMastB.getBean()); 9705 usedMasts.remove(turnoutSignalMastC.getBean()); 9706 usedMasts.remove(turnoutSignalMastD.getBean()); 9707 9708 turnoutSignalMastA.getCombo().setExcludedItems(usedMasts); 9709 turnoutSignalMastB.getCombo().setExcludedItems(usedMasts); 9710 turnoutSignalMastC.getCombo().setExcludedItems(usedMasts); 9711 turnoutSignalMastD.getCombo().setExcludedItems(usedMasts); 9712 } 9713 9714 private LayoutTurnout.Geometry isMastAssignedHere( 9715 @CheckForNull SignalMast mast, 9716 @CheckForNull LayoutTurnout lTurnout) { 9717 if ((mast == null) || (lTurnout == null)) { 9718 return LayoutTurnout.Geometry.NONE; 9719 } 9720 String sysName = mast.getSystemName(); 9721 String uName = mast.getUserName(); 9722 9723 String name = lTurnout.getSignalAMastName(); 9724 if (!name.isEmpty() && (name.equals(uName) || name.equals(sysName))) { 9725 return LayoutTurnout.Geometry.POINTA1; 9726 } 9727 name = lTurnout.getSignalBMastName(); 9728 if (!name.isEmpty() && (name.equals(uName) || name.equals(sysName))) { 9729 return LayoutTurnout.Geometry.POINTA2; 9730 } 9731 name = lTurnout.getSignalCMastName(); 9732 if (!name.isEmpty() && (name.equals(uName) || name.equals(sysName))) { 9733 return LayoutTurnout.Geometry.POINTA3; 9734 } 9735 name = lTurnout.getSignalDMastName(); 9736 if (!name.isEmpty() && (name.equals(uName) || name.equals(sysName))) { 9737 return LayoutTurnout.Geometry.POINTB1; 9738 } 9739 return LayoutTurnout.Geometry.NONE; 9740 } //isMastAssignedHere 9741 9742 public void removeAssignment(@Nonnull SignalMast mast) { 9743 String sName = mast.getSystemName(); 9744 String uName = mast.getUserName(); 9745 for (LayoutTurnout to : layoutEditor.getLayoutTurnouts()) { 9746 if ((to.getSignalAMastName().equals(sName) || ((uName != null) 9747 && (to.getSignalAMastName().equals(uName))))) { 9748 to.setSignalAMast(""); 9749 } 9750 if ((to.getSignalBMastName().equals(sName) || ((uName != null) 9751 && (to.getSignalBMastName().equals(uName))))) { 9752 to.setSignalBMast(""); 9753 } 9754 if ((to.getSignalCMastName().equals(sName) || ((uName != null) 9755 && (to.getSignalCMastName().equals(uName))))) { 9756 to.setSignalCMast(""); 9757 } 9758 if ((to.getSignalDMastName().equals(sName) || ((uName != null) 9759 && (to.getSignalDMastName().equals(uName))))) { 9760 to.setSignalDMast(""); 9761 } 9762 } 9763 for (PositionablePoint po : layoutEditor.getPositionablePoints()) { 9764 if (po.getEastBoundSignalMastName().equals(sName) || po.getEastBoundSignalMastName().equals(uName)) { 9765 po.setEastBoundSignalMast(""); 9766 } 9767 if (po.getWestBoundSignalMastName().equals(sName) || po.getWestBoundSignalMastName().equals(uName)) { 9768 po.setWestBoundSignalMast(""); 9769 } 9770 } 9771 for (LevelXing x : layoutEditor.getLevelXings()) { 9772 if ( (x.getSignalAMastName().equals(sName) || ((uName != null) 9773 && (x.getSignalAMastName().equals(uName))))) { 9774 x.setSignalAMast(""); 9775 } 9776 if ( (x.getSignalBMastName().equals(sName) || ((uName != null) 9777 && (x.getSignalBMastName().equals(uName))))) { 9778 x.setSignalBMast(""); 9779 } 9780 if ( (x.getSignalCMastName().equals(sName) || ((uName != null) 9781 && (x.getSignalCMastName().equals(uName))))) { 9782 x.setSignalCMast(""); 9783 } 9784 if ( (x.getSignalDMastName().equals(sName) || ((uName != null) 9785 && (x.getSignalDMastName().equals(uName))))) { 9786 x.setSignalDMast(""); 9787 } 9788 } 9789 } //removeAssignment 9790 9791 private boolean getTurnoutMastInformation() { 9792 turnout = null; 9793 layoutTurnout = null; 9794 String str = signalMastsTurnoutComboBox.getSelectedItemDisplayName(); 9795 if ((str == null) || str.isEmpty()) { 9796 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, Bundle.getMessage("SignalsError1") + "qqq", 9797 Bundle.getMessage("ErrorTitle"), 9798 JmriJOptionPane.ERROR_MESSAGE); 9799 return false; 9800 } 9801 turnout = InstanceManager.turnoutManagerInstance().getTurnout(str); 9802 if (turnout == null) { 9803 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9804 Bundle.getMessage("SignalsError2", 9805 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 9806 JmriJOptionPane.ERROR_MESSAGE); 9807 return false; 9808 } else { 9809 String uname = turnout.getUserName(); 9810 if ((uname == null) || uname.isEmpty() 9811 || !uname.equals(str)) { 9812 signalMastsTurnoutComboBox.setSelectedItem(turnout); 9813 } 9814 } 9815 layoutTurnout = layoutEditor.getFinder().findLayoutTurnoutByBean(turnout); 9816 9817 if (layoutTurnout == null) { 9818 JmriJOptionPane.showMessageDialog(setSignalsAtTurnoutFrame, 9819 Bundle.getMessage("SignalsError3", 9820 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 9821 JmriJOptionPane.ERROR_MESSAGE); 9822 return false; 9823 } 9824 return true; 9825 } 9826 9827 public void placingBlock(PositionableIcon icon, boolean isRightSide, 9828 double fromPoint, Object obj, Point2D p) { 9829 if (obj instanceof TrackSegment) { 9830 TrackSegment ts = (TrackSegment) obj; 9831 Point2D endPoint; 9832 if (ts.getConnect1() == layoutTurnout) { 9833 endPoint = layoutEditor.getCoords(ts.getConnect2(), ts.getType2()); 9834 } else { 9835 endPoint = layoutEditor.getCoords(ts.getConnect1(), ts.getType1()); 9836 } 9837 boolean isEast = false; 9838 if (MathUtil.equals(endPoint.getX(), p.getX())) { 9839 log.debug("X in both is the same"); 9840 if (endPoint.getY() < p.getY()) { 9841 log.debug("Y end point is less than our point"); 9842 isEast = true; 9843 } 9844 } else if (endPoint.getX() < p.getX()) { 9845 log.debug("end X point is less than our point"); 9846 isEast = true; 9847 } 9848 9849 log.debug("East set is {}", isEast); 9850 setIconOnPanel(ts, icon, isEast, p, endPoint, isRightSide, fromPoint); 9851 } 9852 } 9853 9854 public void placingBlockForTurntable(PositionableIcon icon, boolean isRightSide, 9855 double fromPoint, Object obj, Point2D p) { 9856 if (obj instanceof TrackSegment) { 9857 TrackSegment ts = (TrackSegment) obj; 9858 Point2D endPoint; 9859 // Determine the "other" end of the track segment by comparing coordinates 9860 // with the passed-in anchor point 'p'. This is more robust than checking object references. 9861 if (MathUtil.distance(layoutEditor.getCoords(ts.getConnect1(), ts.getType1()), p) < 1.0) { 9862 // connect1 is at our anchor point 'p', so the other end is connect2 9863 endPoint = layoutEditor.getCoords(ts.getConnect2(), ts.getType2()); 9864 } else { 9865 // connect2 is at our anchor point 'p', so the other end is connect1 9866 endPoint = layoutEditor.getCoords(ts.getConnect1(), ts.getType1()); 9867 } 9868 boolean isEast = false; 9869 if (MathUtil.equals(endPoint.getX(), p.getX())) { 9870 log.debug("X in both is the same"); 9871 if (endPoint.getY() < p.getY()) { 9872 log.debug("Y end point is less than our point"); 9873 isEast = true; 9874 } 9875 } else if (endPoint.getX() < p.getX()) { 9876 log.debug("end X point is less than our point"); 9877 isEast = true; 9878 } 9879 9880 log.debug("East set is {}", isEast); 9881 setIconOnPanel(ts, icon, isEast, p, endPoint, isRightSide, fromPoint); 9882 } 9883 } 9884 9885 private void setSignalMastsCancelPressed(ActionEvent a) { 9886 setSignalMastsAtTurnoutOpenFlag = false; 9887 setSignalMastsAtTurnoutFrame.setVisible(false); 9888 } 9889 9890 /*============================*\ 9891 |* setSignalMastsAtLayoutSlip *| 9892 \*============================*/ 9893 9894 //operational variables for Set SignalMast at Slip tool 9895 private JmriJFrame setSignalMastsAtLayoutSlipFrame = null; 9896 private boolean setSignalMastsAtLayoutSlipOpenFlag = false; 9897 private boolean setSignalMastsAtLayoutSlipFromMenuFlag = false; 9898 9899 private JButton getSavedSlipSignalMasts = null; 9900 private JButton setSlipSignalMastsDone = null; 9901 private JButton setSlipSignalMastsCancel = null; 9902 9903 private String[] slipBlocks = new String[4]; 9904 9905 private final NamedBeanComboBox<Block> slipSignalBlockAComboBox 9906 = new NamedBeanComboBox<>( 9907 InstanceManager.getDefault(BlockManager.class), 9908 null, DisplayOptions.DISPLAYNAME); 9909 private final NamedBeanComboBox<Block> slipSignalBlockBComboBox 9910 = new NamedBeanComboBox<>( 9911 InstanceManager.getDefault(BlockManager.class), 9912 null, DisplayOptions.DISPLAYNAME); 9913 private final NamedBeanComboBox<Block> slipSignalBlockCComboBox 9914 = new NamedBeanComboBox<>( 9915 InstanceManager.getDefault(BlockManager.class), 9916 null, DisplayOptions.DISPLAYNAME); 9917 private final NamedBeanComboBox<Block> slipSignalBlockDComboBox 9918 = new NamedBeanComboBox<>( 9919 InstanceManager.getDefault(BlockManager.class), 9920 null, DisplayOptions.DISPLAYNAME); 9921 9922 private JLabel slipSignalBlockANameLabel = null; 9923 private JLabel slipSignalBlockBNameLabel = null; 9924 private JLabel slipSignalBlockCNameLabel = null; 9925 private JLabel slipSignalBlockDNameLabel = null; 9926 9927 BeanDetails<SignalMast> slipSignalMastA; 9928 BeanDetails<SignalMast> slipSignalMastB; 9929 BeanDetails<SignalMast> slipSignalMastC; 9930 BeanDetails<SignalMast> slipSignalMastD; 9931 9932 JPanel signalMastLayoutSlipPanel = new JPanel(new FlowLayout()); 9933 9934 public void setSignalMastsAtSlipFromMenu(@Nonnull LayoutSlip slip, 9935 @Nonnull String[] blocks, @Nonnull JFrame theFrame) { 9936 layoutSlip = slip; 9937 layoutTurnout = slip; 9938 9939 BlockManager bm = InstanceManager.getDefault(BlockManager.class); 9940 slipSignalBlockAComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockName())); 9941 slipSignalBlockBComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockBName())); 9942 slipSignalBlockCComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockCName())); 9943 slipSignalBlockDComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockDName())); 9944 9945 slipBlocks = new String[4]; 9946 for (int i = 0; i < blocks.length; i++) { 9947 slipBlocks[i] = blocks[i]; 9948 } 9949 setSignalMastsAtLayoutSlipFromMenuFlag = true; 9950 setSignalMastsAtLayoutSlip(theFrame); 9951 } 9952 9953 //TODO: Add to Tools menu? 9954 public void setSignalMastsAtLayoutSlip(@Nonnull JFrame theFrame) { 9955 signalFrame = theFrame; 9956 9957 //Initialize if needed 9958 if (setSignalMastsAtLayoutSlipFrame == null) { 9959 setSignalMastsAtLayoutSlipOpenFlag = false; 9960 9961 slipSignalMastA = new BeanDetails<>("SignalMast", 9962 InstanceManager.getDefault(SignalMastManager.class)); 9963 slipSignalMastB = new BeanDetails<>("SignalMast", 9964 InstanceManager.getDefault(SignalMastManager.class)); 9965 slipSignalMastC = new BeanDetails<>("SignalMast", 9966 InstanceManager.getDefault(SignalMastManager.class)); 9967 slipSignalMastD = new BeanDetails<>("SignalMast", 9968 InstanceManager.getDefault(SignalMastManager.class)); 9969 9970 slipSignalMastA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 9971 slipSignalMastB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 9972 slipSignalMastC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 9973 slipSignalMastD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 9974 9975 setSignalMastsAtLayoutSlipFrame = new JmriJFrame(Bundle.getMessage("SignalMastsAtLayoutSlip"), false, true); 9976 oneFrameToRuleThemAll(setSignalMastsAtLayoutSlipFrame); 9977 setSignalMastsAtLayoutSlipFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 9978// setSignalMastsAtLayoutSlipFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtLayoutSlip", true); 9979 setSignalMastsAtLayoutSlipFrame.setLocation(70, 30); 9980 Container theContentPane = setSignalMastsAtLayoutSlipFrame.getContentPane(); 9981 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 9982 9983 JPanel panel11A = new JPanel(new FlowLayout()); 9984//note: this is just placeholder text; real text is set below 9985 slipSignalBlockANameLabel = new JLabel(" A "); 9986 panel11A.add(slipSignalBlockANameLabel); 9987 panel11A.add(slipSignalBlockAComboBox); 9988 slipSignalBlockAComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 9989 theContentPane.add(panel11A); 9990 9991 JPanel panel11B = new JPanel(new FlowLayout()); 9992//note: this is just placeholder text; real text is set below 9993 slipSignalBlockBNameLabel = new JLabel(" B "); 9994 panel11B.add(slipSignalBlockBNameLabel); 9995 panel11B.add(slipSignalBlockBComboBox); 9996 slipSignalBlockBComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 9997 theContentPane.add(panel11B); 9998 9999 JPanel panel11C = new JPanel(new FlowLayout()); 10000//note: this is just placeholder text; real text is set below 10001 slipSignalBlockCNameLabel = new JLabel(" C "); 10002 panel11C.add(slipSignalBlockCNameLabel); 10003 panel11C.add(slipSignalBlockCComboBox); 10004 slipSignalBlockCComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10005 theContentPane.add(panel11C); 10006 10007 JPanel panel11D = new JPanel(new FlowLayout()); 10008//note: this is just placeholder text; real text is set below 10009 slipSignalBlockDNameLabel = new JLabel(" D "); 10010 panel11D.add(slipSignalBlockDNameLabel); 10011 panel11D.add(slipSignalBlockDComboBox); 10012 slipSignalBlockDComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10013 theContentPane.add(panel11D); 10014 10015 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 10016 10017 JPanel panel2 = new JPanel(new FlowLayout()); 10018 JLabel shTitle = new JLabel(Bundle.getMessage("BeanNameSignalMast")); 10019 panel2.add(shTitle); 10020 panel2.add(new JLabel(" ")); 10021 panel2.add(getSavedSlipSignalMasts = new JButton(Bundle.getMessage("GetSaved"))); 10022 getSavedSlipSignalMasts.addActionListener(this::slipSignalMastsGetSaved); 10023 getSavedSlipSignalMasts.setToolTipText(Bundle.getMessage("GetSavedHint")); 10024 theContentPane.add(panel2); 10025 10026 signalMastLayoutSlipPanel.setLayout(new GridLayout(0, 2)); 10027 theContentPane.add(signalMastLayoutSlipPanel); 10028 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 10029 10030 JPanel panel6 = new JPanel(new FlowLayout()); 10031 10032 panel6.add(new JLabel(" ")); 10033 panel6.add(setSlipSignalMastsDone = new JButton(Bundle.getMessage("ButtonDone"))); 10034 setSlipSignalMastsDone.addActionListener(this::setSlipSignalMastsDonePressed); 10035 setSlipSignalMastsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 10036 panel6.add(setSlipSignalMastsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 10037 setSlipSignalMastsCancel.addActionListener(this::setSlipSignalMastsCancelPressed); 10038 setSlipSignalMastsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 10039 theContentPane.add(panel6); 10040 setSignalMastsAtLayoutSlipFrame.addWindowListener(new WindowAdapter() { 10041 @Override 10042 public void windowClosing(WindowEvent e) { 10043 setSlipSignalMastsCancelPressed(null); 10044 } 10045 }); 10046 } 10047 10048 //Unhide any excluded masts 10049 slipSignalMastA.getCombo().setExcludedItems(new HashSet<>()); 10050 slipSignalMastB.getCombo().setExcludedItems(new HashSet<>()); 10051 slipSignalMastC.getCombo().setExcludedItems(new HashSet<>()); 10052 slipSignalMastD.getCombo().setExcludedItems(new HashSet<>()); 10053 signalMastLayoutSlipPanel.removeAll(); 10054 10055 slipSignalBlockAComboBox.setVisible(!setSignalMastsAtLayoutSlipFromMenuFlag); 10056 slipSignalBlockBComboBox.setVisible(!setSignalMastsAtLayoutSlipFromMenuFlag); 10057 slipSignalBlockCComboBox.setVisible(!setSignalMastsAtLayoutSlipFromMenuFlag); 10058 slipSignalBlockDComboBox.setVisible(!setSignalMastsAtLayoutSlipFromMenuFlag); 10059 10060 if (setSignalMastsAtLayoutSlipFromMenuFlag) { 10061 slipSignalBlockANameLabel.setText(Bundle.getMessage("MakeLabel", 10062 Bundle.getMessage("BeanNameBlock") + " A " 10063 + Bundle.getMessage("Name")) 10064 + " " + layoutSlip.getBlockName()); 10065 slipSignalBlockBNameLabel.setText(Bundle.getMessage("MakeLabel", 10066 Bundle.getMessage("BeanNameBlock") + " B " 10067 + Bundle.getMessage("Name")) 10068 + " " + layoutSlip.getBlockBName()); 10069 slipSignalBlockCNameLabel.setText(Bundle.getMessage("MakeLabel", 10070 Bundle.getMessage("BeanNameBlock") + " C " 10071 + Bundle.getMessage("Name")) 10072 + " " + layoutSlip.getBlockCName()); 10073 slipSignalBlockDNameLabel.setText(Bundle.getMessage("MakeLabel", 10074 Bundle.getMessage("BeanNameBlock") + " D " 10075 + Bundle.getMessage("Name")) 10076 + " " + layoutSlip.getBlockDName()); 10077 refreshSignalMastAtSlipComboBox(); 10078 } else { 10079 slipSignalBlockANameLabel.setText(Bundle.getMessage("MakeLabel", 10080 Bundle.getMessage("BeanNameBlock") + " A " 10081 + Bundle.getMessage("Name"))); 10082 slipSignalBlockBNameLabel.setText(Bundle.getMessage("MakeLabel", 10083 Bundle.getMessage("BeanNameBlock") + " B " 10084 + Bundle.getMessage("Name"))); 10085 slipSignalBlockCNameLabel.setText(Bundle.getMessage("MakeLabel", 10086 Bundle.getMessage("BeanNameBlock") + " C " 10087 + Bundle.getMessage("Name"))); 10088 slipSignalBlockDNameLabel.setText(Bundle.getMessage("MakeLabel", 10089 Bundle.getMessage("BeanNameBlock") + " D " 10090 + Bundle.getMessage("Name"))); 10091 } 10092 10093 if (!setSignalMastsAtLayoutSlipOpenFlag) { 10094 setSignalMastsAtLayoutSlipFrame.setPreferredSize(null); 10095 setSignalMastsAtLayoutSlipFrame.pack(); 10096 setSignalMastsAtLayoutSlipOpenFlag = true; 10097 } 10098 setSignalMastsAtLayoutSlipFrame.setVisible(true); 10099 } 10100 10101 void refreshSignalMastAtSlipComboBox() { 10102 slipSignalMastsGetSaved(null); 10103 createListUsedSignalMasts(); 10104 10105 usedMasts.remove(slipSignalMastA.getBean()); 10106 usedMasts.remove(slipSignalMastB.getBean()); 10107 usedMasts.remove(slipSignalMastC.getBean()); 10108 usedMasts.remove(slipSignalMastD.getBean()); 10109 10110 slipSignalMastA.getCombo().setExcludedItems(usedMasts); 10111 slipSignalMastB.getCombo().setExcludedItems(usedMasts); 10112 slipSignalMastC.getCombo().setExcludedItems(usedMasts); 10113 slipSignalMastD.getCombo().setExcludedItems(usedMasts); 10114 } 10115 10116 private void slipSignalMastsGetSaved(ActionEvent a) { 10117 if (!getSlipMastInformation()) { 10118 return; 10119 } 10120 slipBlocks = layoutSlip.getBlockBoundaries(); 10121 10122 slipSignalMastA.setTextField(layoutSlip.getSignalAMastName()); 10123 slipSignalMastB.setTextField(layoutSlip.getSignalBMastName()); 10124 slipSignalMastC.setTextField(layoutSlip.getSignalCMastName()); 10125 slipSignalMastD.setTextField(layoutSlip.getSignalDMastName()); 10126 10127 slipSignalMastA.setBoundaryLabel(slipBlocks[0]); 10128 slipSignalMastB.setBoundaryLabel(slipBlocks[1]); 10129 slipSignalMastC.setBoundaryLabel(slipBlocks[2]); 10130 slipSignalMastD.setBoundaryLabel(slipBlocks[3]); 10131 10132 boolean boundaryFlag = false; 10133 signalMastLayoutSlipPanel.remove(slipSignalMastA.getDetailsPanel()); 10134 signalMastLayoutSlipPanel.remove(slipSignalMastB.getDetailsPanel()); 10135 signalMastLayoutSlipPanel.remove(slipSignalMastC.getDetailsPanel()); 10136 signalMastLayoutSlipPanel.remove(slipSignalMastD.getDetailsPanel()); 10137 if (slipBlocks[0] != null) { 10138 signalMastLayoutSlipPanel.add(slipSignalMastA.getDetailsPanel()); 10139 boundaryFlag = true; 10140 } 10141 if (slipBlocks[1] != null) { 10142 signalMastLayoutSlipPanel.add(slipSignalMastB.getDetailsPanel()); 10143 boundaryFlag = true; 10144 } 10145 if (slipBlocks[2] != null) { 10146 signalMastLayoutSlipPanel.add(slipSignalMastC.getDetailsPanel()); 10147 boundaryFlag = true; 10148 } 10149 if (slipBlocks[3] != null) { 10150 signalMastLayoutSlipPanel.add(slipSignalMastD.getDetailsPanel()); 10151 boundaryFlag = true; 10152 } 10153 if (!boundaryFlag) { 10154 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, "There are no block boundaries on this level crossing\nIt is therefore not possible to add Signal Masts to it"); 10155 } 10156 setSignalMastsAtLayoutSlipFrame.setPreferredSize(null); 10157 setSignalMastsAtLayoutSlipFrame.pack(); 10158 } 10159 10160 private boolean getSlipMastInformation() { 10161 if (!setSignalMastsAtLayoutSlipFromMenuFlag) { 10162 layoutSlip = null; 10163 List<LayoutSlip> layoutSlips = layoutEditor.getLayoutSlips(); 10164 if (layoutSlips.size() <= 0) { 10165 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10166 Bundle.getMessage("SignalsError15"), 10167 Bundle.getMessage("ErrorTitle"), 10168 JmriJOptionPane.ERROR_MESSAGE); 10169 return false; 10170 } else if (layoutSlips.size() == 1) { 10171 layoutSlip = layoutSlips.get(0); 10172 } else { 10173 LayoutBlock slipBlockA = null; 10174 //LayoutBlock slipBlockC = null; 10175 slipBlockA = getBlockFromEntry(xingBlockACComboBox); 10176 if (slipBlockA == null) { 10177 return false; 10178 } 10179 10180 int foundCount = 0; 10181 //make two block tests first 10182 for (LayoutSlip x : layoutEditor.getLayoutSlips()) { 10183 LayoutBlock xA = null; 10184 LayoutBlock xB = null; 10185 LayoutBlock xC = null; 10186 LayoutBlock xD = null; 10187 10188 LayoutBlock xAC = x.getLayoutBlock(); 10189 if (x.getConnectA() != null) { 10190 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 10191 } 10192 if (x.getConnectB() != null) { 10193 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 10194 } 10195 if (x.getConnectC() != null) { 10196 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 10197 } 10198 if (x.getConnectD() != null) { 10199 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 10200 } 10201 if (((xA != null) && (xC != null) && ((xA == slipBlockA) 10202 || (xC == slipBlockA))) 10203 || ((xB != null) && (xD != null) && ((xB == slipBlockA) 10204 || (xD == slipBlockA)))) { 10205 layoutSlip = x; 10206 foundCount++; 10207 } else if ((xAC != null) && (xAC == slipBlockA)) { 10208 layoutSlip = x; 10209 foundCount++; 10210 } 10211 } 10212 if (foundCount == 0) { 10213 //try one block test 10214 for (LayoutSlip x : layoutEditor.getLayoutSlips()) { 10215 if (slipBlockA == x.getLayoutBlock()) { 10216 layoutSlip = x; 10217 foundCount++; 10218 } 10219 } 10220 } 10221 if (foundCount > 1) { 10222 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10223 Bundle.getMessage("SignalsError16", 10224 new Object[]{" " + foundCount + " "}), 10225 Bundle.getMessage("ErrorTitle"), 10226 JmriJOptionPane.ERROR_MESSAGE); 10227 return false; 10228 } 10229 if (layoutSlip == null) { 10230 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10231 Bundle.getMessage("SignalsError17"), 10232 Bundle.getMessage("ErrorTitle"), 10233 JmriJOptionPane.ERROR_MESSAGE); 10234 return false; 10235 } 10236 } 10237 } 10238 return true; 10239 } 10240 10241 private void setSlipSignalMastsCancelPressed(ActionEvent a) { 10242 setSignalMastsAtLayoutSlipOpenFlag = false; 10243 setSignalMastsAtLayoutSlipFrame.setVisible(false); 10244 } 10245 10246 private void setSlipSignalMastsDonePressed(ActionEvent a) { 10247 if (!getSlipMastInformation()) { 10248 return; 10249 } 10250 10251 SignalMast aMast = getSignalMastFromEntry(slipSignalMastA.getText(), false, setSignalMastsAtLayoutSlipFrame); 10252 SignalMast bMast = getSignalMastFromEntry(slipSignalMastB.getText(), false, setSignalMastsAtLayoutSlipFrame); 10253 SignalMast cMast = getSignalMastFromEntry(slipSignalMastC.getText(), false, setSignalMastsAtLayoutSlipFrame); 10254 SignalMast dMast = getSignalMastFromEntry(slipSignalMastD.getText(), false, setSignalMastsAtLayoutSlipFrame); 10255 10256 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 10257 10258 //place or update signals as requested 10259 if ((aMast != null) && slipSignalMastA.addToPanel()) { 10260 if (isSignalMastOnPanel(aMast) 10261 && (aMast != layoutSlip.getSignalAMast())) { 10262 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10263 Bundle.getMessage("SignalMastsError6", 10264 new Object[]{slipSignalMastA.getText()}), 10265 Bundle.getMessage("ErrorTitle"), 10266 JmriJOptionPane.ERROR_MESSAGE); 10267 return; 10268 } else { 10269 removeSignalMastFromPanel(layoutSlip.getSignalAMast()); 10270 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10271 l.setSignalMast(slipSignalMastA.getText()); 10272 placingBlock(l, slipSignalMastA.isRightSelected(), 10273 0.0, layoutSlip.getConnectA(), layoutSlipView.getCoordsA()); 10274 removeAssignment(aMast); 10275 layoutSlip.setSignalAMast(slipSignalMastA.getText()); 10276 needRedraw = true; 10277 } 10278 } else if ((aMast != null) 10279 && (aMast != layoutSlip.getSignalAMast()) 10280 && (aMast != layoutSlip.getSignalBMast()) 10281 && (aMast != layoutSlip.getSignalCMast()) 10282 && (aMast != layoutSlip.getSignalDMast())) { 10283 if (isSignalMastOnPanel(aMast)) { 10284 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10285 Bundle.getMessage("SignalMastsError13", 10286 new Object[]{slipSignalMastA.getText()}), 10287 Bundle.getMessage("ErrorTitle"), 10288 JmriJOptionPane.ERROR_MESSAGE); 10289 return; 10290 } else { 10291 removeSignalMastFromPanel(layoutSlip.getSignalAMast()); 10292 removeAssignment(aMast); 10293 layoutSlip.setSignalAMast(slipSignalMastA.getText()); 10294 } 10295 } else if ((aMast != null) 10296 && ((aMast == layoutSlip.getSignalBMast()) 10297 || (aMast == layoutSlip.getSignalCMast()) 10298 || (aMast == layoutSlip.getSignalDMast()))) { 10299 //need to figure out what to do in this case. 10300 log.trace("need to figure out what to do in this case."); 10301 } else if (aMast == null) { 10302 removeSignalMastFromPanel(layoutSlip.getSignalAMast()); 10303 layoutSlip.setSignalAMast(""); 10304 } 10305 if ((bMast != null) && slipSignalMastB.addToPanel()) { 10306 if (isSignalMastOnPanel(bMast) 10307 && (bMast != layoutSlip.getSignalBMast())) { 10308 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10309 Bundle.getMessage("SignalMastsError6", 10310 new Object[]{slipSignalMastB.getText()}), 10311 Bundle.getMessage("ErrorTitle"), 10312 JmriJOptionPane.ERROR_MESSAGE); 10313 return; 10314 } else { 10315 removeSignalMastFromPanel(layoutSlip.getSignalBMast()); 10316 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10317 l.setSignalMast(slipSignalMastB.getText()); 10318 placingBlock(l, slipSignalMastB.isRightSelected(), 10319 0.0, layoutSlip.getConnectB(), layoutSlipView.getCoordsB()); 10320 removeAssignment(bMast); 10321 layoutSlip.setSignalBMast(slipSignalMastB.getText()); 10322 needRedraw = true; 10323 } 10324 } else if ((bMast != null) 10325 && (bMast != layoutSlip.getSignalAMast()) 10326 && (bMast != layoutSlip.getSignalBMast()) 10327 && (bMast != layoutSlip.getSignalCMast()) 10328 && (bMast != layoutSlip.getSignalDMast())) { 10329 if (isSignalMastOnPanel(bMast)) { 10330 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10331 Bundle.getMessage("SignalMastsError13", 10332 new Object[]{slipSignalMastB.getText()}), 10333 Bundle.getMessage("ErrorTitle"), 10334 JmriJOptionPane.ERROR_MESSAGE); 10335 return; 10336 } else { 10337 removeSignalMastFromPanel(layoutSlip.getSignalBMast()); 10338 removeAssignment(bMast); 10339 layoutSlip.setSignalBMast(slipSignalMastB.getText()); 10340 } 10341 } else if ((bMast != null) 10342 && ((bMast == layoutSlip.getSignalAMast()) 10343 || (bMast == layoutSlip.getSignalCMast()) 10344 || (bMast == layoutSlip.getSignalDMast()))) { 10345 //need to figure out what to do in this case. 10346 log.trace("need to figure out what to do in this case."); 10347 } else if (bMast == null) { 10348 removeSignalMastFromPanel(layoutSlip.getSignalBMast()); 10349 layoutSlip.setSignalBMast(""); 10350 } 10351 if ((cMast != null) && slipSignalMastC.addToPanel()) { 10352 if (isSignalMastOnPanel(cMast) 10353 && (cMast != layoutSlip.getSignalCMast())) { 10354 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10355 Bundle.getMessage("SignalMastsError6", 10356 new Object[]{slipSignalMastC.getText()}), 10357 Bundle.getMessage("ErrorTitle"), 10358 JmriJOptionPane.ERROR_MESSAGE); 10359 return; 10360 } else { 10361 removeSignalMastFromPanel(layoutSlip.getSignalCMast()); 10362 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10363 l.setSignalMast(slipSignalMastC.getText()); 10364 placingBlock(l, slipSignalMastA.isRightSelected(), 10365 0.0, layoutSlip.getConnectC(), layoutSlipView.getCoordsC()); 10366 removeAssignment(cMast); 10367 layoutSlip.setSignalCMast(slipSignalMastC.getText()); 10368 needRedraw = true; 10369 } 10370 } else if ((cMast != null) 10371 && (cMast != layoutSlip.getSignalAMast()) 10372 && (cMast != layoutSlip.getSignalBMast()) 10373 && (cMast != layoutSlip.getSignalCMast()) 10374 && (cMast != layoutSlip.getSignalDMast())) { 10375 if (isSignalMastOnPanel(cMast)) { 10376 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10377 Bundle.getMessage("SignalMastsError13", 10378 new Object[]{slipSignalMastC.getText()}), 10379 Bundle.getMessage("ErrorTitle"), 10380 JmriJOptionPane.ERROR_MESSAGE); 10381 return; 10382 } else { 10383 removeSignalMastFromPanel(layoutSlip.getSignalCMast()); 10384 removeAssignment(cMast); 10385 layoutSlip.setSignalCMast(slipSignalMastC.getText()); 10386 } 10387 } else if ((cMast != null) 10388 && ((cMast == layoutSlip.getSignalBMast()) 10389 || (cMast == layoutSlip.getSignalAMast()) 10390 || (cMast == layoutSlip.getSignalDMast()))) { 10391 //need to figure out what to do in this case. 10392 log.trace("need to figure out what to do in this case."); 10393 } else if (cMast == null) { 10394 removeSignalMastFromPanel(layoutSlip.getSignalCMast()); 10395 layoutSlip.setSignalCMast(""); 10396 } 10397 if ((dMast != null) && slipSignalMastD.addToPanel()) { 10398 if (isSignalMastOnPanel(dMast) 10399 && (dMast != layoutSlip.getSignalDMast())) { 10400 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10401 Bundle.getMessage("SignalMastsError6", 10402 new Object[]{slipSignalMastD.getText()}), 10403 Bundle.getMessage("ErrorTitle"), 10404 JmriJOptionPane.ERROR_MESSAGE); 10405 return; 10406 } else { 10407 removeSignalMastFromPanel(layoutSlip.getSignalDMast()); 10408 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10409 l.setSignalMast(slipSignalMastD.getText()); 10410 placingBlock(l, slipSignalMastD.isRightSelected(), 10411 0.0, layoutSlip.getConnectD(), layoutSlipView.getCoordsD()); 10412 removeAssignment(dMast); 10413 layoutSlip.setSignalDMast(slipSignalMastD.getText()); 10414 needRedraw = true; 10415 } 10416 } else if ((dMast != null) 10417 && (dMast != layoutSlip.getSignalAMast()) 10418 && (dMast != layoutSlip.getSignalBMast()) 10419 && (dMast != layoutSlip.getSignalCMast()) 10420 && (dMast != layoutSlip.getSignalDMast())) { 10421 if (isSignalMastOnPanel(dMast)) { 10422 JmriJOptionPane.showMessageDialog(setSignalMastsAtLayoutSlipFrame, 10423 Bundle.getMessage("SignalMastsError13", 10424 new Object[]{slipSignalMastD.getText()}), 10425 Bundle.getMessage("ErrorTitle"), 10426 JmriJOptionPane.ERROR_MESSAGE); 10427 return; 10428 } else { 10429 removeSignalMastFromPanel(layoutSlip.getSignalDMast()); 10430 removeAssignment(dMast); 10431 layoutSlip.setSignalDMast(slipSignalMastD.getText()); 10432 } 10433 } else if ((dMast != null) 10434 && ((dMast == layoutSlip.getSignalBMast()) 10435 || (dMast == layoutSlip.getSignalCMast()) 10436 || (dMast == layoutSlip.getSignalAMast()))) { 10437 //need to figure out what to do in this case. 10438 log.trace("need to figure out what to do in this case."); 10439 } else if (dMast == null) { 10440 removeSignalMastFromPanel(layoutSlip.getSignalDMast()); 10441 layoutSlip.setSignalDMast(""); 10442 } 10443 //setup logic if requested 10444 //finish up 10445 setSignalMastsAtLayoutSlipOpenFlag = false; 10446 setSignalMastsAtLayoutSlipFrame.setVisible(false); 10447 if (needRedraw) { 10448 layoutEditor.redrawPanel(); 10449 needRedraw = false; 10450 layoutEditor.setDirty(); 10451 } 10452 } 10453 10454 /*===========================*\ 10455 |* setSignalMastsAtLevelXing *| 10456 \*===========================*/ 10457 //operational variables for Set SignalMast at Level Crossing tool 10458 private JmriJFrame setSignalMastsAtLevelXingFrame = null; 10459 private boolean setSignalMastsAtLevelXingOpenFlag = false; 10460 private boolean setSignalMastsAtLevelXingFromMenuFlag = false; 10461 10462 private JLabel xingSignalBlockACNameLabel = null; 10463 private JLabel xingSignalBlockBDNameLabel = null; 10464 10465 private final NamedBeanComboBox<Block> xingBlockACComboBox = new NamedBeanComboBox<>( 10466 InstanceManager.getDefault(BlockManager.class), 10467 null, DisplayOptions.DISPLAYNAME); 10468 private final NamedBeanComboBox<Block> xingBlockBDComboBox = new NamedBeanComboBox<>( 10469 InstanceManager.getDefault(BlockManager.class), 10470 null, DisplayOptions.DISPLAYNAME); 10471 10472 private JButton getSavedXingSignalMasts = null; 10473 private JButton setXingSignalMastsDone = null; 10474 private JButton setXingSignalMastsCancel = null; 10475 10476 private String[] xingBlocks = new String[4]; 10477 10478 BeanDetails<SignalMast> xingSignalMastA; 10479 BeanDetails<SignalMast> xingSignalMastB; 10480 BeanDetails<SignalMast> xingSignalMastC; 10481 BeanDetails<SignalMast> xingSignalMastD; 10482 10483 JPanel signalMastLevelXingPanel = new JPanel(new FlowLayout()); 10484 10485 Border blackline = BorderFactory.createLineBorder(Color.black); 10486 10487 //display dialog for Set Signals at Level Crossing tool 10488 public void setSignalMastsAtLevelXingFromMenu(@Nonnull LevelXing xing, 10489 @Nonnull String[] blocks, 10490 @Nonnull JFrame theFrame) { 10491 levelXing = xing; 10492 BlockManager bm = InstanceManager.getDefault(BlockManager.class); 10493 xingBlockACComboBox.setSelectedItem(bm.getBlock(levelXing.getBlockNameAC())); 10494 xingBlockBDComboBox.setSelectedItem(bm.getBlock(levelXing.getBlockNameBD())); 10495 xingBlocks = new String[4]; 10496 for (int i = 0; i < blocks.length; i++) { 10497 xingBlocks[i] = blocks[i]; 10498 } 10499 setSignalMastsAtLevelXingFromMenuFlag = true; 10500 setSignalMastsAtLevelXing(theFrame); 10501 setSignalMastsAtLevelXingFromMenuFlag = false; 10502 } 10503 10504 //TODO: Add to Tools menu? 10505 public void setSignalMastsAtLevelXing(@Nonnull JFrame theFrame) { 10506 signalFrame = theFrame; 10507 10508 //Initialize if needed 10509 if (setSignalMastsAtLevelXingFrame == null) { 10510 setSignalMastsAtLevelXingOpenFlag = false; 10511 10512 xingSignalMastA = new BeanDetails<>("SignalMast", 10513 InstanceManager.getDefault(SignalMastManager.class 10514 )); 10515 xingSignalMastB = new BeanDetails<>("SignalMast", 10516 InstanceManager.getDefault(SignalMastManager.class 10517 )); 10518 xingSignalMastC = new BeanDetails<>("SignalMast", 10519 InstanceManager.getDefault(SignalMastManager.class 10520 )); 10521 xingSignalMastD = new BeanDetails<>("SignalMast", 10522 InstanceManager.getDefault(SignalMastManager.class 10523 )); 10524 10525 xingSignalMastA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 10526 xingSignalMastB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 10527 xingSignalMastC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 10528 xingSignalMastD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 10529 10530 setSignalMastsAtLevelXingFrame = new JmriJFrame(Bundle.getMessage("SignalMastsAtLevelXing"), false, true); 10531 oneFrameToRuleThemAll(setSignalMastsAtLevelXingFrame); 10532 setSignalMastsAtLevelXingFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 10533 setSignalMastsAtLevelXingFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtLevelXing", true); 10534 setSignalMastsAtLevelXingFrame.setLocation(70, 30); 10535 Container theContentPane = setSignalMastsAtLevelXingFrame.getContentPane(); 10536 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 10537 10538 JPanel panel11 = new JPanel(new FlowLayout()); 10539 xingSignalBlockACNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 10540 Bundle.getMessage("BeanNameBlock") + " AC " 10541 + Bundle.getMessage("Name"))); 10542 panel11.add(xingSignalBlockACNameLabel); 10543 panel11.add(xingBlockACComboBox); 10544 xingBlockACComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10545 theContentPane.add(panel11); 10546 10547 JPanel panel12 = new JPanel(new FlowLayout()); 10548 xingSignalBlockBDNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 10549 Bundle.getMessage("BeanNameBlock") + " BD " 10550 + Bundle.getMessage("Name"))); 10551 panel12.add(xingSignalBlockBDNameLabel); 10552 panel12.add(xingBlockBDComboBox); 10553 xingBlockBDComboBox.setToolTipText(Bundle.getMessage("SignalsBlockNameHint")); 10554 theContentPane.add(panel12); 10555 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 10556 10557 JPanel panel2 = new JPanel(new FlowLayout()); 10558 JLabel shTitle = new JLabel(Bundle.getMessage("BeanNameSignalMast")); 10559 panel2.add(shTitle); 10560 panel2.add(new JLabel(" ")); 10561 panel2.add(getSavedXingSignalMasts = new JButton(Bundle.getMessage("GetSaved"))); 10562 getSavedXingSignalMasts.addActionListener(this::xingSignalMastsGetSaved); 10563 getSavedXingSignalMasts.setToolTipText(Bundle.getMessage("GetSavedHint")); 10564 theContentPane.add(panel2); 10565 10566 signalMastLevelXingPanel.setLayout(new GridLayout(0, 2)); 10567 10568 theContentPane.add(signalMastLevelXingPanel); 10569 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 10570 10571 JPanel panel6 = new JPanel(new FlowLayout()); 10572 10573 panel6.add(new JLabel(" ")); 10574 panel6.add(setXingSignalMastsDone = new JButton(Bundle.getMessage("ButtonDone"))); 10575 setXingSignalMastsDone.addActionListener(this::setXingSignalMastsDonePressed); 10576 setXingSignalMastsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 10577 panel6.add(setXingSignalMastsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 10578 setXingSignalMastsCancel.addActionListener(this::setXingSignalMastsCancelPressed); 10579 setXingSignalMastsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 10580 theContentPane.add(panel6); 10581 setSignalMastsAtLevelXingFrame.addWindowListener(new WindowAdapter() { 10582 @Override 10583 public void windowClosing(WindowEvent e) { 10584 setXingSignalMastsCancelPressed(null); 10585 } 10586 }); 10587 } //if (setSignalMastsAtLevelXingFrame == null) 10588 10589 //Unhide any excluded masts 10590 xingSignalMastA.getCombo().setExcludedItems(new HashSet<>()); 10591 xingSignalMastB.getCombo().setExcludedItems(new HashSet<>()); 10592 xingSignalMastC.getCombo().setExcludedItems(new HashSet<>()); 10593 xingSignalMastD.getCombo().setExcludedItems(new HashSet<>()); 10594 signalMastLevelXingPanel.removeAll(); 10595 10596 if (setSignalMastsAtLevelXingFromMenuFlag) { 10597 xingBlockACComboBox.setVisible(false); 10598 xingBlockBDComboBox.setVisible(false); 10599 10600 xingSignalBlockACNameLabel.setText(Bundle.getMessage("MakeLabel", 10601 (Bundle.getMessage("BeanNameBlock") + " AC")) 10602 + " " + levelXing.getBlockNameAC()); 10603 xingSignalBlockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 10604 (Bundle.getMessage("BeanNameBlock") + " BD")) 10605 + " " + levelXing.getBlockNameBD()); 10606 10607 xingSignalMastA.setTextField(levelXing.getSignalAMastName()); 10608 xingSignalMastB.setTextField(levelXing.getSignalBMastName()); 10609 xingSignalMastC.setTextField(levelXing.getSignalCMastName()); 10610 xingSignalMastD.setTextField(levelXing.getSignalDMastName()); 10611 10612 xingSignalMastsGetSaved(null); 10613 refreshSignalMastAtXingComboBox(); 10614 } else { 10615 xingSignalBlockACNameLabel.setText(Bundle.getMessage("MakeLabel", 10616 Bundle.getMessage("BeanNameBlock") + " AC " 10617 + Bundle.getMessage("Name"))); 10618 xingSignalBlockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 10619 Bundle.getMessage("BeanNameBlock") + " BD " 10620 + Bundle.getMessage("Name"))); 10621 } 10622 10623 if (!setSignalMastsAtLevelXingOpenFlag) { 10624 setSignalMastsAtLevelXingFrame.setPreferredSize(null); 10625 setSignalMastsAtLevelXingFrame.pack(); 10626 setSignalMastsAtLevelXingOpenFlag = true; 10627 } 10628 setSignalMastsAtLevelXingFrame.setVisible(true); 10629 } //setSignalMastsAtLevelXing 10630 10631 void refreshSignalMastAtXingComboBox() { 10632 xingSignalMastsGetSaved(null); 10633 createListUsedSignalMasts(); 10634 10635 usedMasts.remove(xingSignalMastA.getBean()); 10636 usedMasts.remove(xingSignalMastB.getBean()); 10637 usedMasts.remove(xingSignalMastC.getBean()); 10638 usedMasts.remove(xingSignalMastD.getBean()); 10639 10640 xingSignalMastA.getCombo().setExcludedItems(usedMasts); 10641 xingSignalMastB.getCombo().setExcludedItems(usedMasts); 10642 xingSignalMastC.getCombo().setExcludedItems(usedMasts); 10643 xingSignalMastD.getCombo().setExcludedItems(usedMasts); 10644 } 10645 10646 private void xingSignalMastsGetSaved(ActionEvent a) { 10647 if (!getLevelCrossingMastInformation()) { 10648 return; 10649 } 10650 xingBlocks = levelXing.getBlockBoundaries(); 10651 10652 xingSignalMastA.setTextField(levelXing.getSignalAMastName()); 10653 xingSignalMastB.setTextField(levelXing.getSignalBMastName()); 10654 xingSignalMastC.setTextField(levelXing.getSignalCMastName()); 10655 xingSignalMastD.setTextField(levelXing.getSignalDMastName()); 10656 10657 xingSignalMastA.setBoundaryLabel(xingBlocks[0]); 10658 xingSignalMastB.setBoundaryLabel(xingBlocks[1]); 10659 xingSignalMastC.setBoundaryLabel(xingBlocks[2]); 10660 xingSignalMastD.setBoundaryLabel(xingBlocks[3]); 10661 10662 boolean boundaryFlag = false; 10663 signalMastLevelXingPanel.remove(xingSignalMastA.getDetailsPanel()); 10664 signalMastLevelXingPanel.remove(xingSignalMastB.getDetailsPanel()); 10665 signalMastLevelXingPanel.remove(xingSignalMastC.getDetailsPanel()); 10666 signalMastLevelXingPanel.remove(xingSignalMastD.getDetailsPanel()); 10667 if (xingBlocks[0] != null) { 10668 signalMastLevelXingPanel.add(xingSignalMastA.getDetailsPanel()); 10669 boundaryFlag = true; 10670 } 10671 if (xingBlocks[1] != null) { 10672 signalMastLevelXingPanel.add(xingSignalMastB.getDetailsPanel()); 10673 boundaryFlag = true; 10674 } 10675 if (xingBlocks[2] != null) { 10676 signalMastLevelXingPanel.add(xingSignalMastC.getDetailsPanel()); 10677 boundaryFlag = true; 10678 } 10679 if (xingBlocks[3] != null) { 10680 signalMastLevelXingPanel.add(xingSignalMastD.getDetailsPanel()); 10681 boundaryFlag = true; 10682 } 10683 if (!boundaryFlag) { 10684 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, "There are no block boundaries on this level crossing\nIt is therefore not possible to add Signal Masts to it"); 10685 } 10686 setSignalMastsAtLevelXingFrame.setPreferredSize(null); 10687 setSignalMastsAtLevelXingFrame.pack(); 10688 } //xingSignalMastsGetSaved 10689 10690 private boolean getLevelCrossingMastInformation() { 10691 if (!setSignalMastsAtLevelXingFromMenuFlag) { 10692 levelXing = null; 10693 List<LevelXing> levelXings = layoutEditor.getLevelXings(); 10694 if (levelXings.size() <= 0) { 10695 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10696 Bundle.getMessage("SignalsError15"), 10697 Bundle.getMessage("ErrorTitle"), 10698 JmriJOptionPane.ERROR_MESSAGE); 10699 return false; 10700 } else if (levelXings.size() == 1) { 10701 levelXing = levelXings.get(0); 10702 } else { 10703 LayoutBlock xingBlockA = null; 10704 LayoutBlock xingBlockC = null; 10705 xingBlockA = getBlockFromEntry(xingBlockACComboBox); 10706 if (xingBlockA == null) { 10707 return false; 10708 } 10709 10710 String theBlockName = xingBlockBDComboBox.getSelectedItemDisplayName(); 10711 if ((theBlockName != null) && !theBlockName.isEmpty()) { 10712 xingBlockC = getBlockFromEntry(xingBlockBDComboBox); 10713 if (xingBlockC == null) { 10714 return false; 10715 } 10716 } 10717 10718 int foundCount = 0; 10719 //make two block tests first 10720 if (xingBlockC != null) { 10721 for (LevelXing x : layoutEditor.getLevelXings()) { 10722 LayoutBlock xA = null; 10723 LayoutBlock xB = null; 10724 LayoutBlock xC = null; 10725 LayoutBlock xD = null; 10726 LayoutBlock xAC = x.getLayoutBlockAC(); 10727 LayoutBlock xBD = x.getLayoutBlockBD(); 10728 if (x.getConnectA() != null) { 10729 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 10730 } 10731 if (x.getConnectB() != null) { 10732 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 10733 } 10734 if (x.getConnectC() != null) { 10735 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 10736 } 10737 if (x.getConnectD() != null) { 10738 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 10739 } 10740 if (((xA != null) && (xC != null) && (((xA == xingBlockA) && (xC == xingBlockC)) 10741 || ((xA == xingBlockC) && (xC == xingBlockA)))) 10742 || ((xB != null) && (xD != null) && (((xB == xingBlockA) && (xD == xingBlockC)) 10743 || ((xB == xingBlockC) && (xD == xingBlockA))))) { 10744 levelXing = x; 10745 foundCount++; 10746 } else if ((xAC != null) && (xBD != null) && (((xAC == xingBlockA) && (xBD == xingBlockC)) 10747 || ((xAC == xingBlockC) && (xBD == xingBlockA)))) { 10748 levelXing = x; 10749 foundCount++; 10750 } 10751 } 10752 } 10753 if (foundCount == 0) { 10754 //try one block test 10755 for (LevelXing x : layoutEditor.getLevelXings()) { 10756 if ((xingBlockA == x.getLayoutBlockAC()) || (xingBlockA == x.getLayoutBlockBD())) { 10757 levelXing = x; 10758 foundCount++; 10759 } 10760 } 10761 } 10762 if (foundCount > 1) { 10763 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10764 Bundle.getMessage("SignalsError16", 10765 new Object[]{" " + foundCount + " "}), 10766 Bundle.getMessage("ErrorTitle"), 10767 JmriJOptionPane.ERROR_MESSAGE); 10768 return false; 10769 } 10770 if (levelXing == null) { 10771 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10772 Bundle.getMessage("SignalsError17"), 10773 Bundle.getMessage("ErrorTitle"), 10774 JmriJOptionPane.ERROR_MESSAGE); 10775 return false; 10776 } 10777 } 10778 } 10779 return true; 10780 } //getLevelCrossingMastInformation 10781 10782 private void setXingSignalMastsCancelPressed(ActionEvent a) { 10783 setSignalMastsAtLevelXingOpenFlag = false; 10784 setSignalMastsAtLevelXingFrame.setVisible(false); 10785 } 10786 10787 private void setXingSignalMastsDonePressed(ActionEvent a) { 10788 if (!getLevelCrossingMastInformation()) { 10789 return; 10790 } 10791 SignalMast aMast = getSignalMastFromEntry(xingSignalMastA.getText(), false, setSignalMastsAtLevelXingFrame); 10792 SignalMast bMast = getSignalMastFromEntry(xingSignalMastB.getText(), false, setSignalMastsAtLevelXingFrame); 10793 SignalMast cMast = getSignalMastFromEntry(xingSignalMastC.getText(), false, setSignalMastsAtLevelXingFrame); 10794 SignalMast dMast = getSignalMastFromEntry(xingSignalMastD.getText(), false, setSignalMastsAtLevelXingFrame); 10795 10796 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 10797 10798 //if ( !getXingSignalMastInformation() ) return; 10799 //place or update signals as requested 10800 if ((aMast != null) && xingSignalMastA.addToPanel()) { 10801 if (isSignalMastOnPanel(aMast) 10802 && (aMast != levelXing.getSignalAMast())) { 10803 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10804 Bundle.getMessage("SignalMastsError6", 10805 new Object[]{xingSignalMastA.getText()}), 10806 Bundle.getMessage("ErrorTitle"), 10807 JmriJOptionPane.ERROR_MESSAGE); 10808 return; 10809 } else { 10810 removeSignalMastFromPanel(levelXing.getSignalAMast()); 10811 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10812 l.setSignalMast(xingSignalMastA.getText()); 10813 placingBlock(l, xingSignalMastA.isRightSelected(), 0.0, levelXing.getConnectA(), levelXingView.getCoordsA()); 10814 removeAssignment(aMast); 10815 levelXing.setSignalAMast(xingSignalMastA.getText()); 10816 needRedraw = true; 10817 } 10818 } else if ((aMast != null) 10819 && (aMast != levelXing.getSignalAMast()) 10820 && (aMast != levelXing.getSignalBMast()) 10821 && (aMast != levelXing.getSignalCMast()) 10822 && (aMast != levelXing.getSignalDMast())) { 10823 if (isSignalMastOnPanel(aMast)) { 10824 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10825 Bundle.getMessage("SignalMastsError13", 10826 new Object[]{xingSignalMastA.getText()}), 10827 Bundle.getMessage("ErrorTitle"), 10828 JmriJOptionPane.ERROR_MESSAGE); 10829 return; 10830 } else { 10831 removeSignalMastFromPanel(levelXing.getSignalAMast()); 10832 removeAssignment(aMast); 10833 levelXing.setSignalAMast(xingSignalMastA.getText()); 10834 } 10835 } else if ((aMast != null) 10836 && ((aMast == levelXing.getSignalBMast()) 10837 || (aMast == levelXing.getSignalCMast()) 10838 || (aMast == levelXing.getSignalDMast()))) { 10839 //need to figure out what to do in this case. 10840 log.trace("need to figure out what to do in this case."); 10841 } else if (aMast == null) { 10842 removeSignalMastFromPanel(levelXing.getSignalAMast()); 10843 levelXing.setSignalAMast(""); 10844 } 10845 if ((bMast != null) && xingSignalMastB.addToPanel()) { 10846 if (isSignalMastOnPanel(bMast) 10847 && (bMast != levelXing.getSignalBMast())) { 10848 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10849 Bundle.getMessage("SignalMastsError6", 10850 new Object[]{xingSignalMastB.getText()}), 10851 Bundle.getMessage("ErrorTitle"), 10852 JmriJOptionPane.ERROR_MESSAGE); 10853 return; 10854 } else { 10855 removeSignalMastFromPanel(levelXing.getSignalBMast()); 10856 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10857 l.setSignalMast(xingSignalMastB.getText()); 10858 placingBlock(l, xingSignalMastB.isRightSelected(), 0.0, levelXing.getConnectB(), levelXingView.getCoordsB()); 10859 removeAssignment(bMast); 10860 levelXing.setSignalBMast(xingSignalMastB.getText()); 10861 needRedraw = true; 10862 } 10863 } else if ((bMast != null) 10864 && (bMast != levelXing.getSignalAMast()) 10865 && (bMast != levelXing.getSignalBMast()) 10866 && (bMast != levelXing.getSignalCMast()) 10867 && (bMast != levelXing.getSignalDMast())) { 10868 if (isSignalMastOnPanel(bMast)) { 10869 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10870 Bundle.getMessage("SignalMastsError13", 10871 new Object[]{xingSignalMastB.getText()}), 10872 Bundle.getMessage("ErrorTitle"), 10873 JmriJOptionPane.ERROR_MESSAGE); 10874 return; 10875 } else { 10876 removeSignalMastFromPanel(levelXing.getSignalBMast()); 10877 removeAssignment(bMast); 10878 levelXing.setSignalBMast(xingSignalMastB.getText()); 10879 } 10880 } else if ((bMast != null) 10881 && ((bMast == levelXing.getSignalAMast()) 10882 || (bMast == levelXing.getSignalCMast()) 10883 || (bMast == levelXing.getSignalBMast()) 10884 || (bMast == levelXing.getSignalDMast()))) { 10885 //need to figure out what to do in this case. 10886 log.trace("need to figure out what to do in this case."); 10887 } else if (bMast == null) { 10888 removeSignalMastFromPanel(levelXing.getSignalBMast()); 10889 levelXing.setSignalBMast(""); 10890 } 10891 if ((cMast != null) && xingSignalMastC.addToPanel()) { 10892 if (isSignalMastOnPanel(cMast) 10893 && (cMast != levelXing.getSignalCMast())) { 10894 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10895 Bundle.getMessage("SignalMastsError6", 10896 new Object[]{xingSignalMastC.getText()}), 10897 Bundle.getMessage("ErrorTitle"), 10898 JmriJOptionPane.ERROR_MESSAGE); 10899 return; 10900 } else { 10901 removeSignalMastFromPanel(levelXing.getSignalCMast()); 10902 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10903 l.setSignalMast(xingSignalMastC.getText()); 10904 placingBlock(l, xingSignalMastC.isRightSelected(), 0.0, levelXing.getConnectC(), levelXingView.getCoordsC()); 10905 removeAssignment(cMast); 10906 levelXing.setSignalCMast(xingSignalMastC.getText()); 10907 needRedraw = true; 10908 } 10909 } else if ((cMast != null) 10910 && (cMast != levelXing.getSignalAMast()) 10911 && (cMast != levelXing.getSignalBMast()) 10912 && (cMast != levelXing.getSignalCMast()) 10913 && (cMast != levelXing.getSignalDMast())) { 10914 if (isSignalMastOnPanel(cMast)) { 10915 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10916 Bundle.getMessage("SignalMastsError13", 10917 new Object[]{xingSignalMastC.getText()}), 10918 Bundle.getMessage("ErrorTitle"), 10919 JmriJOptionPane.ERROR_MESSAGE); 10920 return; 10921 } else { 10922 removeSignalMastFromPanel(levelXing.getSignalCMast()); 10923 removeAssignment(cMast); 10924 levelXing.setSignalCMast(xingSignalMastC.getText()); 10925 } 10926 } else if ((cMast != null) 10927 && ((cMast == levelXing.getSignalBMast()) 10928 || (cMast == levelXing.getSignalAMast()) 10929 || (cMast == levelXing.getSignalDMast()))) { 10930 //need to figure out what to do in this case. 10931 log.trace("need to figure out what to do in this case."); 10932 } else if (cMast == null) { 10933 removeSignalMastFromPanel(levelXing.getSignalCMast()); 10934 levelXing.setSignalCName(""); 10935 } 10936 if ((dMast != null) && xingSignalMastD.addToPanel()) { 10937 if (isSignalMastOnPanel(dMast) 10938 && (dMast != levelXing.getSignalDMast())) { 10939 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10940 Bundle.getMessage("SignalMastsError6", 10941 new Object[]{xingSignalMastD.getText()}), 10942 Bundle.getMessage("ErrorTitle"), 10943 JmriJOptionPane.ERROR_MESSAGE); 10944 return; 10945 } else { 10946 removeSignalMastFromPanel(levelXing.getSignalDMast()); 10947 SignalMastIcon l = new SignalMastIcon(layoutEditor); 10948 l.setSignalMast(xingSignalMastD.getText()); 10949 placingBlock(l, xingSignalMastD.isRightSelected(), 0.0, levelXing.getConnectD(), levelXingView.getCoordsD()); 10950 removeAssignment(dMast); 10951 levelXing.setSignalDMast(xingSignalMastD.getText()); 10952 needRedraw = true; 10953 } 10954 } else if ((dMast != null) 10955 && (dMast != levelXing.getSignalAMast()) 10956 && (dMast != levelXing.getSignalBMast()) 10957 && (dMast != levelXing.getSignalCMast()) 10958 && (dMast != levelXing.getSignalDMast())) { 10959 if (isSignalMastOnPanel(dMast)) { 10960 JmriJOptionPane.showMessageDialog(setSignalMastsAtLevelXingFrame, 10961 Bundle.getMessage("SignalMastsError13", 10962 new Object[]{xingSignalMastD.getText()}), 10963 Bundle.getMessage("ErrorTitle"), 10964 JmriJOptionPane.ERROR_MESSAGE); 10965 return; 10966 } else { 10967 removeSignalMastFromPanel(levelXing.getSignalDMast()); 10968 removeAssignment(dMast); 10969 levelXing.setSignalDMast(xingSignalMastD.getText()); 10970 } 10971 } else if ((dMast != null) 10972 && ((dMast == levelXing.getSignalBMast()) 10973 || (dMast == levelXing.getSignalCMast()) 10974 || (dMast == levelXing.getSignalAMast()))) { 10975 //need to figure out what to do in this case. 10976 log.trace("need to figure out what to do in this case."); 10977 } else if (dMast == null) { 10978 removeSignalMastFromPanel(levelXing.getSignalDMast()); 10979 levelXing.setSignalDMast(""); 10980 } 10981 //setup logic if requested 10982 //finish up 10983 setSignalMastsAtLevelXingOpenFlag = false; 10984 setSignalMastsAtLevelXingFrame.setVisible(false); 10985 if (needRedraw) { 10986 layoutEditor.redrawPanel(); 10987 needRedraw = false; 10988 layoutEditor.setDirty(); 10989 } 10990 } //setXingSignalMastsDonePressed 10991 10992 /*=====================*\ 10993 |* setSensorsAtTurnout *| 10994 \*=====================*/ 10995 private JmriJFrame setSensorsAtTurnoutFrame = null; 10996 private boolean setSensorsAtTurnoutOpenFlag = false; 10997 private boolean setSensorsAtTurnoutFromMenuFlag = false; 10998 10999 private JFrame turnoutSensorFrame = null; 11000 private JLabel turnoutSensorNameLabel = null; 11001 11002 private final NamedBeanComboBox<Turnout> sensorsTurnoutComboBox 11003 = new NamedBeanComboBox<>( 11004 InstanceManager.turnoutManagerInstance(), 11005 null, DisplayOptions.DISPLAYNAME); 11006 11007 private JButton setSensorsDone; 11008 private JButton getSavedSensors; 11009 private JButton setSensorsCancel; 11010 private JButton changeSensorIcon = null; 11011 11012 private String[] turnoutSenBlocks = new String[4]; 11013 11014 BeanDetails<Sensor> turnoutSensorA; 11015 BeanDetails<Sensor> turnoutSensorB; 11016 BeanDetails<Sensor> turnoutSensorC; 11017 BeanDetails<Sensor> turnoutSensorD; 11018 11019 JPanel sensorTurnoutPanel = new JPanel(new FlowLayout()); 11020 11021 public void setSensorsAtTurnoutFromMenu(@Nonnull LayoutTurnout to, 11022 @Nonnull String[] blocks, 11023 @Nonnull MultiIconEditor theEditor, 11024 @Nonnull JFrame frame) { 11025 sensorIconEditor = theEditor; 11026 layoutTurnout = to; 11027 turnout = to.getTurnout(); 11028 sensorsTurnoutComboBox.setSelectedItem(turnout); 11029 turnoutSenBlocks = new String[4]; 11030 for (int i = 0; i < blocks.length; i++) { 11031 turnoutSenBlocks[i] = blocks[i]; 11032 } 11033 setSensorsAtTurnoutFromMenuFlag = true; 11034 setSensorsAtTurnout(frame); 11035 setSensorsAtTurnoutFromMenuFlag = false; 11036 } 11037 11038 //TODO: Add to Tools menu? 11039 public void setSensorsAtTurnout(@Nonnull JFrame frame) { 11040 turnoutSensorFrame = frame; 11041 11042 //Initialize if needed 11043 if (setSensorsAtTurnoutFrame == null) { 11044 setSensorsAtTurnoutOpenFlag = false; 11045 11046 turnoutSensorA = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); // NOI18N 11047 turnoutSensorB = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); // NOI18N 11048 turnoutSensorC = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); // NOI18N 11049 turnoutSensorD = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); // NOI18N 11050 11051 turnoutSensorA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 11052 turnoutSensorB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 11053 turnoutSensorC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 11054 turnoutSensorD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 11055 11056 setSensorsAtTurnoutFrame = new JmriJFrame(Bundle.getMessage("SensorsAtTurnout"), false, true); 11057 oneFrameToRuleThemAll(setSensorsAtTurnoutFrame); 11058 setSensorsAtTurnoutFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 11059// setSensorsAtTurnoutFrame.addHelpMenu("package.jmri.jmrit.display.SetSensorsAtTurnout", true); 11060 setSensorsAtTurnoutFrame.setLocation(70, 30); 11061 Container theContentPane = setSensorsAtTurnoutFrame.getContentPane(); 11062 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 11063 11064 JPanel panel1 = new JPanel(new FlowLayout()); 11065 11066 turnoutSensorNameLabel = new JLabel(Bundle.getMessage("BeanNameTurnout") + " " 11067 + Bundle.getMessage("Name")); 11068 panel1.add(turnoutSensorNameLabel); 11069 panel1.add(sensorsTurnoutComboBox); 11070 sensorsTurnoutComboBox.setToolTipText(Bundle.getMessage("SensorsTurnoutNameHint")); 11071 11072 theContentPane.add(panel1); 11073 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 11074 11075 JPanel panel2 = new JPanel(new FlowLayout()); 11076 JLabel shTitle = new JLabel(Bundle.getMessage("Sensors")); 11077 panel2.add(shTitle); 11078 panel2.add(new JLabel(" ")); 11079 panel2.add(getSavedSensors = new JButton(Bundle.getMessage("GetSaved"))); 11080 getSavedSensors.addActionListener(this::turnoutSensorsGetSaved); 11081 getSavedSensors.setToolTipText(Bundle.getMessage("GetSavedHint")); 11082 theContentPane.add(panel2); 11083 11084 sensorTurnoutPanel.setLayout(new GridLayout(0, 2)); //Content added as needed 11085 theContentPane.add(sensorTurnoutPanel); 11086 11087 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 11088 11089 JPanel panel6 = new JPanel(new FlowLayout()); 11090 panel6.add(changeSensorIcon = new JButton(Bundle.getMessage("ChangeSensorIcon"))); 11091 changeSensorIcon.addActionListener((ActionEvent e) -> turnoutSensorFrame.setVisible(true)); 11092 changeSensorIcon.setToolTipText(Bundle.getMessage("ChangeSensorIconHint")); 11093 panel6.add(new JLabel(" ")); 11094 panel6.add(setSensorsDone = new JButton(Bundle.getMessage("ButtonDone"))); 11095 setSensorsDone.addActionListener(this::setSensorsDonePressed); 11096 setSensorsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 11097 panel6.add(setSensorsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 11098 setSensorsCancel.addActionListener(this::setSensorsCancelPressed); 11099 setSensorsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 11100 theContentPane.add(panel6); 11101 setSensorsAtTurnoutFrame.addWindowListener(new WindowAdapter() { 11102 @Override 11103 public void windowClosing(WindowEvent e) { 11104 setSensorsCancelPressed(null); 11105 } 11106 }); 11107 } 11108 11109 sensorTurnoutPanel.removeAll(); 11110 11111 sensorsTurnoutComboBox.setVisible(!setSensorsAtTurnoutFromMenuFlag); 11112 11113 if (setSensorsAtTurnoutFromMenuFlag) { 11114 turnoutSensorNameLabel.setText(Bundle.getMessage("MakeLabel", 11115 Bundle.getMessage("BeanNameTurnout") 11116 + " " + Bundle.getMessage("Name")) 11117 + " " + layoutTurnout.getTurnoutName()); 11118 turnoutSensorsGetSaved(null); 11119 } else { 11120 turnoutSensorNameLabel.setText(Bundle.getMessage("BeanNameTurnout") + " " 11121 + Bundle.getMessage("Name")); 11122 } 11123 11124 if (!setSensorsAtTurnoutOpenFlag) { 11125 setSensorsAtTurnoutFrame.setPreferredSize(null); 11126 setSensorsAtTurnoutFrame.pack(); 11127 setSensorsAtTurnoutOpenFlag = true; 11128 } 11129 setSensorsAtTurnoutFrame.setVisible(true); 11130 } //setSensorsAtTurnout 11131 11132 private void turnoutSensorsGetSaved(ActionEvent a) { 11133 if (!getTurnoutSensorInformation()) { 11134 return; 11135 } 11136 turnoutSenBlocks = layoutTurnout.getBlockBoundaries(); 11137 11138 turnoutSensorA.setTextField(layoutTurnout.getSensorAName()); 11139 turnoutSensorB.setTextField(layoutTurnout.getSensorBName()); 11140 turnoutSensorC.setTextField(layoutTurnout.getSensorCName()); 11141 turnoutSensorD.setTextField(layoutTurnout.getSensorDName()); 11142 11143 turnoutSensorA.setBoundaryLabel(turnoutSenBlocks[0]); 11144 turnoutSensorB.setBoundaryLabel(turnoutSenBlocks[1]); 11145 turnoutSensorC.setBoundaryLabel(turnoutSenBlocks[2]); 11146 turnoutSensorD.setBoundaryLabel(turnoutSenBlocks[3]); 11147 11148 sensorTurnoutPanel.remove(turnoutSensorA.getDetailsPanel()); 11149 sensorTurnoutPanel.remove(turnoutSensorB.getDetailsPanel()); 11150 sensorTurnoutPanel.remove(turnoutSensorC.getDetailsPanel()); 11151 sensorTurnoutPanel.remove(turnoutSensorD.getDetailsPanel()); 11152 11153 boolean boundaryFlag = false; 11154 if (turnoutSenBlocks[0] != null) { 11155 sensorTurnoutPanel.add(turnoutSensorA.getDetailsPanel()); 11156 boundaryFlag = true; 11157 } 11158 if (turnoutSenBlocks[1] != null) { 11159 sensorTurnoutPanel.add(turnoutSensorB.getDetailsPanel()); 11160 boundaryFlag = true; 11161 } 11162 if (turnoutSenBlocks[2] != null) { 11163 sensorTurnoutPanel.add(turnoutSensorC.getDetailsPanel()); 11164 boundaryFlag = true; 11165 } 11166 if (turnoutSenBlocks[3] != null) { 11167 sensorTurnoutPanel.add(turnoutSensorD.getDetailsPanel()); 11168 boundaryFlag = true; 11169 } 11170 if (!boundaryFlag) { 11171 JmriJOptionPane.showMessageDialog(setSensorsAtTurnoutFrame, "There are no block boundaries on this turnout\nIt is therefore not possible to add Sensors to it"); 11172 } 11173 setSensorsAtTurnoutFrame.setPreferredSize(null); 11174 setSensorsAtTurnoutFrame.pack(); 11175 } //turnoutSensorsGetSaved 11176 11177 SensorIcon turnoutSensorBlockIcon; 11178 11179 private void setSensorsDonePressed(ActionEvent a) { 11180 log.trace("setSensorsDonePressed (turnouts)"); // NOI18N 11181 if (!getTurnoutSensorInformation()) { 11182 return; 11183 } 11184 11185 //process sensor names 11186 Sensor sensorA = getSensorFromEntry(turnoutSensorA.getText(), false, setSensorsAtTurnoutFrame); 11187 Sensor sensorB = getSensorFromEntry(turnoutSensorB.getText(), false, setSensorsAtTurnoutFrame); 11188 Sensor sensorC = getSensorFromEntry(turnoutSensorC.getText(), false, setSensorsAtTurnoutFrame); 11189 Sensor sensorD = getSensorFromEntry(turnoutSensorD.getText(), false, setSensorsAtTurnoutFrame); 11190 11191 Sensor currSensorA = layoutTurnout.getSensorA(); 11192 Sensor currSensorB = layoutTurnout.getSensorB(); 11193 Sensor currSensorC = layoutTurnout.getSensorC(); 11194 Sensor currSensorD = layoutTurnout.getSensorD(); 11195 11196 if (log.isTraceEnabled()) { 11197 log.trace("current sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 11198 (currSensorA == null) ? "- none- " : currSensorA.getDisplayName(), // NOI18N 11199 (currSensorB == null) ? "- none- " : currSensorB.getDisplayName(), // NOI18N 11200 (currSensorC == null) ? "- none- " : currSensorC.getDisplayName(), // NOI18N 11201 (currSensorD == null) ? "- none- " : currSensorD.getDisplayName()); // NOI18N 11202 log.trace("new sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 11203 (sensorA == null) ? "- none- " : sensorA.getDisplayName(), // NOI18N 11204 (sensorB == null) ? "- none- " : sensorB.getDisplayName(), // NOI18N 11205 (sensorC == null) ? "- none- " : sensorC.getDisplayName(), // NOI18N 11206 (sensorD == null) ? "- none- " : sensorD.getDisplayName()); // NOI18N 11207 } 11208 11209 LayoutTurnoutView layoutTurnoutView = layoutEditor.getLayoutTurnoutView(layoutTurnout); 11210 11211 //place/remove sensors as requested 11212 if (sensorA == null) { 11213 if (currSensorA != null && removeSensorFromPanel(currSensorA)) { 11214 layoutTurnout.setSensorA(null); 11215 } 11216 } else if (turnoutSensorA != null && layoutTurnout.getConnectA() != null) { 11217 setTurnoutSensor(layoutTurnout, sensorA, currSensorA, turnoutSensorA, layoutTurnout.getConnectA(), layoutTurnoutView.getCoordsA(), "A"); 11218 } 11219 11220 if (sensorB == null) { 11221 if (currSensorB != null && removeSensorFromPanel(currSensorB)) { 11222 layoutTurnout.setSensorB(null); 11223 } 11224 } else if (turnoutSensorB != null && layoutTurnout.getConnectB() != null) { 11225 setTurnoutSensor(layoutTurnout, sensorB, currSensorB, turnoutSensorB, layoutTurnout.getConnectB(), layoutTurnoutView.getCoordsB(), "B"); 11226 } 11227 11228 if (sensorC == null) { 11229 if (currSensorC != null && removeSensorFromPanel(currSensorC)) { 11230 layoutTurnout.setSensorC(null); 11231 } 11232 } else if (turnoutSensorC != null && layoutTurnout.getConnectC() != null) { 11233 setTurnoutSensor(layoutTurnout, sensorC, currSensorC, turnoutSensorC, layoutTurnout.getConnectC(), layoutTurnoutView.getCoordsC(), "C"); 11234 } 11235 11236 if (sensorD == null) { 11237 if (currSensorD != null && removeSensorFromPanel(currSensorD)) { 11238 layoutTurnout.setSensorD(null); 11239 } 11240 } else if (turnoutSensorD != null && layoutTurnout.getConnectD() != null) { 11241 setTurnoutSensor(layoutTurnout, sensorD, currSensorD, turnoutSensorD, layoutTurnout.getConnectD(), layoutTurnoutView.getCoordsD(), "D"); 11242 } 11243 11244 //make sure this layout turnout is not linked to another 11245 layoutTurnout.setLinkType(LayoutTurnout.LinkType.NO_LINK); 11246 layoutTurnout.setLinkedTurnoutName(""); 11247 11248 //finish up 11249 setSensorsAtTurnoutOpenFlag = false; 11250 setSensorsAtTurnoutFrame.setVisible(false); 11251 if (needRedraw) { 11252 layoutEditor.redrawPanel(); 11253 needRedraw = false; 11254 layoutEditor.setDirty(); 11255 } 11256 } //setSensorsDonePressed 11257 11258 /** 11259 * Attached a sensor to a turnout block boundary. Supports both 11260 * LayoutTurnout and LayoutSlip classes. 11261 * 11262 * @since 4.11.2 11263 * @param <T> The specific type, a subtype of LayoutTurnout 11264 * @param trackItem The turnout or slip that is being modified. 11265 * @param newSensor The sensor that is being added. 11266 * @param currSensor The sensor that might already be there, otherwise null. 11267 * @param beanDetail The BeanDetails object that contains the supporting 11268 * data. 11269 * @param connect The track segment that is attached to this point 11270 * @param coords The track componennt coordinates 11271 * @param position Which of the four points is being changed 11272 */ 11273 <T extends LayoutTurnout> void setTurnoutSensor(T trackItem, Sensor newSensor, Sensor currSensor, 11274 BeanDetails<? extends NamedBean> beanDetail, LayoutTrack connect, Point2D coords, String position) { 11275 if (currSensor == null) { 11276 if (!isSensorAssignedAnywhere(newSensor)) { 11277 log.trace("Add sensor '{}'", newSensor.getDisplayName()); // NOI18N 11278 switch (position) { 11279 case "A": // NOI18N 11280 trackItem.setSensorA(beanDetail.getText()); 11281 break; 11282 case "B": // NOI18N 11283 trackItem.setSensorB(beanDetail.getText()); 11284 break; 11285 case "C": // NOI18N 11286 trackItem.setSensorC(beanDetail.getText()); 11287 break; 11288 case "D": // NOI18N 11289 trackItem.setSensorD(beanDetail.getText()); 11290 break; 11291 default: 11292 break; 11293 } 11294 if (beanDetail.addToPanel()) { 11295 log.trace("Add icon for sensor '{}'", newSensor.getDisplayName()); // NOI18N 11296 placingBlock(getSensorIcon(beanDetail.getText()), 11297 beanDetail.isRightSelected(), 0.0, 11298 connect, coords); 11299 needRedraw = true; 11300 } 11301 } else { 11302 sensorAssignedElseWhere(newSensor); 11303 } 11304 } else if (currSensor == newSensor) { 11305 if (beanDetail.addToPanel()) { 11306 if (!isSensorOnPanel(newSensor)) { 11307 log.trace("Add icon for existing sensor '{}'", newSensor.getDisplayName()); // NOI18N 11308 placingBlock(getSensorIcon(beanDetail.getText()), 11309 beanDetail.isRightSelected(), 0.0, 11310 connect, coords); 11311 needRedraw = true; 11312 } 11313 } 11314 } else { 11315 if (!isSensorAssignedAnywhere(newSensor)) { 11316 if (removeSensorFromPanel(currSensor)) { 11317 log.trace("Replace sensor '{}' with sensor '{}'", // NOI18N 11318 currSensor.getDisplayName(), newSensor.getDisplayName()); 11319 switch (position) { 11320 case "A": // NOI18N 11321 trackItem.setSensorA(beanDetail.getText()); 11322 break; 11323 case "B": // NOI18N 11324 trackItem.setSensorB(beanDetail.getText()); 11325 break; 11326 case "C": // NOI18N 11327 trackItem.setSensorC(beanDetail.getText()); 11328 break; 11329 case "D": // NOI18N 11330 trackItem.setSensorD(beanDetail.getText()); 11331 break; 11332 default: 11333 break; 11334 } 11335 if (beanDetail.addToPanel()) { 11336 log.trace("Add icon for replacement sensor '{}'", // NOI18N 11337 newSensor.getDisplayName()); 11338 placingBlock(getSensorIcon(beanDetail.getText()), 11339 beanDetail.isRightSelected(), 0.0, 11340 connect, coords); 11341 needRedraw = true; 11342 } 11343 } 11344 } else { 11345 sensorAssignedElseWhere(newSensor); 11346 } 11347 } 11348 } 11349 11350 private boolean getTurnoutSensorInformation() { 11351 turnout = null; 11352 layoutTurnout = null; 11353 String str = sensorsTurnoutComboBox.getSelectedItemDisplayName(); 11354 if ((str == null) || str.isEmpty()) { 11355 JmriJOptionPane.showMessageDialog(setSensorsAtTurnoutFrame, Bundle.getMessage("SensorsError1"), 11356 Bundle.getMessage("ErrorTitle"), 11357 JmriJOptionPane.ERROR_MESSAGE); 11358 return false; 11359 } 11360 turnout = InstanceManager.turnoutManagerInstance().getTurnout(str); 11361 if (turnout == null) { 11362 JmriJOptionPane.showMessageDialog(setSensorsAtTurnoutFrame, 11363 Bundle.getMessage("SensorsError2", 11364 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 11365 JmriJOptionPane.ERROR_MESSAGE); 11366 return false; 11367 } else { 11368 String uname = turnout.getUserName(); 11369 if ((uname == null) || uname.isEmpty() 11370 || !uname.equals(str)) { 11371 sensorsTurnoutComboBox.setSelectedItem(turnout); 11372 } 11373 } 11374 layoutTurnout = layoutEditor.getFinder().findLayoutTurnoutByBean(turnout); 11375 if (layoutTurnout == null) { 11376 JmriJOptionPane.showMessageDialog(setSensorsAtTurnoutFrame, 11377 Bundle.getMessage("SensorsError3", 11378 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 11379 JmriJOptionPane.ERROR_MESSAGE); 11380 return false; 11381 } 11382 return true; 11383 } //getTurnoutSensorInformation 11384 11385 private void setSensorsCancelPressed(ActionEvent a) { 11386 setSensorsAtTurnoutOpenFlag = false; 11387 setSensorsAtTurnoutFrame.setVisible(false); 11388 } 11389 11390 /*=======================*\ 11391 |* setSensorsAtLevelXing *| 11392 \*=======================*/ 11393 //operational variables for Set Sensors at Level Crossing tool 11394 private JmriJFrame setSensorsAtLevelXingFrame = null; 11395 private boolean setSensorsAtLevelXingOpenFlag = false; 11396 private boolean setSensorsAtLevelXingFromMenuFlag = false; 11397 11398 private JLabel xingSensorsBlockACNameLabel = null; 11399 private JLabel xingSensorsBlockBDNameLabel = null; 11400 11401 private final NamedBeanComboBox<Block> xingSensorsBlockACComboBox 11402 = new NamedBeanComboBox<>( 11403 InstanceManager.getDefault(BlockManager.class), 11404 null, DisplayOptions.DISPLAYNAME); 11405 private final NamedBeanComboBox<Block> xingSensorsBlockBDComboBox 11406 = new NamedBeanComboBox<>( 11407 InstanceManager.getDefault(BlockManager.class), 11408 null, DisplayOptions.DISPLAYNAME); 11409 11410 private JButton getSavedXingSensors = null; 11411 private JButton setXingSensorsDone = null; 11412 private JButton setXingSensorsCancel = null; 11413 private JButton changeSensorXingIcon = null; 11414 JFrame sensorXingFrame = null; 11415 11416 private String[] xingSensorBlocks = new String[4]; 11417 11418 BeanDetails<Sensor> xingSensorA; 11419 BeanDetails<Sensor> xingSensorB; 11420 BeanDetails<Sensor> xingSensorC; 11421 BeanDetails<Sensor> xingSensorD; 11422 11423 JPanel sensorXingPanel = new JPanel(new FlowLayout()); 11424 11425 //display dialog for Set Signals at Level Crossing tool 11426 public void setSensorsAtLevelXingFromMenu(@Nonnull LevelXing xing, 11427 @Nonnull String[] blocks, 11428 @Nonnull MultiIconEditor theEditor, 11429 @Nonnull JFrame theFrame) { 11430 levelXing = xing; 11431 BlockManager bm = InstanceManager.getDefault(BlockManager.class); 11432 xingSensorsBlockACComboBox.setSelectedItem(bm.getBlock(levelXing.getBlockNameAC())); 11433 xingSensorsBlockBDComboBox.setSelectedItem(bm.getBlock(levelXing.getBlockNameBD())); 11434 for (int i = 0; i < blocks.length; i++) { 11435 xingSensorBlocks[i] = blocks[i]; 11436 } 11437 setSensorsAtLevelXingFromMenuFlag = true; 11438 setSensorsAtLevelXing(theEditor, theFrame); 11439 setSensorsAtLevelXingFromMenuFlag = false; 11440 } 11441 11442 //TODO: Add to Tools menu? 11443 public void setSensorsAtLevelXing(@Nonnull MultiIconEditor theEditor, 11444 @Nonnull JFrame theFrame) { 11445 sensorIconEditor = theEditor; 11446 sensorXingFrame = theFrame; 11447 11448 //Initialize if needed 11449 if (setSensorsAtLevelXingFrame == null) { 11450 setSensorsAtLevelXingOpenFlag = false; 11451 11452 xingSensorA = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11453 xingSensorB = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11454 xingSensorC = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11455 xingSensorD = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11456 11457 xingSensorA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 11458 xingSensorB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 11459 xingSensorC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 11460 xingSensorD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 11461 11462 setSensorsAtLevelXingFrame = new JmriJFrame(Bundle.getMessage("SensorsAtLevelXing"), false, true); 11463 oneFrameToRuleThemAll(setSensorsAtLevelXingFrame); 11464 setSensorsAtLevelXingFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 11465// setSensorsAtLevelXingFrame.addHelpMenu("package.jmri.jmrit.display.SetSensorsAtLevelXing", true); 11466 setSensorsAtLevelXingFrame.setLocation(70, 30); 11467 Container theContentPane = setSensorsAtLevelXingFrame.getContentPane(); 11468 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 11469 11470 JPanel panel11 = new JPanel(new FlowLayout()); 11471 11472 xingSensorsBlockACNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 11473 Bundle.getMessage("BeanNameBlock") + " AC " 11474 + Bundle.getMessage("Name"))); 11475 panel11.add(xingSensorsBlockACNameLabel); 11476 panel11.add(xingSensorsBlockACComboBox); 11477 xingSensorsBlockACComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 11478 theContentPane.add(panel11); 11479 11480 JPanel panel12 = new JPanel(new FlowLayout()); 11481 xingSensorsBlockBDNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 11482 Bundle.getMessage("BeanNameBlock") + " BD " 11483 + Bundle.getMessage("Name"))); 11484 panel12.add(xingSensorsBlockBDNameLabel); 11485 panel12.add(xingSensorsBlockBDComboBox); 11486 xingSensorsBlockBDComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 11487 theContentPane.add(panel12); 11488 11489 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 11490 11491 JPanel panel2 = new JPanel(new FlowLayout()); 11492 JLabel shTitle = new JLabel(Bundle.getMessage("BeanNameSensor")); 11493 panel2.add(shTitle); 11494 panel2.add(new JLabel(" ")); 11495 panel2.add(getSavedXingSensors = new JButton(Bundle.getMessage("GetSaved"))); 11496 getSavedXingSensors.addActionListener(this::xingSensorsGetSaved); 11497 getSavedXingSensors.setToolTipText(Bundle.getMessage("GetSavedHint")); 11498 theContentPane.add(panel2); 11499 11500 sensorXingPanel.setLayout(new GridLayout(0, 2)); 11501 theContentPane.add(sensorXingPanel); 11502 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 11503 11504 JPanel panel6 = new JPanel(new FlowLayout()); 11505 panel6.add(changeSensorXingIcon = new JButton(Bundle.getMessage("ChangeSensorIcon"))); 11506 changeSensorXingIcon.addActionListener((ActionEvent e) -> sensorXingFrame.setVisible(true)); 11507 changeSensorXingIcon.setToolTipText(Bundle.getMessage("ChangeSensorIconHint")); 11508 11509 panel6.add(new JLabel(" ")); 11510 panel6.add(setXingSensorsDone = new JButton(Bundle.getMessage("ButtonDone"))); 11511 setXingSensorsDone.addActionListener(this::setXingSensorsDonePressed); 11512 setXingSensorsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 11513 panel6.add(setXingSensorsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 11514 setXingSensorsCancel.addActionListener(this::setXingSensorsCancelPressed); 11515 setXingSensorsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 11516 theContentPane.add(panel6); 11517 setSensorsAtLevelXingFrame.addWindowListener(new WindowAdapter() { 11518 @Override 11519 public void windowClosing(WindowEvent e) { 11520 setXingSensorsCancelPressed(null); 11521 } 11522 }); 11523 } 11524 11525 sensorXingPanel.removeAll(); 11526 11527 xingSensorsBlockACComboBox.setVisible(!setSensorsAtLevelXingFromMenuFlag); 11528 xingSensorsBlockBDComboBox.setVisible(!setSensorsAtLevelXingFromMenuFlag); 11529 11530 if (setSensorsAtLevelXingFromMenuFlag) { 11531 xingSensorsBlockACNameLabel.setText(Bundle.getMessage("MakeLabel", 11532 Bundle.getMessage("BeanNameBlock") + " AC " 11533 + Bundle.getMessage("Name")) + " " + levelXing.getBlockNameAC()); 11534 xingSensorsBlockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 11535 Bundle.getMessage("BeanNameBlock") + " BD " 11536 + Bundle.getMessage("Name")) + " " + levelXing.getBlockNameBD()); 11537 11538 xingSensorA.setTextField(levelXing.getSensorAName()); 11539 xingSensorB.setTextField(levelXing.getSensorBName()); 11540 xingSensorC.setTextField(levelXing.getSensorCName()); 11541 xingSensorD.setTextField(levelXing.getSensorDName()); 11542 xingSensorsGetSaved(null); 11543 } else { 11544 xingSensorsBlockACNameLabel.setText(Bundle.getMessage("MakeLabel", 11545 Bundle.getMessage("BeanNameBlock") + " AC " 11546 + Bundle.getMessage("Name"))); 11547 xingSensorsBlockBDNameLabel.setText(Bundle.getMessage("MakeLabel", 11548 Bundle.getMessage("BeanNameBlock") + " BD " 11549 + Bundle.getMessage("Name"))); 11550 } 11551 11552 if (!setSensorsAtLevelXingOpenFlag) { 11553 setSensorsAtLevelXingFrame.setPreferredSize(null); 11554 setSensorsAtLevelXingFrame.pack(); 11555 setSensorsAtLevelXingOpenFlag = true; 11556 } 11557 setSensorsAtLevelXingFrame.setVisible(true); 11558 } 11559 11560 private void xingSensorsGetSaved(ActionEvent a) { 11561 if (!getLevelCrossingSensorInformation()) { 11562 return; 11563 } 11564 11565 xingSensorBlocks = levelXing.getBlockBoundaries(); 11566 11567 xingSensorA.setTextField(levelXing.getSensorAName()); 11568 xingSensorB.setTextField(levelXing.getSensorBName()); 11569 xingSensorC.setTextField(levelXing.getSensorCName()); 11570 xingSensorD.setTextField(levelXing.getSensorDName()); 11571 11572 sensorXingPanel.remove(xingSensorA.getDetailsPanel()); 11573 sensorXingPanel.remove(xingSensorB.getDetailsPanel()); 11574 sensorXingPanel.remove(xingSensorC.getDetailsPanel()); 11575 sensorXingPanel.remove(xingSensorD.getDetailsPanel()); 11576 11577 xingSensorA.setBoundaryLabel(xingSensorBlocks[0]); 11578 xingSensorB.setBoundaryLabel(xingSensorBlocks[1]); 11579 xingSensorC.setBoundaryLabel(xingSensorBlocks[2]); 11580 xingSensorD.setBoundaryLabel(xingSensorBlocks[3]); 11581 11582 boolean boundaryFlag = false; 11583 if (xingSensorBlocks[0] != null) { 11584 sensorXingPanel.add(xingSensorA.getDetailsPanel()); 11585 boundaryFlag = true; 11586 } 11587 if (xingSensorBlocks[1] != null) { 11588 sensorXingPanel.add(xingSensorB.getDetailsPanel()); 11589 boundaryFlag = true; 11590 } 11591 if (xingSensorBlocks[2] != null) { 11592 sensorXingPanel.add(xingSensorC.getDetailsPanel()); 11593 boundaryFlag = true; 11594 } 11595 if (xingSensorBlocks[3] != null) { 11596 sensorXingPanel.add(xingSensorD.getDetailsPanel()); 11597 boundaryFlag = true; 11598 } 11599 if (!boundaryFlag) { 11600 JmriJOptionPane.showMessageDialog(setSensorsAtLevelXingFrame, Bundle.getMessage("NoBoundaryXingSensor")); 11601 } 11602 setSensorsAtLevelXingFrame.setPreferredSize(null); 11603 setSensorsAtLevelXingFrame.pack(); 11604 } 11605 11606 private boolean getLevelCrossingSensorInformation() { 11607 if (!setSensorsAtLevelXingFromMenuFlag) { 11608 levelXing = null; 11609 List<LevelXing> levelXings = layoutEditor.getLevelXings(); 11610 if (levelXings.size() <= 0) { 11611 JmriJOptionPane.showMessageDialog(setSensorsAtLevelXingFrame, 11612 Bundle.getMessage("SignalsError15"), 11613 Bundle.getMessage("ErrorTitle"), 11614 JmriJOptionPane.ERROR_MESSAGE); 11615 return false; 11616 } else if (levelXings.size() == 1) { 11617 levelXing = levelXings.get(0); 11618 } else { 11619 LayoutBlock xingSensorBlockA = null; 11620 LayoutBlock xingSensorBlockC = null; 11621 xingSensorBlockA = getBlockFromEntry(xingSensorsBlockACComboBox); 11622 if (xingSensorBlockA == null) { 11623 return false; 11624 } 11625 String theBlockName = xingSensorsBlockBDComboBox.getSelectedItemDisplayName(); 11626 if ((theBlockName != null) && !theBlockName.isEmpty()) { 11627 xingSensorBlockC = getBlockFromEntry(xingSensorsBlockBDComboBox); 11628 if (xingSensorBlockC == null) { 11629 return false; 11630 } 11631 } 11632 11633 int foundCount = 0; 11634 //make two block tests first 11635 if (xingSensorBlockC != null) { 11636 for (LevelXing x : layoutEditor.getLevelXings()) { 11637 LayoutBlock xA = null; 11638 LayoutBlock xB = null; 11639 LayoutBlock xC = null; 11640 LayoutBlock xD = null; 11641 LayoutBlock xAC = x.getLayoutBlockAC(); 11642 LayoutBlock xBD = x.getLayoutBlockBD(); 11643 if (x.getConnectA() != null) { 11644 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 11645 } 11646 if (x.getConnectB() != null) { 11647 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 11648 } 11649 if (x.getConnectC() != null) { 11650 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 11651 } 11652 if (x.getConnectD() != null) { 11653 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 11654 } 11655 if (((xA != null) && (xC != null) && (((xA == xingSensorBlockA) && (xC == xingSensorBlockC)) 11656 || ((xA == xingSensorBlockC) && (xC == xingSensorBlockA)))) 11657 || ((xB != null) && (xD != null) && (((xB == xingSensorBlockA) && (xD == xingSensorBlockC)) 11658 || ((xB == xingSensorBlockC) && (xD == xingSensorBlockA))))) { 11659 levelXing = x; 11660 foundCount++; 11661 } else if ((xAC != null) && (xBD != null) && (((xAC == xingSensorBlockA) && (xBD == xingSensorBlockC)) 11662 || ((xAC == xingSensorBlockC) && (xBD == xingSensorBlockA)))) { 11663 levelXing = x; 11664 foundCount++; 11665 } 11666 } 11667 } 11668 if (foundCount == 0) { 11669 //try one block test 11670 for (LevelXing x : layoutEditor.getLevelXings()) { 11671 if ((xingSensorBlockA == x.getLayoutBlockAC()) || (xingSensorBlockA == x.getLayoutBlockBD())) { 11672 levelXing = x; 11673 foundCount++; 11674 } 11675 } 11676 } 11677 if (foundCount > 1) { 11678 JmriJOptionPane.showMessageDialog(setSensorsAtLevelXingFrame, 11679 Bundle.getMessage("SignalsError16", 11680 new Object[]{" " + foundCount + " "}), 11681 Bundle.getMessage("ErrorTitle"), 11682 JmriJOptionPane.ERROR_MESSAGE); 11683 return false; 11684 } 11685 if (levelXing == null) { 11686 JmriJOptionPane.showMessageDialog(setSensorsAtLevelXingFrame, 11687 Bundle.getMessage("SignalsError17"), 11688 Bundle.getMessage("ErrorTitle"), 11689 JmriJOptionPane.ERROR_MESSAGE); 11690 return false; 11691 } 11692 } 11693 } 11694 return true; 11695 } 11696 11697 private void setXingSensorsCancelPressed(ActionEvent a) { 11698 setSensorsAtLevelXingOpenFlag = false; 11699 setSensorsAtLevelXingFrame.setVisible(false); 11700 } 11701 11702 private void setXingSensorsDonePressed(ActionEvent a) { 11703 log.trace("setXingSensorsDonePressed"); // NOI18N 11704 11705 if (!getLevelCrossingSensorInformation()) { 11706 return; 11707 } 11708 11709 Sensor aSensor = getSensorFromEntry(xingSensorA.getText(), false, setSensorsAtLevelXingFrame); 11710 Sensor bSensor = getSensorFromEntry(xingSensorB.getText(), false, setSensorsAtLevelXingFrame); 11711 Sensor cSensor = getSensorFromEntry(xingSensorC.getText(), false, setSensorsAtLevelXingFrame); 11712 Sensor dSensor = getSensorFromEntry(xingSensorD.getText(), false, setSensorsAtLevelXingFrame); 11713 11714 Sensor currSensorA = levelXing.getSensorA(); 11715 Sensor currSensorB = levelXing.getSensorB(); 11716 Sensor currSensorC = levelXing.getSensorC(); 11717 Sensor currSensorD = levelXing.getSensorD(); 11718 11719 if (log.isTraceEnabled()) { 11720 log.trace("current sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 11721 (currSensorA == null) ? "- none- " : currSensorA.getDisplayName(), // NOI18N 11722 (currSensorB == null) ? "- none- " : currSensorB.getDisplayName(), // NOI18N 11723 (currSensorC == null) ? "- none- " : currSensorC.getDisplayName(), // NOI18N 11724 (currSensorD == null) ? "- none- " : currSensorD.getDisplayName()); // NOI18N 11725 log.trace("new sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 11726 (aSensor == null) ? "- none- " : aSensor.getDisplayName(), // NOI18N 11727 (bSensor == null) ? "- none- " : bSensor.getDisplayName(), // NOI18N 11728 (cSensor == null) ? "- none- " : cSensor.getDisplayName(), // NOI18N 11729 (dSensor == null) ? "- none- " : dSensor.getDisplayName()); // NOI18N 11730 } 11731 11732 LevelXingView levelXingView = layoutEditor.getLevelXingView(levelXing); 11733 // place/remove sensors as requested 11734 if (aSensor == null) { 11735 if (currSensorA != null && removeSensorFromPanel(currSensorA)) { 11736 levelXing.setSensorAName(null); 11737 } 11738 } else if (xingSensorA != null && levelXing.getConnectA() != null) { 11739 setLevelXingSensor(aSensor, currSensorA, xingSensorA, levelXing.getConnectA(), levelXingView.getCoordsA(), "A"); 11740 } 11741 11742 if (bSensor == null) { 11743 if (currSensorB != null && removeSensorFromPanel(currSensorB)) { 11744 levelXing.setSensorBName(null); 11745 } 11746 } else if (xingSensorB != null && levelXing.getConnectB() != null) { 11747 setLevelXingSensor(bSensor, currSensorB, xingSensorB, levelXing.getConnectB(), levelXingView.getCoordsB(), "B"); 11748 } 11749 11750 if (cSensor == null) { 11751 if (currSensorC != null && removeSensorFromPanel(currSensorC)) { 11752 levelXing.setSensorCName(null); 11753 } 11754 } else if (xingSensorC != null && levelXing.getConnectC() != null) { 11755 setLevelXingSensor(cSensor, currSensorC, xingSensorC, levelXing.getConnectC(), levelXingView.getCoordsC(), "C"); 11756 } 11757 11758 if (dSensor == null) { 11759 if (currSensorD != null && removeSensorFromPanel(currSensorD)) { 11760 levelXing.setSensorDName(null); 11761 } 11762 } else if (xingSensorD != null && levelXing.getConnectD() != null) { 11763 setLevelXingSensor(dSensor, currSensorD, xingSensorD, levelXing.getConnectD(), levelXingView.getCoordsD(), "D"); 11764 } 11765 11766 //setup logic if requested 11767 //finish up 11768 setSensorsAtLevelXingOpenFlag = false; 11769 setSensorsAtLevelXingFrame.setVisible(false); 11770 if (needRedraw) { 11771 layoutEditor.redrawPanel(); 11772 needRedraw = false; 11773 layoutEditor.setDirty(); 11774 } 11775 } 11776 11777 /** 11778 * Attached a sensor to a level crossing block boundary. 11779 * 11780 * @since 4.11.2 11781 * @param newSensor The sensor that is being added. 11782 * @param currSensor The sensor that might already be there, otherwise null. 11783 * @param beanDetail The BeanDetails object that contains the supporting 11784 * data. 11785 * @param connect The track segment that is attached to this point 11786 * @param coords The track componennt coordinates 11787 * @param position Which of the four points is being changed 11788 */ 11789 void setLevelXingSensor(Sensor newSensor, Sensor currSensor, BeanDetails<? extends NamedBean> beanDetail, 11790 LayoutTrack connect, Point2D coords, String position) { 11791 if (currSensor == null) { 11792 if (!isSensorAssignedAnywhere(newSensor)) { 11793 log.trace("Add sensor '{}'", newSensor.getDisplayName()); // NOI18N 11794 switch (position) { 11795 case "A": // NOI18N 11796 levelXing.setSensorAName(beanDetail.getText()); 11797 break; 11798 case "B": // NOI18N 11799 levelXing.setSensorBName(beanDetail.getText()); 11800 break; 11801 case "C": // NOI18N 11802 levelXing.setSensorCName(beanDetail.getText()); 11803 break; 11804 case "D": // NOI18N 11805 levelXing.setSensorDName(beanDetail.getText()); 11806 break; 11807 default: 11808 break; 11809 } 11810 if (beanDetail.addToPanel()) { 11811 log.trace("Add icon for sensor '{}'", newSensor.getDisplayName()); // NOI18N 11812 placingBlock(getSensorIcon(beanDetail.getText()), 11813 beanDetail.isRightSelected(), 0.0, connect, coords); 11814 needRedraw = true; 11815 } 11816 } else { 11817 sensorAssignedElseWhere(newSensor); 11818 } 11819 } else if (currSensor == newSensor) { 11820 if (beanDetail.addToPanel()) { 11821 if (!isSensorOnPanel(newSensor)) { 11822 log.trace("Add icon for existing sensor '{}'", newSensor.getDisplayName()); // NOI18N 11823 placingBlock(getSensorIcon(beanDetail.getText()), 11824 beanDetail.isRightSelected(), 0.0, connect, coords); 11825 needRedraw = true; 11826 } 11827 } 11828 } else { 11829 if (!isSensorAssignedAnywhere(newSensor)) { 11830 if (removeSensorFromPanel(currSensor)) { 11831 log.trace("Replace sensor '{}' with sensor '{}'", // NOI18N 11832 currSensor.getDisplayName(), newSensor.getDisplayName()); 11833 switch (position) { 11834 case "A": // NOI18N 11835 levelXing.setSensorAName(beanDetail.getText()); 11836 break; 11837 case "B": // NOI18N 11838 levelXing.setSensorBName(beanDetail.getText()); 11839 break; 11840 case "C": // NOI18N 11841 levelXing.setSensorCName(beanDetail.getText()); 11842 break; 11843 case "D": // NOI18N 11844 levelXing.setSensorDName(beanDetail.getText()); 11845 break; 11846 default: 11847 break; 11848 } 11849 if (beanDetail.addToPanel()) { 11850 log.trace("Add icon for replacement sensor '{}'", // NOI18N 11851 newSensor.getDisplayName()); 11852 placingBlock(getSensorIcon(beanDetail.getText()), 11853 beanDetail.isRightSelected(), 0.0, connect, coords); 11854 needRedraw = true; 11855 } 11856 } 11857 } else { 11858 sensorAssignedElseWhere(newSensor); 11859 } 11860 } 11861 } 11862 11863 private boolean getSimpleBlockInformation() { 11864 //might have to do something to trick it with an end bumper 11865 if (!setSignalMastsAtBlockBoundaryFromMenuFlag) { 11866 block1 = getBlockFromEntry(block1IDComboBox); 11867 if (block1 == null) { 11868 return false; 11869 } 11870 block2 = getBlockFromEntry(block2IDComboBox); 11871 boundary = null; 11872 //if block2 is undefined or same as block 1 11873 if (block2 == null || (block1 == block2)) { 11874 //find the 1st positionablePoint that's connect1'ed to block1 11875 for (PositionablePoint p : layoutEditor.getPositionablePoints()) { 11876 if (p.getType() == PositionablePoint.PointType.END_BUMPER) { 11877 if (p.getConnect1() != null && p.getConnect1().getLayoutBlock() == block1) { 11878 boundary = p; 11879 break; 11880 } 11881 } 11882 } 11883 } 11884 11885 //now we try to find an anchor that connected to blocks 1 and 2 11886 //(if this fails boundary will still be set to the pp set if 11887 //block2 was null or equal to block1 above.) 11888 for (PositionablePoint p : layoutEditor.getPositionablePoints()) { 11889 if (p.getType() != PositionablePoint.PointType.END_BUMPER) { 11890 LayoutBlock bA = null; 11891 LayoutBlock bB = null; 11892 if (p.getConnect1() != null) { 11893 bA = p.getConnect1().getLayoutBlock(); 11894 } 11895 if (p.getConnect2() != null) { 11896 bB = p.getConnect2().getLayoutBlock(); 11897 } 11898 if ((bA != null) && (bB != null) && (bA != bB)) { 11899 if (((bA == block1) && (bB == block2)) 11900 || ((bA == block2) && (bB == block1))) { 11901 boundary = p; 11902 break; 11903 } 11904 } 11905 } 11906 } 11907 //if all that failed... 11908 if (boundary == null) { 11909 JmriJOptionPane.showMessageDialog(setSignalsAtBlockBoundaryFrame, 11910 Bundle.getMessage("SignalsError7"), 11911 Bundle.getMessage("ErrorTitle"), 11912 JmriJOptionPane.ERROR_MESSAGE); 11913 return false; 11914 } 11915 } 11916 return true; 11917 } 11918 11919 /*==================*\ 11920 |* setSensorsAtSlip *| 11921 \*==================*/ 11922 //operational variables for Set Sensors at Slip tool 11923 private JmriJFrame setSensorsAtSlipFrame = null; 11924 private boolean setSensorsAtSlipOpenFlag = false; 11925 private boolean setSensorsAtSlipFromMenuFlag = false; 11926 11927 private JButton getSavedSlipSensors = null; 11928 private JButton setSlipSensorsDone = null; 11929 private JButton setSlipSensorsCancel = null; 11930 private JButton changeSensorSlipIcon = null; 11931 JFrame sensorSlipFrame = null; 11932 11933 private final NamedBeanComboBox<Block> slipSensorsBlockAComboBox 11934 = new NamedBeanComboBox<>( 11935 InstanceManager.getDefault(BlockManager.class), 11936 null, DisplayOptions.DISPLAYNAME); 11937 private final NamedBeanComboBox<Block> slipSensorsBlockBComboBox 11938 = new NamedBeanComboBox<>( 11939 InstanceManager.getDefault(BlockManager.class), 11940 null, DisplayOptions.DISPLAYNAME); 11941 private final NamedBeanComboBox<Block> slipSensorsBlockCComboBox 11942 = new NamedBeanComboBox<>( 11943 InstanceManager.getDefault(BlockManager.class), 11944 null, DisplayOptions.DISPLAYNAME); 11945 private final NamedBeanComboBox<Block> slipSensorsBlockDComboBox 11946 = new NamedBeanComboBox<>( 11947 InstanceManager.getDefault(BlockManager.class), 11948 null, DisplayOptions.DISPLAYNAME); 11949 11950 private String[] slipSensorBlocks = new String[4]; 11951 11952 BeanDetails<Sensor> slipSensorA; 11953 BeanDetails<Sensor> slipSensorB; 11954 BeanDetails<Sensor> slipSensorC; 11955 BeanDetails<Sensor> slipSensorD; 11956 11957 JPanel sensorSlipPanel = new JPanel(new FlowLayout()); 11958 11959 //display dialog for Set Signals at Level Crossing tool 11960 public void setSensorsAtSlipFromMenu(@Nonnull LayoutSlip slip, 11961 @Nonnull String[] blocks, 11962 @Nonnull MultiIconEditor theEditor, 11963 @Nonnull JFrame theFrame) { 11964 layoutSlip = slip; 11965 BlockManager bm = InstanceManager.getDefault(BlockManager.class); 11966 slipSensorsBlockAComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockName())); 11967 slipSensorsBlockBComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockBName())); 11968 slipSensorsBlockCComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockCName())); 11969 slipSensorsBlockDComboBox.setSelectedItem(bm.getBlock(layoutSlip.getBlockDName())); 11970 for (int i = 0; i < blocks.length; i++) { 11971 slipSensorBlocks[i] = blocks[i]; 11972 } 11973 setSensorsAtSlipFromMenuFlag = true; 11974 setSensorsAtSlip(theEditor, theFrame); 11975 setSensorsAtSlipFromMenuFlag = false; 11976 } 11977 11978 //TODO: Add to Tools menu? 11979 public void setSensorsAtSlip(@Nonnull MultiIconEditor theEditor, 11980 @Nonnull JFrame theFrame) { 11981 sensorIconEditor = theEditor; 11982 sensorSlipFrame = theFrame; 11983 11984 //Initialize if needed 11985 if (setSensorsAtSlipFrame == null) { 11986 setSensorsAtSlipOpenFlag = false; 11987 11988 slipSensorA = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11989 slipSensorB = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11990 slipSensorC = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11991 slipSensorD = new BeanDetails<>("Sensor", InstanceManager.sensorManagerInstance()); 11992 11993 slipSensorA.getDetailsPanel().setBackground(new Color(255, 255, 200)); 11994 slipSensorB.getDetailsPanel().setBackground(new Color(200, 255, 255)); 11995 slipSensorC.getDetailsPanel().setBackground(new Color(200, 200, 255)); 11996 slipSensorD.getDetailsPanel().setBackground(new Color(255, 200, 200)); 11997 11998 setSensorsAtSlipFrame = new JmriJFrame(Bundle.getMessage("SensorsAtSlip"), false, true); 11999 oneFrameToRuleThemAll(setSensorsAtSlipFrame); 12000 setSensorsAtSlipFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 12001// setSensorsAtSlipFrame.addHelpMenu("package.jmri.jmrit.display.SetSensorsAtLevelSlip", true); 12002 setSensorsAtSlipFrame.setLocation(70, 30); 12003 Container theContentPane = setSensorsAtSlipFrame.getContentPane(); 12004 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 12005 12006 JPanel panel11A = new JPanel(new FlowLayout()); 12007 slipSignalBlockANameLabel = new JLabel(Bundle.getMessage("MakeLabel", 12008 Bundle.getMessage("BeanNameBlock") + " A " 12009 + Bundle.getMessage("Name"))); 12010 panel11A.add(slipSignalBlockANameLabel); 12011 panel11A.add(slipSensorsBlockAComboBox); 12012 slipSensorsBlockAComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 12013 theContentPane.add(panel11A); 12014 12015 JPanel panel11B = new JPanel(new FlowLayout()); 12016 slipSignalBlockBNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 12017 Bundle.getMessage("BeanNameBlock") + " B " 12018 + Bundle.getMessage("Name"))); 12019 panel11B.add(slipSignalBlockBNameLabel); 12020 panel11B.add(slipSensorsBlockBComboBox); 12021 slipSensorsBlockBComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 12022 theContentPane.add(panel11B); 12023 12024 JPanel panel11C = new JPanel(new FlowLayout()); 12025 slipSignalBlockCNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 12026 Bundle.getMessage("BeanNameBlock") + " C " 12027 + Bundle.getMessage("Name"))); 12028 panel11C.add(slipSignalBlockCNameLabel); 12029 panel11C.add(slipSensorsBlockCComboBox); 12030 slipSensorsBlockCComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 12031 theContentPane.add(panel11C); 12032 12033 JPanel panel11D = new JPanel(new FlowLayout()); 12034 slipSignalBlockDNameLabel = new JLabel(Bundle.getMessage("MakeLabel", 12035 Bundle.getMessage("BeanNameBlock") + " D " 12036 + Bundle.getMessage("Name"))); 12037 panel11D.add(slipSignalBlockDNameLabel); 12038 panel11D.add(slipSensorsBlockDComboBox); 12039 slipSensorsBlockDComboBox.setToolTipText(Bundle.getMessage("SensorsBlockNameHint")); 12040 theContentPane.add(panel11D); 12041 12042 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12043 12044 JPanel panel2 = new JPanel(new FlowLayout()); 12045 JLabel shTitle = new JLabel(Bundle.getMessage("BeanNameSensor")); 12046 panel2.add(shTitle); 12047 panel2.add(new JLabel(" ")); 12048 panel2.add(getSavedSlipSensors = new JButton(Bundle.getMessage("GetSaved"))); 12049 getSavedSlipSensors.addActionListener(this::slipSensorsGetSaved); 12050 getSavedSlipSensors.setToolTipText(Bundle.getMessage("GetSavedHint")); 12051 theContentPane.add(panel2); 12052 12053 sensorSlipPanel.setLayout(new GridLayout(0, 2)); 12054 theContentPane.add(sensorSlipPanel); 12055 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12056 12057 JPanel panel6 = new JPanel(new FlowLayout()); 12058 panel6.add(changeSensorSlipIcon = new JButton(Bundle.getMessage("ChangeSensorIcon"))); 12059 changeSensorSlipIcon.addActionListener((ActionEvent e) -> sensorSlipFrame.setVisible(true)); 12060 changeSensorSlipIcon.setToolTipText(Bundle.getMessage("ChangeSensorIconHint")); 12061 12062 panel6.add(new JLabel(" ")); 12063 panel6.add(setSlipSensorsDone = new JButton(Bundle.getMessage("ButtonDone"))); 12064 setSlipSensorsDone.addActionListener(this::setSlipSensorsDonePressed); 12065 setSlipSensorsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 12066 panel6.add(setSlipSensorsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 12067 setSlipSensorsCancel.addActionListener(this::setSlipSensorsCancelPressed); 12068 setSlipSensorsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 12069 theContentPane.add(panel6); 12070 setSensorsAtSlipFrame.addWindowListener(new WindowAdapter() { 12071 @Override 12072 public void windowClosing(WindowEvent e) { 12073 setSlipSensorsCancelPressed(null); 12074 } 12075 }); 12076 } //if (setSensorsAtSlipFrame == null) 12077 12078 sensorSlipPanel.removeAll(); 12079 12080 slipSensorsBlockAComboBox.setVisible(!setSensorsAtSlipFromMenuFlag); 12081 slipSensorsBlockBComboBox.setVisible(!setSensorsAtSlipFromMenuFlag); 12082 slipSensorsBlockCComboBox.setVisible(!setSensorsAtSlipFromMenuFlag); 12083 slipSensorsBlockDComboBox.setVisible(!setSensorsAtSlipFromMenuFlag); 12084 12085 if (setSensorsAtSlipFromMenuFlag) { 12086 slipSignalBlockANameLabel.setText(Bundle.getMessage("MakeLabel", 12087 Bundle.getMessage("BeanNameBlock") + " A " 12088 + Bundle.getMessage("Name")) + " " + layoutSlip.getBlockName()); 12089 slipSignalBlockBNameLabel.setText(Bundle.getMessage("MakeLabel", 12090 Bundle.getMessage("BeanNameBlock") + " B " 12091 + Bundle.getMessage("Name")) + " " + layoutSlip.getBlockBName()); 12092 slipSignalBlockCNameLabel.setText(Bundle.getMessage("MakeLabel", 12093 Bundle.getMessage("BeanNameBlock") + " C " 12094 + Bundle.getMessage("Name")) + " " + layoutSlip.getBlockCName()); 12095 slipSignalBlockDNameLabel.setText(Bundle.getMessage("MakeLabel", 12096 Bundle.getMessage("BeanNameBlock") + " D " 12097 + Bundle.getMessage("Name")) + " " + layoutSlip.getBlockDName()); 12098 slipSensorsGetSaved(null); 12099 } else { 12100 slipSignalBlockANameLabel.setText(Bundle.getMessage("MakeLabel", 12101 Bundle.getMessage("BeanNameBlock") + " A " 12102 + Bundle.getMessage("Name"))); 12103 slipSignalBlockBNameLabel.setText(Bundle.getMessage("MakeLabel", 12104 Bundle.getMessage("BeanNameBlock") + " B " 12105 + Bundle.getMessage("Name"))); 12106 slipSignalBlockCNameLabel.setText(Bundle.getMessage("MakeLabel", 12107 Bundle.getMessage("BeanNameBlock") + " C " 12108 + Bundle.getMessage("Name"))); 12109 slipSignalBlockDNameLabel.setText(Bundle.getMessage("MakeLabel", 12110 Bundle.getMessage("BeanNameBlock") + " D " 12111 + Bundle.getMessage("Name"))); 12112 } 12113 12114 if (setSensorsAtSlipOpenFlag) { 12115 slipSensorsGetSaved(null); 12116 } else { 12117 setSensorsAtSlipFrame.setPreferredSize(null); 12118 setSensorsAtSlipFrame.setVisible(true); 12119 setSensorsAtSlipOpenFlag = true; 12120 } 12121 setSensorsAtSlipFrame.setPreferredSize(null); 12122 setSensorsAtSlipFrame.pack(); 12123 } 12124 12125 private void slipSensorsGetSaved(ActionEvent a) { 12126 if (!getSlipSensorInformation()) { 12127 return; 12128 } 12129 12130 slipSensorBlocks = layoutSlip.getBlockBoundaries(); 12131 12132 slipSensorA.setTextField(layoutSlip.getSensorAName()); 12133 slipSensorB.setTextField(layoutSlip.getSensorBName()); 12134 slipSensorC.setTextField(layoutSlip.getSensorCName()); 12135 slipSensorD.setTextField(layoutSlip.getSensorDName()); 12136 12137 sensorSlipPanel.remove(slipSensorA.getDetailsPanel()); 12138 sensorSlipPanel.remove(slipSensorB.getDetailsPanel()); 12139 sensorSlipPanel.remove(slipSensorC.getDetailsPanel()); 12140 sensorSlipPanel.remove(slipSensorD.getDetailsPanel()); 12141 12142 slipSensorA.setBoundaryLabel(slipSensorBlocks[0]); 12143 slipSensorB.setBoundaryLabel(slipSensorBlocks[1]); 12144 slipSensorC.setBoundaryLabel(slipSensorBlocks[2]); 12145 slipSensorD.setBoundaryLabel(slipSensorBlocks[3]); 12146 12147 boolean boundaryFlag = false; 12148 if (slipSensorBlocks[0] != null) { 12149 sensorSlipPanel.add(slipSensorA.getDetailsPanel()); 12150 boundaryFlag = true; 12151 } 12152 if (slipSensorBlocks[1] != null) { 12153 sensorSlipPanel.add(slipSensorB.getDetailsPanel()); 12154 boundaryFlag = true; 12155 } 12156 if (slipSensorBlocks[2] != null) { 12157 sensorSlipPanel.add(slipSensorC.getDetailsPanel()); 12158 boundaryFlag = true; 12159 } 12160 if (slipSensorBlocks[3] != null) { 12161 sensorSlipPanel.add(slipSensorD.getDetailsPanel()); 12162 boundaryFlag = true; 12163 } 12164 if (!boundaryFlag) { 12165 JmriJOptionPane.showMessageDialog(setSensorsAtSlipFrame, Bundle.getMessage("NoBoundarySlipSensor")); 12166 } 12167 setSensorsAtSlipFrame.setPreferredSize(null); 12168 setSensorsAtSlipFrame.pack(); 12169 } 12170 12171 private boolean getSlipSensorInformation() { 12172 if (!setSensorsAtSlipFromMenuFlag) { 12173 layoutSlip = null; 12174 List<LayoutSlip> layoutSlips = layoutEditor.getLayoutSlips(); 12175 if (layoutSlips.size() <= 0) { 12176 JmriJOptionPane.showMessageDialog(setSensorsAtSlipFrame, 12177 Bundle.getMessage("SignalsError15"), 12178 Bundle.getMessage("ErrorTitle"), 12179 JmriJOptionPane.ERROR_MESSAGE); 12180 return false; 12181 } else if (layoutSlips.size() == 1) { 12182 layoutSlip = layoutSlips.get(0); 12183 } else { 12184 LayoutBlock slipSensorBlockA = null; 12185 slipSensorBlockA = getBlockFromEntry(slipSensorsBlockAComboBox); 12186 if (slipSensorBlockA == null) { 12187 return false; 12188 } 12189 12190 int foundCount = 0; 12191 for (LayoutSlip x : layoutEditor.getLayoutSlips()) { 12192 LayoutBlock xA = null; 12193 LayoutBlock xB = null; 12194 LayoutBlock xC = null; 12195 LayoutBlock xD = null; 12196 12197 LayoutBlock xAC = x.getLayoutBlock(); 12198 if (x.getConnectA() != null) { 12199 xA = ((TrackSegment) x.getConnectA()).getLayoutBlock(); 12200 } 12201 if (x.getConnectB() != null) { 12202 xB = ((TrackSegment) x.getConnectB()).getLayoutBlock(); 12203 } 12204 if (x.getConnectC() != null) { 12205 xC = ((TrackSegment) x.getConnectC()).getLayoutBlock(); 12206 } 12207 if (x.getConnectD() != null) { 12208 xD = ((TrackSegment) x.getConnectD()).getLayoutBlock(); 12209 } 12210 if (((xA != null) && (xC != null) && ((xA == slipSensorBlockA) 12211 || (xC == slipSensorBlockA))) 12212 || ((xB != null) && (xD != null) && (((xB == slipSensorBlockA)) 12213 || ((xD == slipSensorBlockA))))) { 12214 layoutSlip = x; 12215 foundCount++; 12216 } else if ((xAC != null) && (xAC == slipSensorBlockA)) { 12217 layoutSlip = x; 12218 foundCount++; 12219 } 12220 } 12221 if (foundCount == 0) { 12222 //try one block test 12223 for (LayoutSlip x : layoutEditor.getLayoutSlips()) { 12224 if (slipSensorBlockA == x.getLayoutBlock()) { 12225 layoutSlip = x; 12226 foundCount++; 12227 } 12228 } 12229 } 12230 if (foundCount > 1) { 12231 JmriJOptionPane.showMessageDialog(setSensorsAtSlipFrame, 12232 Bundle.getMessage("SignalsError16", 12233 new Object[]{" " + foundCount + " "}), 12234 Bundle.getMessage("ErrorTitle"), 12235 JmriJOptionPane.ERROR_MESSAGE); 12236 return false; 12237 } 12238 if (layoutSlip == null) { 12239 JmriJOptionPane.showMessageDialog(setSensorsAtSlipFrame, 12240 Bundle.getMessage("SignalsError17"), 12241 Bundle.getMessage("ErrorTitle"), 12242 JmriJOptionPane.ERROR_MESSAGE); 12243 return false; 12244 } 12245 } 12246 } 12247 return true; 12248 } 12249 12250 private void setSlipSensorsCancelPressed(ActionEvent a) { 12251 setSensorsAtSlipOpenFlag = false; 12252 setSensorsAtSlipFrame.setVisible(false); 12253 } 12254 12255 private void setSlipSensorsDonePressed(ActionEvent a) { 12256 log.trace("setSlipSensorsDonePressed"); 12257 if (!getSlipSensorInformation()) { 12258 return; 12259 } 12260 12261 Sensor sensorA = getSensorFromEntry(slipSensorA.getText(), false, setSensorsAtSlipFrame); 12262 Sensor sensorB = getSensorFromEntry(slipSensorB.getText(), false, setSensorsAtSlipFrame); 12263 Sensor sensorC = getSensorFromEntry(slipSensorC.getText(), false, setSensorsAtSlipFrame); 12264 Sensor sensorD = getSensorFromEntry(slipSensorD.getText(), false, setSensorsAtSlipFrame); 12265 12266 Sensor currSensorA = layoutSlip.getSensorA(); 12267 Sensor currSensorB = layoutSlip.getSensorB(); 12268 Sensor currSensorC = layoutSlip.getSensorC(); 12269 Sensor currSensorD = layoutSlip.getSensorD(); 12270 12271 if (log.isTraceEnabled()) { 12272 log.trace("current sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 12273 (currSensorA == null) ? "- none- " : currSensorA.getDisplayName(), // NOI18N 12274 (currSensorB == null) ? "- none- " : currSensorB.getDisplayName(), // NOI18N 12275 (currSensorC == null) ? "- none- " : currSensorC.getDisplayName(), // NOI18N 12276 (currSensorD == null) ? "- none- " : currSensorD.getDisplayName()); // NOI18N 12277 log.trace("new sensors: A = {}, B = {}, C = {}, D = {}", // NOI18N 12278 (sensorA == null) ? "- none- " : sensorA.getDisplayName(), // NOI18N 12279 (sensorB == null) ? "- none- " : sensorB.getDisplayName(), // NOI18N 12280 (sensorC == null) ? "- none- " : sensorC.getDisplayName(), // NOI18N 12281 (sensorD == null) ? "- none- " : sensorD.getDisplayName()); // NOI18N 12282 } 12283 12284 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 12285 12286 //place/remove sensors as requested 12287 if (sensorA == null) { 12288 if (currSensorA != null && removeSensorFromPanel(currSensorA)) { 12289 layoutSlip.setSensorA(null); 12290 } 12291 } else if (slipSensorA != null && layoutSlip.getConnectA() != null) { 12292 setTurnoutSensor(layoutSlip, sensorA, currSensorA, slipSensorA, layoutSlip.getConnectA(), layoutSlipView.getCoordsA(), "A"); 12293 } 12294 12295 if (sensorB == null) { 12296 if (currSensorB != null && removeSensorFromPanel(currSensorB)) { 12297 layoutSlip.setSensorB(null); 12298 } 12299 } else if (slipSensorB != null && layoutSlip.getConnectB() != null) { 12300 setTurnoutSensor(layoutSlip, sensorB, currSensorB, slipSensorB, layoutSlip.getConnectB(), layoutSlipView.getCoordsB(), "B"); 12301 } 12302 12303 if (sensorC == null) { 12304 if (currSensorC != null && removeSensorFromPanel(currSensorC)) { 12305 layoutSlip.setSensorC(null); 12306 } 12307 } else if (slipSensorC != null && layoutSlip.getConnectC() != null) { 12308 setTurnoutSensor(layoutSlip, sensorC, currSensorC, slipSensorC, layoutSlip.getConnectC(), layoutSlipView.getCoordsC(), "C"); 12309 } 12310 12311 if (sensorD == null) { 12312 if (currSensorD != null && removeSensorFromPanel(currSensorD)) { 12313 layoutSlip.setSensorD(null); 12314 } 12315 } else if (slipSensorD != null && layoutSlip.getConnectD() != null) { 12316 setTurnoutSensor(layoutSlip, sensorD, currSensorD, slipSensorD, layoutSlip.getConnectD(), layoutSlipView.getCoordsD(), "D"); 12317 } 12318 12319 //setup logic if requested 12320 //finish up 12321 setSensorsAtSlipOpenFlag = false; 12322 setSensorsAtSlipFrame.setVisible(false); 12323 if (needRedraw) { 12324 layoutEditor.redrawPanel(); 12325 needRedraw = false; 12326 layoutEditor.setDirty(); 12327 12328 } 12329 } 12330 12331 static class BeanDetails<B extends NamedBean> { 12332 12333 private final String bundleName; 12334 private final String beanString; 12335 private final JLabel textLabel; 12336 12337 private final String boundaryLabelText = Bundle.getMessage("BoundaryOf"); 12338 private final JLabel boundaryLabel = new JLabel(boundaryLabelText); 12339 12340 private final Manager<B> manager; 12341 12342 private final JPanel detailsPanel = new JPanel(new FlowLayout()); 12343 private final JRadioButton addBeanCheck = new JRadioButton(Bundle.getMessage("DoNotPlace")); 12344 private final JRadioButton left = new JRadioButton(Bundle.getMessage("LeftHandSide")); 12345 private final JRadioButton right = new JRadioButton(Bundle.getMessage("RightHandSide")); 12346 private final ButtonGroup buttonGroup = new ButtonGroup(); 12347 private final NamedBeanComboBox<B> beanCombo; 12348 12349 private final JLabel boundaryBlocks = new JLabel(); 12350 12351 private final Border blackline = BorderFactory.createLineBorder(Color.black); 12352 12353 BeanDetails(@Nonnull String beanType, @Nonnull Manager<B> manager) { 12354 beanCombo = new NamedBeanComboBox<>(manager); 12355 beanCombo.setAllowNull(true); 12356 JComboBoxUtil.setupComboBoxMaxRows(beanCombo); 12357 //I18N translate from type (Sensor) to BeanNameSensor 12358 //to use NamedBeanBundle property 12359 if ("Sensor".equals(beanType)) { 12360 bundleName = "BeanNameSensor"; 12361 } else if ("SignalMast".equals(beanType)) { 12362 bundleName = "BeanNameSignalMast"; 12363 } else { 12364 log.error("Unexpected value for BeanDetails: '{}'", beanType); 12365 bundleName = beanType; 12366 } 12367 beanString = Bundle.getMessage(bundleName); 12368 textLabel = new JLabel(beanString); 12369 this.manager = manager; 12370 //this.beanType = beanType; 12371 12372 buttonGroup.add(addBeanCheck); 12373 buttonGroup.add(left); 12374 buttonGroup.add(right); 12375 addBeanCheck.setSelected(true); 12376 12377 boundaryBlocks.setAlignmentX(Component.CENTER_ALIGNMENT); 12378 boundaryBlocks.setOpaque(false); 12379 detailsPanel.setLayout(new BorderLayout()); 12380 detailsPanel.setBorder(BorderFactory.createTitledBorder(blackline, Bundle.getMessage("BlockBoundary"))); 12381 boundaryLabel.setAlignmentX(Component.CENTER_ALIGNMENT); 12382 12383 JPanel boundaryDetails = new JPanel(new FlowLayout()); 12384 boundaryDetails.setOpaque(false); 12385 boundaryDetails.setLayout(new BoxLayout(boundaryDetails, BoxLayout.Y_AXIS)); 12386 boundaryDetails.add(boundaryLabel); 12387 boundaryDetails.add(boundaryBlocks); 12388 12389 detailsPanel.add(boundaryDetails, BorderLayout.PAGE_START); 12390 detailsPanel.add(addIconPanel(), BorderLayout.CENTER); 12391 detailsPanel.add(positionLeftRight(), BorderLayout.PAGE_END); 12392 } 12393 12394 protected void setTextField(String value) { 12395 beanCombo.setSelectedItem(manager.getNamedBean(value)); 12396 } 12397 12398 protected String getText() { 12399 return beanCombo.getSelectedItemDisplayName(); 12400 } 12401 12402 protected B getBean() { 12403 return beanCombo.getSelectedItem(); 12404 } 12405 12406 protected JPanel getDetailsPanel() { 12407 return detailsPanel; 12408 } 12409 12410 protected boolean addToPanel() { 12411 return !addBeanCheck.isSelected(); 12412 } 12413 12414 protected boolean isRightSelected() { 12415 return right.isSelected(); 12416 } 12417 12418 protected void setBoundaryTitle(String text) { 12419 detailsPanel.setBorder(BorderFactory.createTitledBorder(blackline, text)); 12420 } 12421 12422 protected void setBoundaryLabelText(String text) { 12423 boundaryLabel.setText(text); 12424 } 12425 12426 protected void setBoundaryLabel(String label) { 12427 boundaryBlocks.setText(label); 12428 } 12429 12430 protected NamedBeanComboBox<B> getCombo() { 12431 return beanCombo; 12432 } 12433 12434 protected JPanel positionLeftRight() { 12435 JPanel placementPanel = new JPanel(); 12436 placementPanel.setBorder(BorderFactory.createTitledBorder( 12437 blackline, 12438 Bundle.getMessage("PlaceItem", new Object[]{beanString}))); 12439 12440 placementPanel.setLayout(new BoxLayout(placementPanel, BoxLayout.Y_AXIS)); 12441 placementPanel.setOpaque(false); 12442 placementPanel.add(addBeanCheck); 12443 placementPanel.add(left); 12444 placementPanel.add(right); 12445 addBeanCheck.setOpaque(false); 12446 left.setOpaque(false); 12447 right.setOpaque(false); 12448 12449 addBeanCheck.setToolTipText(Bundle.getMessage("PlaceItemToolTip", 12450 new Object[]{beanString})); 12451 12452 right.setToolTipText(Bundle.getMessage("PlaceRightToolTip", 12453 new Object[]{beanString})); 12454 12455 left.setToolTipText(Bundle.getMessage("PlaceLeftToolTip", 12456 new Object[]{beanString})); 12457 return placementPanel; 12458 } 12459 12460 protected JPanel addIconPanel() { 12461 JPanel addBeanPanel = new JPanel(new FlowLayout()); 12462 addBeanPanel.setOpaque(false); 12463 addBeanPanel.add(textLabel); 12464 textLabel.setOpaque(false); 12465 addBeanPanel.add(beanCombo); 12466 return addBeanPanel; 12467 } 12468 } 12469 12470 /*==================*\ 12471 |* setSignalsAtSlip *| 12472 \*==================*/ 12473//operational variables for Set Signals at slip tool 12474 private JmriJFrame setSignalsAtSlipFrame = null; 12475 private boolean setSignalsAtSlipOpenFlag = false; 12476 private boolean setSignalsAtSlipFromMenuFlag = false; 12477 12478 private final JComboBox<String> slipNameComboBox = new JComboBox<>(); 12479 12480 private final NamedBeanComboBox<SignalHead> a1SlipSignalHeadComboBox 12481 = new NamedBeanComboBox<>( 12482 InstanceManager.getDefault(SignalHeadManager.class), 12483 null, DisplayOptions.DISPLAYNAME); 12484 private final NamedBeanComboBox<SignalHead> a2SlipSignalHeadComboBox 12485 = new NamedBeanComboBox<>( 12486 InstanceManager.getDefault(SignalHeadManager.class), 12487 null, DisplayOptions.DISPLAYNAME); 12488 private final NamedBeanComboBox<SignalHead> b1SlipSignalHeadComboBox 12489 = new NamedBeanComboBox<>( 12490 InstanceManager.getDefault(SignalHeadManager.class), 12491 null, DisplayOptions.DISPLAYNAME); 12492 private final NamedBeanComboBox<SignalHead> b2SlipSignalHeadComboBox 12493 = new NamedBeanComboBox<>( 12494 InstanceManager.getDefault(SignalHeadManager.class), 12495 null, DisplayOptions.DISPLAYNAME); 12496 private final NamedBeanComboBox<SignalHead> c1SlipSignalHeadComboBox 12497 = new NamedBeanComboBox<>( 12498 InstanceManager.getDefault(SignalHeadManager.class), 12499 null, DisplayOptions.DISPLAYNAME); 12500 private final NamedBeanComboBox<SignalHead> c2SlipSignalHeadComboBox 12501 = new NamedBeanComboBox<>( 12502 InstanceManager.getDefault(SignalHeadManager.class), 12503 null, DisplayOptions.DISPLAYNAME); 12504 private final NamedBeanComboBox<SignalHead> d1SlipSignalHeadComboBox 12505 = new NamedBeanComboBox<>( 12506 InstanceManager.getDefault(SignalHeadManager.class), 12507 null, DisplayOptions.DISPLAYNAME); 12508 private final NamedBeanComboBox<SignalHead> d2SlipSignalHeadComboBox 12509 = new NamedBeanComboBox<>( 12510 InstanceManager.getDefault(SignalHeadManager.class), 12511 null, DisplayOptions.DISPLAYNAME); 12512 12513 private final JCheckBox setA1SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12514 private final JCheckBox setupA1SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12515 private final JCheckBox setA2SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12516 private final JCheckBox setupA2SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12517 private final JCheckBox setB1SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12518 private final JCheckBox setupB1SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12519 private final JCheckBox setB2SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12520 private final JCheckBox setupB2SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12521 private final JCheckBox setC1SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12522 private final JCheckBox setupC1SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12523 private final JCheckBox setC2SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12524 private final JCheckBox setupC2SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12525 private final JCheckBox setD1SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12526 private final JCheckBox setupD1SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12527 private final JCheckBox setD2SlipHead = new JCheckBox(Bundle.getMessage("PlaceHead")); 12528 private final JCheckBox setupD2SlipLogic = new JCheckBox(Bundle.getMessage("SetLogic")); 12529 12530 private JButton setSlipSignalsDone = null; 12531 private JButton setSlipSignalsCancel = null; 12532 private LayoutSlip layoutSlip = null; 12533 12534 private SignalHead a1SlipHead = null; 12535 private SignalHead a2SlipHead = null; 12536 private SignalHead b1SlipHead = null; 12537 private SignalHead b2SlipHead = null; 12538 private SignalHead c1SlipHead = null; 12539 private SignalHead c2SlipHead = null; 12540 private SignalHead d1SlipHead = null; 12541 private SignalHead d2SlipHead = null; 12542 12543 private JPanel dblSlipC2SigPanel; 12544 private JPanel dblSlipB2SigPanel; 12545 12546 public void setSignalsAtSlipFromMenu(@Nonnull LayoutSlip ls, 12547 @Nonnull MultiIconEditor theEditor, @Nonnull JFrame theFrame) { 12548 layoutSlip = ls; 12549 a1SlipSignalHeadComboBox.setSelectedItem(null); 12550 a2SlipSignalHeadComboBox.setSelectedItem(null); 12551 b1SlipSignalHeadComboBox.setSelectedItem(null); 12552 b2SlipSignalHeadComboBox.setSelectedItem(null); 12553 c1SlipSignalHeadComboBox.setSelectedItem(null); 12554 c2SlipSignalHeadComboBox.setSelectedItem(null); 12555 d1SlipSignalHeadComboBox.setSelectedItem(null); 12556 d2SlipSignalHeadComboBox.setSelectedItem(null); 12557 12558 setSignalsAtSlipFromMenuFlag = true; 12559 setSignalsAtSlip(theEditor, theFrame); 12560 setSignalsAtSlipFromMenuFlag = false; 12561 } 12562 12563 public void setSignalsAtSlip(@Nonnull MultiIconEditor theEditor, 12564 @Nonnull JFrame theFrame) { 12565 signalIconEditor = theEditor; 12566 signalFrame = theFrame; 12567 12568 //Initialize if needed 12569 if (setSignalsAtSlipFrame == null) { 12570 setSignalsAtSlipOpenFlag = false; 12571 setSignalsAtSlipFrame = new JmriJFrame(Bundle.getMessage("SignalsAtSlip"), false, true); 12572 oneFrameToRuleThemAll(setSignalsAtSlipFrame); 12573 setSignalsAtSlipFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 12574 setSignalsAtSlipFrame.addHelpMenu("package.jmri.jmrit.display.SetSignalsAtSlip", true); 12575 setSignalsAtSlipFrame.setLocation(70, 30); 12576 Container theContentPane = setSignalsAtSlipFrame.getContentPane(); 12577 theContentPane.setLayout(new BoxLayout(theContentPane, BoxLayout.Y_AXIS)); 12578 12579 JPanel panel1 = new JPanel(new FlowLayout()); 12580 JLabel turnout1NameLabel = new JLabel(Bundle.getMessage("Slip") + " " 12581 + Bundle.getMessage("Name")); 12582 panel1.add(turnout1NameLabel); 12583 panel1.add(slipNameComboBox); 12584 for (LayoutSlip slip : layoutEditor.getLayoutSlips()) { 12585 slipNameComboBox.addItem(slip.getDisplayName()); 12586 } 12587 12588 slipNameComboBox.insertItemAt("", 0); 12589 12590 if (layoutSlip != null) { 12591 slipNameComboBox.setSelectedItem(layoutSlip.getDisplayName()); 12592 getSlipTurnoutSignalsGetSaved(null); 12593 } else { 12594 slipNameComboBox.setSelectedIndex(0); 12595 } 12596 slipNameComboBox.addActionListener((ActionEvent e) -> { 12597 for (LayoutSlip slip : layoutEditor.getLayoutSlips()) { 12598 if (slip.getDisplayName().equals(slipNameComboBox.getSelectedItem())) { 12599 //slip1NameField.setText(slip.getDisplayName()); 12600 getSlipTurnoutSignalsGetSaved(e); 12601 boolean enable = (slip.getSlipType() == LayoutSlip.TurnoutType.DOUBLE_SLIP); 12602 dblSlipC2SigPanel.setVisible(enable); 12603 dblSlipB2SigPanel.setVisible(enable); 12604 setSignalsAtSlipFrame.pack(); 12605 return; 12606 } 12607 } 12608 }); 12609 theContentPane.add(panel1); 12610 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12611 12612 JPanel panel2a = new JPanel(new FlowLayout()); 12613 panel2a.add(new JLabel(" ")); 12614 panel2a.add(setPlaceAllHeads); 12615 setPlaceAllHeads.setToolTipText(Bundle.getMessage("PlaceAllHeadsHint")); 12616 setPlaceAllHeads.addActionListener((ActionEvent e) -> { 12617 boolean isSelected = setPlaceAllHeads.isSelected(); 12618 //(de)select all checkboxes 12619 setA1SlipHead.setSelected(isSelected); 12620 setA2SlipHead.setSelected(isSelected); 12621 setB1SlipHead.setSelected(isSelected); 12622 setB2SlipHead.setSelected(isSelected); 12623 setC1SlipHead.setSelected(isSelected); 12624 setC2SlipHead.setSelected(isSelected); 12625 setD1SlipHead.setSelected(isSelected); 12626 setD2SlipHead.setSelected(isSelected); 12627 }); 12628 panel2a.add(new JLabel(" ")); 12629 panel2a.add(setupAllLogic); 12630 setupAllLogic.setToolTipText(Bundle.getMessage("SetAllLogicHint")); 12631 setupAllLogic.addActionListener((ActionEvent e) -> { 12632 boolean isSelected = setupAllLogic.isSelected(); 12633 //(de)select all checkboxes 12634 setupA1SlipLogic.setSelected(isSelected); 12635 setupA2SlipLogic.setSelected(isSelected); 12636 setupB1SlipLogic.setSelected(isSelected); 12637 setupB2SlipLogic.setSelected(isSelected); 12638 setupC1SlipLogic.setSelected(isSelected); 12639 setupC2SlipLogic.setSelected(isSelected); 12640 setupD1SlipLogic.setSelected(isSelected); 12641 setupD2SlipLogic.setSelected(isSelected); 12642 }); 12643 theContentPane.add(panel2a); 12644 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12645 12646 //Signal heads located at turnout 1 12647 JPanel panel21x = new JPanel(new FlowLayout()); 12648 panel21x.add(new JLabel(Bundle.getMessage("SignalLocated") 12649 + " " + Bundle.getMessage("BeanNameTurnout") + " 1 - " 12650 + Bundle.getMessage("ContinuingTrack"))); 12651 theContentPane.add(panel21x); 12652 12653 JPanel panel21 = new JPanel(new FlowLayout()); 12654 panel21.add(new JLabel(Bundle.getMessage("MakeLabel", 12655 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12656 + Bundle.getMessage("ContinuingTrack")))); 12657 panel21.add(a1SlipSignalHeadComboBox); 12658 theContentPane.add(panel21); 12659 a1SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12660 12661 JPanel panel22 = new JPanel(new FlowLayout()); 12662 panel22.add(new JLabel(Bundle.getMessage("OrBoth") + " 2 " + Bundle.getMessage("Tracks)") + " ")); 12663 panel22.add(setA1SlipHead); 12664 setA1SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12665 panel22.add(new JLabel(" ")); 12666 panel22.add(setupA1SlipLogic); 12667 setupA1SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12668 theContentPane.add(panel22); 12669 12670 JPanel panel23 = new JPanel(new FlowLayout()); 12671 panel23.add(new JLabel(Bundle.getMessage("MakeLabel", 12672 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12673 + Bundle.getMessage("DivergingTrack")))); 12674 panel23.add(a2SlipSignalHeadComboBox); 12675 theContentPane.add(panel23); 12676 a2SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12677 12678 JPanel panel24 = new JPanel(new FlowLayout()); 12679 panel24.add(new JLabel(" ")); 12680 panel24.add(setA2SlipHead); 12681 setA2SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12682 panel24.add(new JLabel(" ")); 12683 panel24.add(setupA2SlipLogic); 12684 setupA2SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12685 theContentPane.add(panel24); 12686 12687 JPanel panel31x = new JPanel(new FlowLayout()); 12688 panel31x.add(new JLabel(Bundle.getMessage("SignalLocated") 12689 + " " + Bundle.getMessage("BeanNameTurnout") + " 1 - " 12690 + Bundle.getMessage("DivergingTrack"))); 12691 theContentPane.add(panel31x); 12692 12693 JPanel panel31 = new JPanel(new FlowLayout()); 12694 panel31.add(new JLabel(Bundle.getMessage("MakeLabel", 12695 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12696 + Bundle.getMessage("ContinuingTrack")))); 12697 panel31.add(b1SlipSignalHeadComboBox); 12698 theContentPane.add(panel31); 12699 b1SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12700 12701 JPanel panel32 = new JPanel(new FlowLayout()); 12702 panel32.add(new JLabel(Bundle.getMessage("OrBoth") + " 2 " + Bundle.getMessage("Tracks)") + " ")); 12703 panel32.add(setB1SlipHead); 12704 setB1SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12705 panel32.add(new JLabel(" ")); 12706 panel32.add(setupB1SlipLogic); 12707 setupB1SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12708 theContentPane.add(panel32); 12709 12710 dblSlipB2SigPanel = new JPanel(new FlowLayout()); 12711 dblSlipB2SigPanel.setLayout(new BoxLayout(dblSlipB2SigPanel, BoxLayout.Y_AXIS)); 12712 12713 JPanel panel33 = new JPanel(new FlowLayout()); 12714 panel33.add(new JLabel(Bundle.getMessage("MakeLabel", 12715 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12716 + Bundle.getMessage("DivergingTrack")))); 12717 panel33.add(b2SlipSignalHeadComboBox); 12718 dblSlipB2SigPanel.add(panel33); 12719 b2SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12720 12721 JPanel panel34 = new JPanel(new FlowLayout()); 12722 panel34.add(new JLabel(" ")); 12723 panel34.add(setB2SlipHead); 12724 setB2SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12725 panel34.add(new JLabel(" ")); 12726 panel34.add(setupB2SlipLogic); 12727 setupB2SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12728 dblSlipB2SigPanel.add(panel34); 12729 12730 theContentPane.add(dblSlipB2SigPanel); 12731 dblSlipB2SigPanel.setVisible(false); 12732 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12733 //Signal heads located at turnout 2 12734 12735 JPanel panel41x = new JPanel(new FlowLayout()); 12736 panel41x.add(new JLabel(Bundle.getMessage("SignalLocated") 12737 + " " + Bundle.getMessage("BeanNameTurnout") + " 2 - " 12738 + Bundle.getMessage("ContinuingTrack"))); 12739 theContentPane.add(panel41x); 12740 12741 JPanel panel41 = new JPanel(new FlowLayout()); 12742 panel41.add(new JLabel(Bundle.getMessage("MakeLabel", 12743 Bundle.getMessage("ProtectsTurnout") + " 2 - " 12744 + Bundle.getMessage("ContinuingTrack")))); 12745 panel41.add(c1SlipSignalHeadComboBox); 12746 theContentPane.add(panel41); 12747 c1SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12748 12749 JPanel panel42 = new JPanel(new FlowLayout()); 12750 panel42.add(new JLabel(Bundle.getMessage("OrBoth") + " 1 " + Bundle.getMessage("Tracks)") + " ")); 12751 panel42.add(setC1SlipHead); 12752 setC1SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12753 panel42.add(new JLabel(" ")); 12754 panel42.add(setupC1SlipLogic); 12755 setupC1SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12756 theContentPane.add(panel42); 12757 dblSlipC2SigPanel = new JPanel(new FlowLayout()); 12758 dblSlipC2SigPanel.setLayout(new BoxLayout(dblSlipC2SigPanel, BoxLayout.Y_AXIS)); 12759 12760 JPanel panel43 = new JPanel(new FlowLayout()); 12761 panel43.add(new JLabel(Bundle.getMessage("MakeLabel", 12762 Bundle.getMessage("ProtectsTurnout") + " 1 - " 12763 + Bundle.getMessage("DivergingTrack")))); 12764 panel43.add(c2SlipSignalHeadComboBox); 12765 dblSlipC2SigPanel.add(panel43); 12766 c2SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12767 12768 JPanel panel44 = new JPanel(new FlowLayout()); 12769 panel44.add(new JLabel(" ")); 12770 panel44.add(setC2SlipHead); 12771 setC2SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12772 panel44.add(new JLabel(" ")); 12773 panel44.add(setupC2SlipLogic); 12774 setupC2SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12775 dblSlipC2SigPanel.add(panel44); 12776 theContentPane.add(dblSlipC2SigPanel); 12777 12778 JPanel panel51x = new JPanel(new FlowLayout()); 12779 panel51x.add(new JLabel(Bundle.getMessage("SignalLocated") 12780 + " " + Bundle.getMessage("BeanNameTurnout") + " 2 - " 12781 + Bundle.getMessage("DivergingTrack"))); 12782 theContentPane.add(panel51x); 12783 12784 JPanel panel51 = new JPanel(new FlowLayout()); 12785 panel51.add(new JLabel(Bundle.getMessage("MakeLabel", 12786 Bundle.getMessage("ProtectsTurnout") + " 1 - " 12787 + Bundle.getMessage("ContinuingTrack")))); 12788 panel51.add(d1SlipSignalHeadComboBox); 12789 theContentPane.add(panel51); 12790 d1SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12791 12792 JPanel panel52 = new JPanel(new FlowLayout()); 12793 panel52.add(new JLabel(Bundle.getMessage("OrBoth") + " 1 " + Bundle.getMessage("Tracks)") + " ")); 12794 panel52.add(setD1SlipHead); 12795 setD1SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12796 panel52.add(new JLabel(" ")); 12797 panel52.add(setupD1SlipLogic); 12798 setupD1SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12799 theContentPane.add(panel52); 12800 12801 JPanel panel53 = new JPanel(new FlowLayout()); 12802 panel53.add(new JLabel(Bundle.getMessage("MakeLabel", 12803 Bundle.getMessage("ProtectsTurnout") + " 1 - " 12804 + Bundle.getMessage("DivergingTrack")))); 12805 panel53.add(d2SlipSignalHeadComboBox); 12806 theContentPane.add(panel53); 12807 d2SlipSignalHeadComboBox.setToolTipText(Bundle.getMessage("SignalHeadNameHint")); 12808 12809 JPanel panel54 = new JPanel(new FlowLayout()); 12810 panel54.add(new JLabel(" ")); 12811 panel54.add(setD2SlipHead); 12812 setD2SlipHead.setToolTipText(Bundle.getMessage("PlaceHeadHint")); 12813 panel54.add(new JLabel(" ")); 12814 panel54.add(setupD2SlipLogic); 12815 setupD2SlipLogic.setToolTipText(Bundle.getMessage("SetLogicHint")); 12816 theContentPane.add(panel54); 12817 theContentPane.add(new JSeparator(JSeparator.HORIZONTAL)); 12818 12819 JPanel panel6 = new JPanel(new FlowLayout()); 12820 panel6.add(changeTToTSignalIcon = new JButton(Bundle.getMessage("ChangeSignalIcon"))); 12821 changeTToTSignalIcon.addActionListener((ActionEvent e) -> signalFrame.setVisible(true)); 12822 changeTToTSignalIcon.setToolTipText(Bundle.getMessage("ChangeSignalIconHint")); 12823 panel6.add(new JLabel(" ")); 12824 panel6.add(setSlipSignalsDone = new JButton(Bundle.getMessage("ButtonDone"))); 12825 setSlipSignalsDone.addActionListener(this::setSlipSignalsDonePressed); 12826 setSlipSignalsDone.setToolTipText(Bundle.getMessage("DoneHint", Bundle.getMessage("ButtonDone"))); 12827 panel6.add(setSlipSignalsCancel = new JButton(Bundle.getMessage("ButtonCancel"))); 12828 setSlipSignalsCancel.addActionListener(this::setSlipSignalsCancelPressed); 12829 setSlipSignalsCancel.setToolTipText(Bundle.getMessage("CancelHint", Bundle.getMessage("ButtonCancel"))); 12830 theContentPane.add(panel6); 12831 setSignalsAtSlipFrame.addWindowListener(new WindowAdapter() { 12832 @Override 12833 public void windowClosing(WindowEvent e) { 12834 setSlipSignalsCancelPressed(null); 12835 } 12836 }); 12837 } 12838 setPlaceAllHeads.setSelected(false); 12839 setupAllLogic.setSelected(false); 12840 12841 boolean enable = (layoutSlip != null 12842 && layoutSlip.getSlipType() == LayoutSlip.TurnoutType.DOUBLE_SLIP); 12843 dblSlipC2SigPanel.setVisible(enable); 12844 dblSlipB2SigPanel.setVisible(enable); 12845 12846 if (setSignalsAtSlipFromMenuFlag) { 12847 getSlipTurnoutSignalsGetSaved(null); 12848 } 12849 12850 if (!setSignalsAtSlipOpenFlag) { 12851 setSignalsAtSlipFrame.setPreferredSize(null); 12852 setSignalsAtSlipFrame.pack(); 12853 setSignalsAtSlipOpenFlag = true; 12854 } 12855 setSignalsAtSlipFrame.setVisible(true); 12856 } 12857 12858 private void getSlipTurnoutSignalsGetSaved(ActionEvent a) { 12859 if (!getSlipTurnoutInformation()) { 12860 return; 12861 } 12862 a1SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalA1()); 12863 a2SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalA2()); 12864 b1SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalB1()); 12865 b2SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalB2()); 12866 c1SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalC1()); 12867 c2SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalC2()); 12868 d1SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalD1()); 12869 d2SlipSignalHeadComboBox.setSelectedItem(layoutSlip.getSignalD2()); 12870 } 12871 12872 private void setSlipSignalsCancelPressed(ActionEvent a) { 12873 setSignalsAtSlipOpenFlag = false; 12874 setSignalsAtSlipFrame.setVisible(false); 12875 } 12876 12877 private boolean getSlipTurnoutInformation() { 12878 turnout1 = null; 12879 turnout2 = null; 12880 layoutSlip = null; 12881 for (LayoutSlip ls : layoutEditor.getLayoutSlips()) { 12882 if (ls.getDisplayName().equals(slipNameComboBox.getSelectedItem())) { 12883 layoutSlip = ls; 12884 break; 12885 } 12886 } 12887 if (layoutSlip == null) { 12888 return false; 12889 } 12890 String str = layoutSlip.getDisplayName(); 12891 12892 turnout1 = layoutSlip.getTurnout(); 12893 if (turnout1 == null) { 12894 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12895 Bundle.getMessage("SignalsError2", 12896 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 12897 JmriJOptionPane.ERROR_MESSAGE); 12898 return false; 12899 } 12900 turnout2 = layoutSlip.getTurnoutB(); 12901 if (turnout2 == null) { 12902 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12903 Bundle.getMessage("SignalsError2", 12904 new Object[]{str}), Bundle.getMessage("ErrorTitle"), 12905 JmriJOptionPane.ERROR_MESSAGE); 12906 return false; 12907 } 12908 return true; 12909 } 12910 12911 private void setSlipSignalsDonePressed(ActionEvent a) { 12912 if (!getSlipTurnoutInformation()) { 12913 return; 12914 } 12915 if (!getSlipSignalHeadInformation()) { 12916 return; 12917 } 12918 12919 //place signal icons if requested, and assign signal heads to this turnout 12920 String signalHeadName = a1SlipSignalHeadComboBox.getSelectedItemDisplayName(); 12921 if (signalHeadName == null) { 12922 signalHeadName = ""; 12923 } 12924 if (setA1SlipHead.isSelected()) { 12925 if (isHeadOnPanel(a1SlipHead) 12926 && (a1SlipHead != getHeadFromName(layoutSlip.getSignalB1Name()))) { 12927 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12928 Bundle.getMessage("SignalsError6", 12929 new Object[]{signalHeadName}), 12930 Bundle.getMessage("ErrorTitle"), 12931 JmriJOptionPane.ERROR_MESSAGE); 12932 return; 12933 } else { 12934 removeSignalHeadFromPanel(layoutSlip.getSignalA1Name()); 12935 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 12936 placeA1Slip(signalHeadName); 12937 } else { 12938 placeB1Slip(signalHeadName); 12939 } 12940 removeAssignment(a1SlipHead); 12941 layoutSlip.setSignalA1Name(signalHeadName); 12942 needRedraw = true; 12943 } 12944 } else { 12945 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a1SlipHead, layoutSlip); 12946 if (assigned == LayoutTurnout.Geometry.NONE) { 12947 if (isHeadOnPanel(a1SlipHead) 12948 && isHeadAssignedAnywhere(a1SlipHead)) { 12949 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12950 Bundle.getMessage("SignalsError8", 12951 new Object[]{signalHeadName}), 12952 Bundle.getMessage("ErrorTitle"), 12953 JmriJOptionPane.ERROR_MESSAGE); 12954 return; 12955 } else { 12956 removeSignalHeadFromPanel(layoutSlip.getSignalB1Name()); 12957 removeAssignment(a1SlipHead); 12958 layoutSlip.setSignalA1Name(signalHeadName); 12959 } 12960 //} else if (assigned != B1) { 12961 //need to figure out what to do in this case - assigned to a different position on the same turnout. 12962 } 12963 } 12964 12965 signalHeadName = a2SlipSignalHeadComboBox.getSelectedItemDisplayName(); 12966 if (signalHeadName == null) { 12967 signalHeadName = ""; 12968 } 12969 if ((a2SlipHead != null) && setA2SlipHead.isSelected()) { 12970 if (isHeadOnPanel(a2SlipHead) 12971 && (a2SlipHead != getHeadFromName(layoutSlip.getSignalB2Name()))) { 12972 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12973 Bundle.getMessage("SignalsError6", 12974 new Object[]{signalHeadName}), 12975 Bundle.getMessage("ErrorTitle"), 12976 JmriJOptionPane.ERROR_MESSAGE); 12977 return; 12978 } else { 12979 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 12980 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 12981 placeA2Slip(signalHeadName); 12982 } else { 12983 placeB2Slip(signalHeadName); 12984 } 12985 removeAssignment(a2SlipHead); 12986 layoutSlip.setSignalA2Name(signalHeadName); 12987 needRedraw = true; 12988 } 12989 } else if (a2SlipHead != null) { 12990 LayoutTurnout.Geometry assigned = isHeadAssignedHere(a2SlipHead, layoutSlip); 12991 if (assigned == LayoutTurnout.Geometry.NONE) { 12992 if (isHeadOnPanel(a2SlipHead) 12993 && isHeadAssignedAnywhere(a2SlipHead)) { 12994 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 12995 Bundle.getMessage("SignalsError8", 12996 new Object[]{signalHeadName}), 12997 Bundle.getMessage("ErrorTitle"), 12998 JmriJOptionPane.ERROR_MESSAGE); 12999 return; 13000 } else { 13001 removeSignalHeadFromPanel(layoutSlip.getSignalA2Name()); 13002 removeAssignment(a2SlipHead); 13003 layoutSlip.setSignalA2Name(signalHeadName); 13004 } 13005 //} else if (assigned != B2) { 13006 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13007 } 13008 } else { //a2SlipHead known to be null here 13009 removeSignalHeadFromPanel(layoutSlip.getSignalA2Name()); 13010 layoutSlip.setSignalB2Name(""); 13011 } 13012 13013 signalHeadName = b1SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13014 if (signalHeadName == null) { 13015 signalHeadName = ""; 13016 } 13017 if (setB1SlipHead.isSelected()) { 13018 if (isHeadOnPanel(b1SlipHead) 13019 && (b1SlipHead != getHeadFromName(layoutSlip.getSignalC1Name()))) { 13020 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13021 Bundle.getMessage("SignalsError6", 13022 new Object[]{signalHeadName}), 13023 Bundle.getMessage("ErrorTitle"), 13024 JmriJOptionPane.ERROR_MESSAGE); 13025 return; 13026 } else { 13027 removeSignalHeadFromPanel(layoutSlip.getSignalB1Name()); 13028 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13029 placeB1Slip(signalHeadName); 13030 } else { 13031 placeA1Slip(signalHeadName); 13032 } 13033 removeAssignment(b1SlipHead); 13034 layoutSlip.setSignalB1Name(signalHeadName); 13035 needRedraw = true; 13036 } 13037 } else { 13038 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b1SlipHead, layoutSlip); 13039 if (assigned == LayoutTurnout.Geometry.NONE) { 13040 if (isHeadOnPanel(b1SlipHead) 13041 && isHeadAssignedAnywhere(b1SlipHead)) { 13042 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13043 Bundle.getMessage("SignalsError8", 13044 new Object[]{signalHeadName}), 13045 Bundle.getMessage("ErrorTitle"), 13046 JmriJOptionPane.ERROR_MESSAGE); 13047 return; 13048 } else { 13049 removeSignalHeadFromPanel(layoutSlip.getSignalB1Name()); 13050 removeAssignment(b1SlipHead); 13051 layoutSlip.setSignalB1Name(signalHeadName); 13052 } 13053 //} else if (assigned != C1) { 13054 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13055 } 13056 } 13057 13058 if (layoutSlip.getTurnoutType() == LayoutSlip.TurnoutType.DOUBLE_SLIP) { 13059 signalHeadName = b2SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13060 if (signalHeadName == null) { 13061 signalHeadName = ""; 13062 } 13063 if ((b2SlipHead != null) && setB2SlipHead.isSelected()) { 13064 if (isHeadOnPanel(b2SlipHead) 13065 && (b2SlipHead != getHeadFromName(layoutSlip.getSignalC2Name()))) { 13066 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13067 Bundle.getMessage("SignalsError6", 13068 new Object[]{signalHeadName}), 13069 Bundle.getMessage("ErrorTitle"), 13070 JmriJOptionPane.ERROR_MESSAGE); 13071 return; 13072 } else { 13073 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 13074 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13075 placeB2Slip(signalHeadName); 13076 } else { 13077 placeA2Slip(signalHeadName); 13078 } 13079 removeAssignment(b2SlipHead); 13080 layoutSlip.setSignalB2Name(signalHeadName); 13081 needRedraw = true; 13082 } 13083 } else if (b2SlipHead != null) { 13084 LayoutTurnout.Geometry assigned = isHeadAssignedHere(b2SlipHead, layoutSlip); 13085 if (assigned == LayoutTurnout.Geometry.NONE) { 13086 if (isHeadOnPanel(b2SlipHead) 13087 && isHeadAssignedAnywhere(b2SlipHead)) { 13088 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13089 Bundle.getMessage("SignalsError8", 13090 new Object[]{signalHeadName}), 13091 Bundle.getMessage("ErrorTitle"), 13092 JmriJOptionPane.ERROR_MESSAGE); 13093 return; 13094 } else { 13095 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 13096 removeAssignment(b2SlipHead); 13097 layoutSlip.setSignalB2Name(signalHeadName); 13098 } 13099 //} else if (assigned != C2) { 13100 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13101 } 13102 } else { //b2SlipHead known to be null here 13103 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 13104 layoutSlip.setSignalB2Name(""); 13105 } 13106 } else { 13107 if (b2SlipHead != null) { 13108 BlockBossLogic.getStoppedObject(layoutSlip.getSignalB2Name()); 13109 removeSignalHeadFromPanel(layoutSlip.getSignalB2Name()); 13110 layoutSlip.setSignalB2Name(""); 13111 b2SlipHead = null; 13112 } 13113 } 13114 13115 //signal heads on turnout 2 13116 signalHeadName = c1SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13117 if (signalHeadName == null) { 13118 signalHeadName = ""; 13119 } 13120 if (setC1SlipHead.isSelected()) { 13121 if (isHeadOnPanel(c1SlipHead) 13122 && (c1SlipHead != getHeadFromName(layoutSlip.getSignalB1Name()))) { 13123 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13124 Bundle.getMessage("SignalsError6", 13125 new Object[]{signalHeadName}), 13126 Bundle.getMessage("ErrorTitle"), 13127 JmriJOptionPane.ERROR_MESSAGE); 13128 return; 13129 } else { 13130 removeSignalHeadFromPanel(layoutSlip.getSignalC1Name()); 13131 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13132 placeC1Slip(signalHeadName); 13133 } else { 13134 placeD1Slip(signalHeadName); 13135 } 13136 removeAssignment(c1SlipHead); 13137 layoutSlip.setSignalC1Name(signalHeadName); 13138 needRedraw = true; 13139 } 13140 } else { 13141 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c1SlipHead, layoutSlip); 13142 if (assigned == LayoutTurnout.Geometry.NONE) { 13143 if (isHeadOnPanel(c1SlipHead) 13144 && isHeadAssignedAnywhere(c1SlipHead)) { 13145 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13146 Bundle.getMessage("SignalsError8", 13147 new Object[]{signalHeadName}), 13148 Bundle.getMessage("ErrorTitle"), 13149 JmriJOptionPane.ERROR_MESSAGE); 13150 return; 13151 } else { 13152 removeSignalHeadFromPanel(layoutSlip.getSignalC1Name()); 13153 removeAssignment(c1SlipHead); 13154 layoutSlip.setSignalC1Name(signalHeadName); 13155 } 13156 //} else if (assigned != B1) { 13157 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13158 } 13159 } 13160 13161 if (layoutSlip.getTurnoutType() == LayoutSlip.TurnoutType.DOUBLE_SLIP) { 13162 signalHeadName = c2SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13163 if (signalHeadName == null) { 13164 signalHeadName = ""; 13165 } 13166 if ((c2SlipHead != null) && setC2SlipHead.isSelected()) { 13167 if (isHeadOnPanel(c2SlipHead) 13168 && (c2SlipHead != getHeadFromName(layoutSlip.getSignalB2Name()))) { 13169 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13170 Bundle.getMessage("SignalsError6", 13171 new Object[]{signalHeadName}), 13172 Bundle.getMessage("ErrorTitle"), 13173 JmriJOptionPane.ERROR_MESSAGE); 13174 return; 13175 } else { 13176 removeSignalHeadFromPanel(layoutSlip.getSignalC2Name()); 13177 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13178 placeC2Slip(signalHeadName); 13179 } else { 13180 placeD2Slip(signalHeadName); 13181 } 13182 removeAssignment(c2SlipHead); 13183 layoutSlip.setSignalC2Name(signalHeadName); 13184 needRedraw = true; 13185 } 13186 } else if (c2SlipHead != null) { 13187 LayoutTurnout.Geometry assigned = isHeadAssignedHere(c2SlipHead, layoutSlip); 13188 if (assigned == LayoutTurnout.Geometry.NONE) { 13189 if (isHeadOnPanel(c2SlipHead) 13190 && isHeadAssignedAnywhere(c2SlipHead)) { 13191 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13192 Bundle.getMessage("SignalsError8", 13193 new Object[]{signalHeadName}), 13194 Bundle.getMessage("ErrorTitle"), 13195 JmriJOptionPane.ERROR_MESSAGE); 13196 return; 13197 } else { 13198 removeSignalHeadFromPanel(layoutSlip.getSignalC2Name()); 13199 removeAssignment(c2SlipHead); 13200 layoutSlip.setSignalC2Name(signalHeadName); 13201 } 13202 //} else if (assigned != B2) { 13203 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13204 } 13205 } else { //c2SlipHead known to be null here 13206 removeSignalHeadFromPanel(layoutSlip.getSignalC2Name()); 13207 layoutSlip.setSignalC2Name(""); 13208 } 13209 } else { 13210 if (c2SlipHead != null) { 13211 BlockBossLogic.getStoppedObject(layoutSlip.getSignalC2Name()); 13212 removeSignalHeadFromPanel(layoutSlip.getSignalC2Name()); 13213 layoutSlip.setSignalC2Name(""); 13214 c2SlipHead = null; 13215 } 13216 } 13217 13218 signalHeadName = d1SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13219 if (signalHeadName == null) { 13220 signalHeadName = ""; 13221 } 13222 if (setD1SlipHead.isSelected()) { 13223 if (isHeadOnPanel(d1SlipHead) 13224 && (d1SlipHead != getHeadFromName(layoutSlip.getSignalC1Name()))) { 13225 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13226 Bundle.getMessage("SignalsError6", 13227 new Object[]{signalHeadName}), 13228 Bundle.getMessage("ErrorTitle"), 13229 JmriJOptionPane.ERROR_MESSAGE); 13230 return; 13231 } else { 13232 removeSignalHeadFromPanel(layoutSlip.getSignalD1Name()); 13233 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13234 placeD1Slip(signalHeadName); 13235 } else { 13236 placeC1Slip(signalHeadName); 13237 } 13238 removeAssignment(d1SlipHead); 13239 layoutSlip.setSignalD1Name(signalHeadName); 13240 needRedraw = true; 13241 } 13242 } else { 13243 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d1SlipHead, layoutSlip); 13244 if (assigned == LayoutTurnout.Geometry.NONE) { 13245 if (isHeadOnPanel(d1SlipHead) 13246 && isHeadAssignedAnywhere(d1SlipHead)) { 13247 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13248 Bundle.getMessage("SignalsError8", 13249 new Object[]{signalHeadName}), 13250 Bundle.getMessage("ErrorTitle"), 13251 JmriJOptionPane.ERROR_MESSAGE); 13252 return; 13253 } else { 13254 removeSignalHeadFromPanel(layoutSlip.getSignalD1Name()); 13255 removeAssignment(d1SlipHead); 13256 layoutSlip.setSignalD1Name(signalHeadName); 13257 } 13258 //} else if (assigned != C1) { 13259 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13260 } 13261 } 13262 13263 signalHeadName = d2SlipSignalHeadComboBox.getSelectedItemDisplayName(); 13264 if (signalHeadName == null) { 13265 signalHeadName = ""; 13266 } 13267 if ((d2SlipHead != null) && setD2SlipHead.isSelected()) { 13268 if (isHeadOnPanel(d2SlipHead) 13269 && (d2SlipHead != getHeadFromName(layoutSlip.getSignalC2Name()))) { 13270 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13271 Bundle.getMessage("SignalsError6", 13272 new Object[]{signalHeadName}), 13273 Bundle.getMessage("ErrorTitle"), 13274 JmriJOptionPane.ERROR_MESSAGE); 13275 return; 13276 } else { 13277 removeSignalHeadFromPanel(layoutSlip.getSignalD2Name()); 13278 if (layoutSlip.getContinuingSense() == Turnout.CLOSED) { 13279 placeD2Slip(signalHeadName); 13280 } else { 13281 placeC2Slip(signalHeadName); 13282 } 13283 removeAssignment(d2SlipHead); 13284 layoutSlip.setSignalD2Name(signalHeadName); 13285 needRedraw = true; 13286 } 13287 } else if (d2SlipHead != null) { 13288 LayoutTurnout.Geometry assigned = isHeadAssignedHere(d2SlipHead, layoutSlip); 13289 if (assigned == LayoutTurnout.Geometry.NONE) { 13290 if (isHeadOnPanel(d2SlipHead) 13291 && isHeadAssignedAnywhere(d2SlipHead)) { 13292 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13293 Bundle.getMessage("SignalsError8", 13294 new Object[]{signalHeadName}), 13295 Bundle.getMessage("ErrorTitle"), 13296 JmriJOptionPane.ERROR_MESSAGE); 13297 return; 13298 } else { 13299 removeSignalHeadFromPanel(layoutSlip.getSignalD2Name()); 13300 removeAssignment(d2SlipHead); 13301 layoutSlip.setSignalD2Name(signalHeadName); 13302 } 13303 //} else if (assigned != C2) { 13304 //need to figure out what to do in this case - assigned to a different position on the same turnout. 13305 } 13306 } else { //d2SlipHead known to be null here 13307 removeSignalHeadFromPanel(layoutSlip.getSignalD2Name()); 13308 layoutSlip.setSignalD2Name(""); 13309 } 13310 //setup logic if requested 13311 if (setupA1SlipLogic.isSelected() || setupA2SlipLogic.isSelected()) { 13312 setLogicSlip(a1SlipHead, (TrackSegment) layoutSlip.getConnectC(), a2SlipHead, 13313 (TrackSegment) layoutSlip.getConnectD(), setupA1SlipLogic.isSelected(), 13314 setupA2SlipLogic.isSelected(), layoutSlip, layoutSlip.getTurnout(), 13315 layoutSlip.getTurnoutB(), LayoutTurnout.STATE_AC, LayoutTurnout.STATE_AD, 0); 13316 } 13317 if (setupB1SlipLogic.isSelected() || setupB2SlipLogic.isSelected()) { 13318 setLogicSlip(b1SlipHead, (TrackSegment) layoutSlip.getConnectD(), b2SlipHead, 13319 (TrackSegment) layoutSlip.getConnectC(), setupB1SlipLogic.isSelected(), 13320 setupB2SlipLogic.isSelected(), layoutSlip, layoutSlip.getTurnout(), 13321 layoutSlip.getTurnoutB(), LayoutTurnout.STATE_BD, LayoutTurnout.STATE_BC, 2); 13322 } 13323 if (setupC1SlipLogic.isSelected() || setupC2SlipLogic.isSelected()) { 13324 setLogicSlip(c1SlipHead, (TrackSegment) layoutSlip.getConnectA(), c2SlipHead, 13325 (TrackSegment) layoutSlip.getConnectB(), setupC1SlipLogic.isSelected(), 13326 setupC2SlipLogic.isSelected(), layoutSlip, layoutSlip.getTurnoutB(), 13327 layoutSlip.getTurnout(), LayoutTurnout.STATE_AC, LayoutTurnout.STATE_BC, 4); 13328 } 13329 if (setupD1SlipLogic.isSelected() || setupD2SlipLogic.isSelected()) { 13330 setLogicSlip(d1SlipHead, (TrackSegment) layoutSlip.getConnectB(), d2SlipHead, 13331 (TrackSegment) layoutSlip.getConnectA(), setupD1SlipLogic.isSelected(), 13332 setupD2SlipLogic.isSelected(), layoutSlip, layoutSlip.getTurnoutB(), 13333 layoutSlip.getTurnout(), LayoutTurnout.STATE_BD, LayoutTurnout.STATE_AD, 6); 13334 } 13335 //finish up 13336 setSignalsAtSlipOpenFlag = false; 13337 setSignalsAtSlipFrame.setVisible(false); 13338 13339 if (needRedraw) { 13340 layoutEditor.redrawPanel(); 13341 needRedraw = false; 13342 layoutEditor.setDirty(); 13343 } 13344 } //setSlipSignalsDonePressed 13345 13346 private boolean getSlipSignalHeadInformation() { 13347 a1SlipHead = getSignalHeadFromEntry(a1SlipSignalHeadComboBox, true, setSignalsAtSlipFrame); 13348 if (a1SlipHead == null) { 13349 return false; 13350 } 13351 a2SlipHead = getSignalHeadFromEntry(a2SlipSignalHeadComboBox, false, setSignalsAtSlipFrame); 13352 13353 b1SlipHead = getSignalHeadFromEntry(b1SlipSignalHeadComboBox, true, setSignalsAtSlipFrame); 13354 if (b1SlipHead == null) { 13355 return false; 13356 } 13357 b2SlipHead = getSignalHeadFromEntry(b2SlipSignalHeadComboBox, false, setSignalsAtSlipFrame); 13358 13359 c1SlipHead = getSignalHeadFromEntry(c1SlipSignalHeadComboBox, true, setSignalsAtSlipFrame); 13360 if (c1SlipHead == null) { 13361 return false; 13362 } 13363 c2SlipHead = getSignalHeadFromEntry(c2SlipSignalHeadComboBox, false, setSignalsAtSlipFrame); 13364 13365 d1SlipHead = getSignalHeadFromEntry(d1SlipSignalHeadComboBox, true, setSignalsAtSlipFrame); 13366 if (d1SlipHead == null) { 13367 return false; 13368 } 13369 d2SlipHead = getSignalHeadFromEntry(d2SlipSignalHeadComboBox, false, setSignalsAtSlipFrame); 13370 13371 return true; 13372 } 13373 13374 private void placeA1Slip(String signalHeadName) { 13375 //place head near the continuing track of turnout 1 13376 //placingBlock(getSignalHeadIcon(signalHeadName), false, 0.0, layoutSlip.getConnectA(), layoutSlip.getCoordsA()); 13377 if (testIcon == null) { 13378 testIcon = signalIconEditor.getIcon(0); 13379 } 13380 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13381 13382 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13383 Point2D coordsA = layoutSlipView.getCoordsA(); 13384 Point2D coordsD = layoutSlipView.getCoordsD(); 13385 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13386 13387 double aDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsA, coordsCenter)); 13388 double dDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsCenter)); 13389 double diffDirDEG = MathUtil.diffAngleDEG(aDirDEG, dDirDEG); 13390 double shiftX = 0.0; 13391 if (diffDirDEG < 0.0) { 13392 shiftX -= shift * Math.cos(Math.toRadians(diffDirDEG)); 13393 } 13394 Point2D delta = new Point2D.Double(shiftX, -shift); 13395 13396 delta = MathUtil.rotateDEG(delta, aDirDEG); 13397 Point2D where = MathUtil.add(coordsA, delta); 13398 setSignalHeadOnPanel(aDirDEG, signalHeadName, where); 13399 } 13400 13401 private void placeA2Slip(String signalHeadName) { 13402 //SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 13403 //placingBlock(l, false, (4 + l.getHeight()), layoutSlip.getConnectA(), layoutSlip.getCoordsA()); 13404 if (testIcon == null) { 13405 testIcon = signalIconEditor.getIcon(0); 13406 } 13407 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13408 13409 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13410 Point2D coordsA = layoutSlipView.getCoordsA(); 13411 Point2D coordsD = layoutSlipView.getCoordsD(); 13412 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13413 13414 double aDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsA, coordsCenter)); 13415 double dDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsCenter)); 13416 double diffDirDEG = MathUtil.diffAngleDEG(aDirDEG, dDirDEG); 13417 double shiftX = 2.0 * shift; 13418 if (diffDirDEG < 0.0) { 13419 shiftX -= shift * Math.cos(Math.toRadians(diffDirDEG)); 13420 } 13421 Point2D delta = new Point2D.Double(shiftX, -shift); 13422 13423 delta = MathUtil.rotateDEG(delta, aDirDEG); 13424 Point2D where = MathUtil.add(coordsA, delta); 13425 setSignalHeadOnPanel(aDirDEG, signalHeadName, where); 13426 } 13427 13428 private void placeB1Slip(String signalHeadName) { 13429 //placingBlock(getSignalHeadIcon(signalHeadName), true, 0.0, layoutSlip.getConnectB(), layoutSlip.getCoordsB()); 13430 if (testIcon == null) { 13431 testIcon = signalIconEditor.getIcon(0); 13432 } 13433 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13434 13435 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13436 Point2D coordsB = layoutSlipView.getCoordsB(); 13437 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13438 13439 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 13440 13441 Point2D delta = new Point2D.Double(+shift, -shift); 13442 delta = MathUtil.rotateDEG(delta, bDirDEG); 13443 Point2D where = MathUtil.add(coordsB, delta); 13444 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 13445 } 13446 13447 private void placeB2Slip(String signalHeadName) { 13448 //SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 13449 //placingBlock(l, true, (4 + l.getHeight()), layoutSlip.getConnectB(), layoutSlip.getCoordsB()); 13450 if (testIcon == null) { 13451 testIcon = signalIconEditor.getIcon(0); 13452 } 13453 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13454 13455 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13456 Point2D coordsB = layoutSlipView.getCoordsB(); 13457 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13458 13459 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 13460 13461 Point2D delta = new Point2D.Double(-shift, -shift); 13462 delta = MathUtil.rotateDEG(delta, bDirDEG); 13463 Point2D where = MathUtil.add(coordsB, delta); 13464 setSignalHeadOnPanel(bDirDEG, signalHeadName, where); 13465 } 13466 13467 private void placeC1Slip(String signalHeadName) { 13468 //placingBlock(getSignalHeadIcon(signalHeadName), false, 0.0, layoutSlip.getConnectC(), layoutSlip.getCoordsC()); 13469 if (testIcon == null) { 13470 testIcon = signalIconEditor.getIcon(0); 13471 } 13472 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13473 13474 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13475 Point2D coordsB = layoutSlipView.getCoordsB(); 13476 Point2D coordsC = layoutSlipView.getCoordsC(); 13477 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13478 13479 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 13480 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 13481 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 13482 double shiftX = 0.0; 13483 if (diffDirDEG < 0.0) { 13484 shiftX -= shift * Math.cos(Math.toRadians(diffDirDEG)); 13485 } 13486 Point2D delta = new Point2D.Double(shiftX, -shift); 13487 13488 delta = MathUtil.rotateDEG(delta, cDirDEG); 13489 Point2D where = MathUtil.add(coordsC, delta); 13490 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 13491 } 13492 13493 private void placeC2Slip(String signalHeadName) { 13494 //SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 13495 //placingBlock(l, false, (4 + l.getHeight()), layoutSlip.getConnectC(), layoutSlip.getCoordsC()); 13496 if (testIcon == null) { 13497 testIcon = signalIconEditor.getIcon(0); 13498 } 13499 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13500 13501 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13502 Point2D coordsB = layoutSlipView.getCoordsB(); 13503 Point2D coordsC = layoutSlipView.getCoordsC(); 13504 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13505 13506 double bDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsB, coordsCenter)); 13507 double cDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsC, coordsCenter)); 13508 double diffDirDEG = MathUtil.diffAngleDEG(cDirDEG, bDirDEG); 13509 double shiftX = 2.0 * shift; 13510 if (diffDirDEG < 0.0) { 13511 shiftX -= shift * Math.cos(Math.toRadians(diffDirDEG)); 13512 } 13513 Point2D delta = new Point2D.Double(shiftX, -shift); 13514 13515 delta = MathUtil.rotateDEG(delta, cDirDEG); 13516 Point2D where = MathUtil.add(coordsC, delta); 13517 setSignalHeadOnPanel(cDirDEG, signalHeadName, where); 13518 } 13519 13520 private void placeD1Slip(String signalHeadName) { 13521 //placingBlock(getSignalHeadIcon(signalHeadName), true, 0.0, layoutSlip.getConnectD(), layoutSlip.getCoordsD()); 13522 if (testIcon == null) { 13523 testIcon = signalIconEditor.getIcon(0); 13524 } 13525 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13526 13527 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13528 Point2D coordsD = layoutSlipView.getCoordsD(); 13529 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13530 13531 double dDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsCenter)); 13532 13533 Point2D delta = new Point2D.Double(+shift, -shift); 13534 delta = MathUtil.rotateDEG(delta, dDirDEG); 13535 Point2D where = MathUtil.add(coordsD, delta); 13536 setSignalHeadOnPanel(dDirDEG, signalHeadName, where); 13537 } 13538 13539 private void placeD2Slip(String signalHeadName) { 13540 //SignalHeadIcon l = getSignalHeadIcon(signalHeadName); 13541 //placingBlock(l, true, (4 + l.getHeight()), layoutSlip.getConnectD(), layoutSlip.getCoordsD()); 13542 if (testIcon == null) { 13543 testIcon = signalIconEditor.getIcon(0); 13544 } 13545 double shift = Math.hypot(testIcon.getIconHeight(), testIcon.getIconWidth()) / 2.0; 13546 13547 LayoutSlipView layoutSlipView = layoutEditor.getLayoutSlipView(layoutSlip); 13548 Point2D coordsD = layoutSlipView.getCoordsD(); 13549 Point2D coordsCenter = layoutSlipView.getCoordsCenter(); 13550 13551 double dDirDEG = MathUtil.wrap360(90.0 - MathUtil.computeAngleDEG(coordsD, coordsCenter)); 13552 13553 Point2D delta = new Point2D.Double(-shift, -shift); 13554 delta = MathUtil.rotateDEG(delta, dDirDEG); 13555 Point2D where = MathUtil.add(coordsD, delta); 13556 setSignalHeadOnPanel(dDirDEG, signalHeadName, where); 13557 } 13558 13559 private void setLogicSlip(SignalHead head, TrackSegment track1, SignalHead secondHead, TrackSegment track2, 13560 boolean setup1, boolean setup2, 13561 LayoutSlip slip, Turnout nearTurnout, Turnout farTurnout, 13562 int continueState, int divergeState, int number) { 13563 //initialize common components and ensure all is defined 13564 LayoutBlock connectorBlock = slip.getLayoutBlock(); 13565 Sensor connectorOccupancy = null; 13566 if (connectorBlock == null) { 13567 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13568 Bundle.getMessage("InfoMessage6"), 13569 Bundle.getMessage("MessageTitle"), 13570 JmriJOptionPane.INFORMATION_MESSAGE); 13571 return; 13572 } 13573 connectorOccupancy = connectorBlock.getOccupancySensor(); 13574 if (connectorOccupancy == null) { 13575 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13576 Bundle.getMessage("InfoMessage4", 13577 new Object[]{connectorBlock.getUserName()}), 13578 Bundle.getMessage("MessageTitle"), 13579 JmriJOptionPane.INFORMATION_MESSAGE); 13580 return; 13581 } 13582 13583 int nearState = layoutSlip.getTurnoutState(nearTurnout, continueState); 13584 int farState = layoutSlip.getTurnoutState(farTurnout, continueState); 13585 13586 //setup signal head for continuing track of far turnout (or both tracks of far turnout) 13587 if ((track1 == null) && setup1) { 13588 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13589 Bundle.getMessage("InfoMessage7"), 13590 Bundle.getMessage("MessageTitle"), 13591 JmriJOptionPane.INFORMATION_MESSAGE); 13592 return; 13593 } 13594 Sensor occupancy = null; 13595 SignalHead nextHead = null; 13596 if ((track1 != null) && setup1) { 13597 LayoutBlock block = track1.getLayoutBlock(); 13598 if (block == null) { 13599 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13600 Bundle.getMessage("InfoMessage6"), 13601 Bundle.getMessage("MessageTitle"), 13602 JmriJOptionPane.INFORMATION_MESSAGE); 13603 return; 13604 } 13605 occupancy = block.getOccupancySensor(); 13606 if (occupancy == null) { 13607 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13608 Bundle.getMessage("InfoMessage4", 13609 new Object[]{block.getUserName()}), 13610 Bundle.getMessage("MessageTitle"), 13611 JmriJOptionPane.INFORMATION_MESSAGE); 13612 return; 13613 } 13614 //need to sort this out??? 13615 nextHead = getNextSignalFromObject(track1, slip, 13616 head.getSystemName(), setSignalsAtSlipFrame); 13617 if ((nextHead == null) && (!reachedEndBumper())) { 13618 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13619 Bundle.getMessage("InfoMessage5", 13620 new Object[]{block.getUserName()}), 13621 Bundle.getMessage("MessageTitle"), 13622 JmriJOptionPane.INFORMATION_MESSAGE); 13623 return; 13624 } 13625 if (secondHead != null) { 13626 //this head signals only the continuing track of the far turnout 13627 if (!initializeBlockBossLogic(head.getDisplayName())) { 13628 return; 13629 } 13630 logic.setMode(BlockBossLogic.TRAILINGMAIN); 13631 if (farState == Turnout.THROWN) { 13632 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 13633 } 13634 logic.setTurnout(farTurnout.getDisplayName()); 13635 logic.setSensor1(occupancy.getDisplayName()); 13636 if (occupancy != connectorOccupancy) { 13637 logic.setSensor2(connectorOccupancy.getDisplayName()); 13638 } 13639 if (nextHead != null) { 13640 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 13641 } 13642 if (auxSignal != null) { 13643 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 13644 } 13645 String nearSensorName = setupNearLogixSlip(nearTurnout, nearState, head, farTurnout, farState, slip, number); 13646 addNearSensorToSlipLogic(nearSensorName); 13647 finalizeBlockBossLogic(); 13648 } 13649 } 13650 if ((secondHead != null) && !setup2) { 13651 return; 13652 } 13653 SignalHead savedAuxSignal = auxSignal; 13654 if (track2 == null) { 13655 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13656 Bundle.getMessage("InfoMessage7"), 13657 Bundle.getMessage("MessageTitle"), 13658 JmriJOptionPane.INFORMATION_MESSAGE); 13659 return; 13660 } 13661 LayoutBlock block2 = track2.getLayoutBlock(); 13662 if (block2 == null) { 13663 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13664 Bundle.getMessage("InfoMessage6"), 13665 Bundle.getMessage("MessageTitle"), 13666 JmriJOptionPane.INFORMATION_MESSAGE); 13667 return; 13668 } 13669 Sensor occupancy2 = block2.getOccupancySensor(); 13670 if (occupancy2 == null) { 13671 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13672 Bundle.getMessage("InfoMessage4", 13673 new Object[]{block2.getUserName()}), 13674 Bundle.getMessage("MessageTitle"), 13675 JmriJOptionPane.INFORMATION_MESSAGE); 13676 return; 13677 } 13678 SignalHead nextHead2 = null; 13679 if (secondHead != null) { 13680 nextHead2 = getNextSignalFromObject(track2, 13681 slip, secondHead.getSystemName(), setSignalsAtSlipFrame); 13682 if ((nextHead2 == null) && (!reachedEndBumper())) { 13683 JmriJOptionPane.showMessageDialog(setSignalsAtSlipFrame, 13684 Bundle.getMessage("InfoMessage5", 13685 new Object[]{block2.getUserName()}), 13686 Bundle.getMessage("MessageTitle"), 13687 JmriJOptionPane.INFORMATION_MESSAGE); 13688 return; 13689 } 13690 } 13691 if ((secondHead == null) && (track1 != null) && setup1) { 13692 if (!initializeBlockBossLogic(head.getDisplayName())) { 13693 return; 13694 } 13695 logic.setMode(BlockBossLogic.FACING); 13696 logic.setTurnout(farTurnout.getDisplayName()); 13697 if (occupancy != null) { 13698 logic.setWatchedSensor1(occupancy.getDisplayName()); 13699 } 13700 logic.setWatchedSensor2(occupancy2.getDisplayName()); 13701 logic.setSensor2(connectorOccupancy.getDisplayName()); 13702 if (nextHead != null) { 13703 logic.setWatchedSignal1(nextHead.getDisplayName(), false); 13704 } 13705 if (savedAuxSignal != null) { 13706 logic.setWatchedSignal1Alt(savedAuxSignal.getDisplayName()); 13707 } 13708 if (nextHead2 != null) { 13709 logic.setWatchedSignal2(nextHead2.getDisplayName()); 13710 } 13711 if (auxSignal != null) { 13712 logic.setWatchedSignal2Alt(auxSignal.getDisplayName()); 13713 } 13714 String nearSensorName = setupNearLogixSlip(nearTurnout, nearState, head, farTurnout, farState, slip, number + 1); 13715 addNearSensorToSlipLogic(nearSensorName); 13716 logic.setLimitSpeed2(true); 13717 finalizeBlockBossLogic(); 13718 } else if ((secondHead != null) && setup2) { 13719 if (!initializeBlockBossLogic(secondHead.getDisplayName())) { 13720 return; 13721 } 13722 nearState = layoutSlip.getTurnoutState(nearTurnout, divergeState); 13723 farState = layoutSlip.getTurnoutState(farTurnout, divergeState); 13724 13725 logic.setMode(BlockBossLogic.TRAILINGDIVERGING); 13726 if (farState == Turnout.CLOSED) { 13727 logic.setMode(BlockBossLogic.TRAILINGMAIN); 13728 logic.setLimitSpeed1(true); 13729 } else { 13730 logic.setLimitSpeed2(true); 13731 } 13732 logic.setTurnout(farTurnout.getDisplayName()); 13733 logic.setSensor1(occupancy2.getDisplayName()); 13734 if (occupancy2 != connectorOccupancy) { 13735 logic.setSensor2(connectorOccupancy.getDisplayName()); 13736 } 13737 if (nextHead2 != null) { 13738 logic.setWatchedSignal1(nextHead2.getDisplayName(), false); 13739 } 13740 if (auxSignal != null) { 13741 logic.setWatchedSignal1Alt(auxSignal.getDisplayName()); 13742 } 13743 String nearSensorName = setupNearLogixSlip(nearTurnout, nearState, secondHead, farTurnout, farState, slip, number + 1); 13744 addNearSensorToSlipLogic(nearSensorName); 13745 finalizeBlockBossLogic(); 13746 } 13747 } //setLogicSlip 13748 13749 private String setupNearLogixSlip(Turnout turn, int nearState, 13750 SignalHead head, Turnout farTurn, int farState, LayoutSlip slip, int number) { 13751 String turnoutName = turn.getDisplayName(); 13752 String farTurnoutName = farTurn.getDisplayName(); 13753 13754 String logixPrefix = InstanceManager.getDefault(jmri.LogixManager.class).getSystemNamePrefix(); 13755 String pref = InstanceManager.getDefault(jmri.LogixManager.class).getSystemPrefix(); 13756 String logixName = logixPrefix + ":IX_LAYOUTSLIP:" + slip.getId(); 13757 String sensorName = pref + "S:" + logixName + "C" + number; 13758 try { 13759 InstanceManager.sensorManagerInstance().provideSensor(sensorName); 13760 } catch (IllegalArgumentException ex) { 13761 log.error("Trouble creating sensor {} while setting up Logix.", sensorName); 13762 return ""; 13763 } 13764 boolean newConditional = false; 13765 Logix x = InstanceManager.getDefault(LogixManager.class 13766 ).getBySystemName(logixName); 13767 13768 if (x == null) { 13769 x = InstanceManager.getDefault(LogixManager.class 13770 ).createNewLogix(logixName, ""); 13771 newConditional = true; 13772 if (x == null) { 13773 log.error("Trouble creating logix {} while setting up signal logic.", logixName); 13774 return ""; 13775 } 13776 x.setComment("Layout Slip, Signalhead logic"); 13777 } 13778 x.deActivateLogix(); 13779 String cName = logixName + "C" + number; 13780 13781 Conditional c = InstanceManager.getDefault(ConditionalManager.class 13782 ).getBySystemName(cName); 13783 13784 if (c == null) { 13785 c = InstanceManager.getDefault(ConditionalManager.class 13786 ). 13787 createNewConditional(cName, ""); 13788 newConditional = true; 13789 if (c == null) { 13790 log.error("Trouble creating conditional {} while setting up Logix.", cName); 13791 return ""; 13792 } 13793 } 13794 Conditional.Type type = Conditional.Type.TURNOUT_THROWN; 13795 if (nearState == Turnout.CLOSED) { 13796 type = Conditional.Type.TURNOUT_CLOSED; 13797 } 13798 ArrayList<ConditionalVariable> variableList = new ArrayList<>(); 13799 variableList.add(new ConditionalVariable(false, Conditional.Operator.AND, 13800 type, turnoutName, true)); 13801 13802 type = Conditional.Type.TURNOUT_THROWN; 13803 if (farState == Turnout.CLOSED) { 13804 type = Conditional.Type.TURNOUT_CLOSED; 13805 } 13806 variableList.add(new ConditionalVariable(false, Conditional.Operator.AND, 13807 type, farTurnoutName, true)); 13808 c.setStateVariables(variableList); 13809 ArrayList<ConditionalAction> actionList = new ArrayList<>(); 13810 actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE, 13811 Conditional.Action.SET_SENSOR, sensorName, 13812 Sensor.INACTIVE, "")); 13813 actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_FALSE, 13814 Conditional.Action.SET_SENSOR, sensorName, 13815 Sensor.ACTIVE, "")); 13816 c.setAction(actionList); //string data 13817 if (newConditional) { 13818 x.addConditional(cName, -1); 13819 } 13820 x.activateLogix(); 13821 return sensorName; 13822 } //setupNearLogixSlip 13823 13824 /* 13825 * Adds the sensor specified to the open BlockBossLogic, provided it is not already there and 13826 * provided there is an open slot. If 'name' is null or empty, returns without doing anything. 13827 */ 13828 private void addNearSensorToSlipLogic(String name) { 13829 if ((name != null) && !name.isEmpty()) { 13830 //return if a sensor by this name is already present 13831 if (logic.getSensor1() != null && logic.getSensor1().equals(name)) { 13832 return; 13833 } 13834 if (logic.getSensor2() != null && logic.getSensor2().equals(name)) { 13835 return; 13836 } 13837 if (logic.getSensor3() != null && logic.getSensor3().equals(name)) { 13838 return; 13839 } 13840 if (logic.getSensor4() != null && logic.getSensor4().equals(name)) { 13841 return; 13842 } 13843 if (logic.getSensor5() != null && logic.getSensor5().equals(name)) { 13844 return; 13845 } 13846 //add in the first available slot 13847 if (logic.getSensor1() == null) { 13848 logic.setSensor1(name); 13849 } else if (logic.getSensor2() == null) { 13850 logic.setSensor2(name); 13851 } else if (logic.getSensor3() == null) { 13852 logic.setSensor3(name); 13853 } else if (logic.getSensor4() == null) { 13854 logic.setSensor4(name); 13855 } else if (logic.getSensor5() == null) { 13856 logic.setSensor5(name); 13857 } else { 13858 log.error("Error - could not add sensor to SSL for signal head {}", logic.getDrivenSignal()); 13859 } 13860 } 13861 } 13862 13863 /** 13864 * get a signal head icon for the given signal head 13865 * 13866 * @param signalName name of a signal head. 13867 * @return a SignalHeadIcon for the signal. 13868 */ 13869 @CheckReturnValue 13870 public SignalHeadIcon getSignalHeadIcon(@Nonnull String signalName) { 13871 if (signalIconEditor == null) { 13872 signalIconEditor = layoutEditor.getLayoutEditorToolBarPanel().signalIconEditor; 13873 } 13874 SignalHeadIcon l = new SignalHeadIcon(layoutEditor); 13875 l.setSignalHead(signalName); 13876 l.setIcon("SignalHeadStateRed", signalIconEditor.getIcon(0)); 13877 l.setIcon("SignalHeadStateFlashingRed", signalIconEditor.getIcon(1)); 13878 l.setIcon("SignalHeadStateYellow", signalIconEditor.getIcon(2)); 13879 l.setIcon("SignalHeadStateFlashingYellow", signalIconEditor.getIcon(3)); 13880 l.setIcon("SignalHeadStateGreen", signalIconEditor.getIcon(4)); 13881 l.setIcon("SignalHeadStateFlashingGreen", signalIconEditor.getIcon(5)); 13882 l.setIcon("SignalHeadStateDark", signalIconEditor.getIcon(6)); 13883 l.setIcon("SignalHeadStateHeld", signalIconEditor.getIcon(7)); 13884 l.setIcon("SignalHeadStateLunar", signalIconEditor.getIcon(8)); 13885 l.setIcon("SignalHeadStateFlashingLunar", signalIconEditor.getIcon(9)); 13886 l.rotate(90); 13887 return l; 13888 } 13889 13890 //convenience strings 13891 private final String eastString = Bundle.getMessage("East"); 13892 private final String westString = Bundle.getMessage("West"); 13893 private final String continuingString = Bundle.getMessage("Continuing"); 13894 private final String divergingString = Bundle.getMessage("Diverging"); 13895 private final String throatString = Bundle.getMessage("Throat"); 13896 private final String throatContinuingString = Bundle.getMessage("ThroatContinuing"); 13897 private final String throatDivergingString = Bundle.getMessage("ThroatDiverging"); 13898 13899 private final String divergingAString = Bundle.getMessage("Diverging_", "A"); 13900 private final String divergingBString = Bundle.getMessage("Diverging_", "B"); 13901 13902 protected Boolean addLayoutTurnoutSignalHeadInfoToMenu( 13903 @Nonnull String inTurnoutNameA, @Nonnull String inTurnoutNameB, 13904 @Nonnull JMenu inMenu) { 13905 Boolean result = false; //assume failure (pessimist!) 13906 13907 //lookup turnouts 13908 turnout = turnout1 = turnoutA = InstanceManager.turnoutManagerInstance().getTurnout(inTurnoutNameA); 13909 turnout2 = turnoutB = InstanceManager.turnoutManagerInstance().getTurnout(inTurnoutNameB); 13910 //map those to layout turnouts (if possible) 13911 for (LayoutTurnout lt : layoutEditor.getLayoutTurnouts()) { 13912 Turnout to = lt.getTurnout(); 13913 if (to != null) { 13914 String uname = to.getUserName(); 13915 String sname = to.getSystemName(); 13916 if (!inTurnoutNameA.isEmpty() && (sname.equals(inTurnoutNameA) || ((uname != null) && uname.equals(inTurnoutNameA)))) { 13917 layoutTurnout = layoutTurnout1 = layoutTurnoutA = lt; 13918 } 13919 if (!inTurnoutNameB.isEmpty() && (sname.equals(inTurnoutNameB) || ((uname != null) && uname.equals(inTurnoutNameB)))) { 13920 layoutTurnout2 = layoutTurnoutB = lt; 13921 } 13922 } 13923 } 13924 13925 int before_mcc = inMenu.getMenuComponentCount(); 13926 if (before_mcc != 0) { 13927 inMenu.add(new JSeparator()); 13928 } 13929 LayoutTurnout.LinkType linkType = layoutTurnout.getLinkType(); 13930 if ((layoutTurnout.getTurnoutType() == LayoutTurnout.TurnoutType.DOUBLE_XOVER) 13931 || (layoutTurnout.getTurnoutType() == LayoutTurnout.TurnoutType.RH_XOVER) 13932 || (layoutTurnout.getTurnoutType() == LayoutTurnout.TurnoutType.LH_XOVER)) { 13933 JMenuItem jmi = inMenu.add(Bundle.getMessage("Crossover")); 13934 jmi.setEnabled(false); 13935 inMenu.add(new JSeparator()); 13936 before_mcc += 2; 13937 addInfoToMenu("A " + continuingString, layoutTurnout.getSignalA1Name(), inMenu); 13938 addInfoToMenu("A " + divergingString, layoutTurnout.getSignalA2Name(), inMenu); 13939 addInfoToMenu("B " + continuingString, layoutTurnout.getSignalB1Name(), inMenu); 13940 addInfoToMenu("B " + divergingString, layoutTurnout.getSignalB2Name(), inMenu); 13941 addInfoToMenu("C " + continuingString, layoutTurnout.getSignalC1Name(), inMenu); 13942 addInfoToMenu("C " + divergingString, layoutTurnout.getSignalC2Name(), inMenu); 13943 addInfoToMenu("D " + continuingString, layoutTurnout.getSignalD1Name(), inMenu); 13944 addInfoToMenu("D " + divergingString, layoutTurnout.getSignalD2Name(), inMenu); 13945 } else if (linkType == LayoutTurnout.LinkType.NO_LINK) { 13946 JMenuItem jmi = inMenu.add(Bundle.getMessage("BeanNameTurnout")); 13947 jmi.setEnabled(false); 13948 inMenu.add(new JSeparator()); 13949 before_mcc += 2; 13950 addInfoToMenu(throatContinuingString, layoutTurnout.getSignalA1Name(), inMenu); 13951 addInfoToMenu(throatDivergingString, layoutTurnout.getSignalA2Name(), inMenu); 13952 addInfoToMenu(continuingString, layoutTurnout.getSignalB1Name(), inMenu); 13953 addInfoToMenu(divergingString, layoutTurnout.getSignalC1Name(), inMenu); 13954 } else if (linkType == LayoutTurnout.LinkType.THROAT_TO_THROAT) { 13955 String menuString = Bundle.getMessage("ThroatToThroat") + " ("; 13956 menuString += Bundle.getMessage("BeanNameTurnout") + ", " + Bundle.getMessage("BeanNameRoute"); 13957 menuString += ", " + Bundle.getMessage("BeanNameSignalHead") + ":)"; 13958 JMenuItem jmi = inMenu.add(menuString); 13959 jmi.setEnabled(false); 13960 inMenu.add(new JSeparator()); 13961 before_mcc += 2; 13962 addInfoToMenu(eastString + ", " + continuingString + ", " + continuingString, layoutTurnout1.getSignalB1Name(), inMenu); 13963 addInfoToMenu(eastString + ", " + continuingString + ", " + divergingString, layoutTurnout1.getSignalB2Name(), inMenu); 13964 addInfoToMenu(eastString + ", " + divergingString + ", " + continuingString, layoutTurnout1.getSignalC1Name(), inMenu); 13965 addInfoToMenu(eastString + ", " + divergingString + ", " + divergingString, layoutTurnout1.getSignalC2Name(), inMenu); 13966 addInfoToMenu(westString + ", " + continuingString + ", " + continuingString, layoutTurnout2.getSignalB1Name(), inMenu); 13967 addInfoToMenu(westString + ", " + continuingString + ", " + divergingString, layoutTurnout2.getSignalB2Name(), inMenu); 13968 addInfoToMenu(westString + ", " + divergingString + ", " + continuingString, layoutTurnout2.getSignalC1Name(), inMenu); 13969 addInfoToMenu(westString + ", " + divergingString + ", " + divergingString, layoutTurnout2.getSignalC2Name(), inMenu); 13970 } else if (linkType == LayoutTurnout.LinkType.FIRST_3_WAY) { 13971 JMenuItem jmi = inMenu.add(Bundle.getMessage("ThreeWay")); 13972 jmi.setEnabled(false); 13973 inMenu.add(new JSeparator()); 13974 before_mcc += 2; 13975 addInfoToMenu(throatString + " " + continuingString, layoutTurnoutA.getSignalA1Name(), inMenu); 13976 addInfoToMenu(throatString + " " + divergingAString, layoutTurnoutA.getSignalA2Name(), inMenu); 13977 addInfoToMenu(throatString + " " + divergingBString, layoutTurnoutA.getSignalA3Name(), inMenu); 13978 addInfoToMenu(continuingString, layoutTurnoutA.getSignalC1Name(), inMenu); 13979 addInfoToMenu(divergingAString, layoutTurnoutB.getSignalB1Name(), inMenu); 13980 addInfoToMenu(divergingBString, layoutTurnoutB.getSignalC1Name(), inMenu); 13981 } else if (linkType == LayoutTurnout.LinkType.SECOND_3_WAY) { 13982 JMenuItem jmi = inMenu.add(Bundle.getMessage("ThreeWay")); 13983 jmi.setEnabled(false); 13984 inMenu.add(new JSeparator()); 13985 before_mcc += 2; 13986 addInfoToMenu(throatString + " " + continuingString, layoutTurnoutB.getSignalA1Name(), inMenu); 13987 addInfoToMenu(throatString + " " + divergingAString, layoutTurnoutB.getSignalA2Name(), inMenu); 13988 addInfoToMenu(throatString + " " + divergingBString, layoutTurnoutB.getSignalA3Name(), inMenu); 13989 addInfoToMenu(continuingString, layoutTurnoutB.getSignalC1Name(), inMenu); 13990 addInfoToMenu(divergingAString, layoutTurnoutA.getSignalB1Name(), inMenu); 13991 addInfoToMenu(divergingBString, layoutTurnoutA.getSignalC1Name(), inMenu); 13992 } 13993 int after_mcc = inMenu.getMenuComponentCount(); 13994 if (before_mcc != after_mcc) { 13995 inMenu.add(new JSeparator()); 13996 result = true; //it's GOOD! 13997 } 13998 return result; 13999 } //addLayoutTurnoutSignalHeadInfoToMenu 14000 14001 protected Boolean addBlockBoundarySignalHeadInfoToMenu( 14002 @Nonnull PositionablePoint inPositionablePoint, 14003 @Nonnull JMenu inMenu) { 14004 Boolean result = false; //assume failure (pessimist!) 14005 14006 int before_mcc = inMenu.getMenuComponentCount(); 14007 if (before_mcc != 0) { 14008 inMenu.add(new JSeparator()); 14009 } 14010 14011 JMenuItem jmi = inMenu.add(Bundle.getMessage("BlockBoundary")); 14012 jmi.setEnabled(false); 14013 inMenu.add(new JSeparator()); 14014 before_mcc += 2; 14015 14016 addInfoToMenu(Bundle.getMessage("East/SouthBound"), inPositionablePoint.getEastBoundSignal(), inMenu); 14017 addInfoToMenu(Bundle.getMessage("West/NorthBound"), inPositionablePoint.getWestBoundSignal(), inMenu); 14018 14019 int after_mcc = inMenu.getMenuComponentCount(); 14020 if (before_mcc != after_mcc) { 14021 inMenu.add(new JSeparator()); 14022 result = true; //it's GOOD! 14023 } 14024 14025 return result; 14026 } 14027 14028 protected Boolean addLevelXingSignalHeadInfoToMenu( 14029 @Nonnull LevelXing inLevelXing, 14030 @Nonnull JMenu inMenu) { 14031 Boolean result = false; //assume failure (pessimist!) 14032 14033 int before_mcc = inMenu.getMenuComponentCount(); 14034 if (before_mcc != 0) { 14035 inMenu.add(new JSeparator()); 14036 } 14037 14038 JMenuItem jmi = inMenu.add(Bundle.getMessage("LevelCrossing")); 14039 jmi.setEnabled(false); 14040 inMenu.add(new JSeparator()); 14041 before_mcc += 2; 14042 14043 addInfoToMenu(Bundle.getMessage("MakeLabel", 14044 Bundle.getMessage("TrackXConnect", "A")), 14045 inLevelXing.getSignalAName(), inMenu); 14046 addInfoToMenu(Bundle.getMessage("MakeLabel", 14047 Bundle.getMessage("TrackXConnect", "B")), 14048 inLevelXing.getSignalBName(), inMenu); 14049 addInfoToMenu(Bundle.getMessage("MakeLabel", 14050 Bundle.getMessage("TrackXConnect", "C")), 14051 inLevelXing.getSignalCName(), inMenu); 14052 addInfoToMenu(Bundle.getMessage("MakeLabel", 14053 Bundle.getMessage("TrackXConnect", "D")), 14054 inLevelXing.getSignalDName(), inMenu); 14055 14056 int after_mcc = inMenu.getMenuComponentCount(); 14057 if (before_mcc != after_mcc) { 14058 inMenu.add(new JSeparator()); 14059 result = true; //it's GOOD! 14060 } 14061 14062 return result; 14063 } 14064 14065 protected Boolean addLayoutSlipSignalHeadInfoToMenu( 14066 @Nonnull LayoutTurnout inLayoutTurnout, 14067 @Nonnull JMenu inMenu) { 14068 Boolean result = false; //assume failure (pessimist!) 14069 14070 int before_mcc = inMenu.getMenuComponentCount(); 14071 if (before_mcc != 0) { 14072 inMenu.add(new JSeparator()); 14073 } 14074 14075 JMenuItem jmi = inMenu.add(Bundle.getMessage("Slip")); 14076 jmi.setEnabled(false); 14077 inMenu.add(new JSeparator()); 14078 before_mcc += 2; 14079 14080 addInfoToMenu("A " + continuingString, inLayoutTurnout.getSignalA1Name(), inMenu); 14081 addInfoToMenu("A " + divergingString, inLayoutTurnout.getSignalA2Name(), inMenu); 14082 addInfoToMenu("B " + continuingString, inLayoutTurnout.getSignalB1Name(), inMenu); 14083 addInfoToMenu("B " + divergingString, inLayoutTurnout.getSignalB2Name(), inMenu); 14084 addInfoToMenu("C " + continuingString, inLayoutTurnout.getSignalC1Name(), inMenu); 14085 addInfoToMenu("C " + divergingString, inLayoutTurnout.getSignalC2Name(), inMenu); 14086 addInfoToMenu("D " + continuingString, inLayoutTurnout.getSignalD1Name(), inMenu); 14087 addInfoToMenu("D " + divergingString, inLayoutTurnout.getSignalD2Name(), inMenu); 14088 14089 int after_mcc = inMenu.getMenuComponentCount(); 14090 if (before_mcc != after_mcc) { 14091 inMenu.add(new JSeparator()); 14092 result = true; //it's GOOD! 14093 } 14094 14095 return result; 14096 } 14097 14098 private void addInfoToMenu(@CheckForNull String title, 14099 @CheckForNull String info, @Nonnull JMenu menu) { 14100 if ((title != null) && !title.isEmpty() && (info != null) && !info.isEmpty()) { 14101 addInfoToMenu(title + ": " + info, menu); 14102 } 14103 } 14104 14105 private void addInfoToMenu(@CheckForNull String info, @Nonnull JMenu menu) { 14106 if ((info != null) && !info.isEmpty()) { 14107 JMenuItem jmi = new JMenuItem(info); 14108 jmi.setEnabled(false); 14109 menu.add(jmi); 14110 } 14111 } 14112 14113 private void oneFrameToRuleThemAll(@Nonnull JmriJFrame goodFrame) { 14114 setSensorsAtBlockBoundaryFrame = closeIfNotFrame(goodFrame, setSensorsAtBlockBoundaryFrame); 14115 setSensorsAtLevelXingFrame = closeIfNotFrame(goodFrame, setSensorsAtLevelXingFrame); 14116 setSensorsAtSlipFrame = closeIfNotFrame(goodFrame, setSensorsAtSlipFrame); 14117 setSensorsAtTurnoutFrame = closeIfNotFrame(goodFrame, setSensorsAtTurnoutFrame); 14118 setSignalMastsAtBlockBoundaryFrame = closeIfNotFrame(goodFrame, setSignalMastsAtBlockBoundaryFrame); 14119 setSignalMastsAtLayoutSlipFrame = closeIfNotFrame(goodFrame, setSignalMastsAtLayoutSlipFrame); 14120 setSignalMastsAtLevelXingFrame = closeIfNotFrame(goodFrame, setSignalMastsAtLevelXingFrame); 14121 setSignalMastsAtTurnoutFrame = closeIfNotFrame(goodFrame, setSignalMastsAtTurnoutFrame); 14122 setSignalsAt3WayTurnoutFrame = closeIfNotFrame(goodFrame, setSignalsAt3WayTurnoutFrame); 14123 setSignalsAtBlockBoundaryFrame = closeIfNotFrame(goodFrame, setSignalsAtBlockBoundaryFrame); 14124 setSignalsAtLevelXingFrame = closeIfNotFrame(goodFrame, setSignalsAtLevelXingFrame); 14125 setSignalsAtSlipFrame = closeIfNotFrame(goodFrame, setSignalsAtSlipFrame); 14126 setSignalsAtThroatToThroatTurnoutsFrame = closeIfNotFrame(goodFrame, setSignalsAtThroatToThroatTurnoutsFrame); 14127 setSignalsAtTurnoutFrame = closeIfNotFrame(goodFrame, setSignalsAtTurnoutFrame); 14128 setSignalsAtXoverTurnoutFrame = closeIfNotFrame(goodFrame, setSignalsAtXoverTurnoutFrame); 14129 } 14130 14131 private JmriJFrame closeIfNotFrame(@Nonnull JmriJFrame goodFrame, @CheckForNull JmriJFrame badFrame) { 14132 JmriJFrame result = badFrame; 14133 if ((badFrame != null) && (goodFrame != badFrame)) { 14134 badFrame.setVisible(false); 14135 badFrame.dispose(); 14136 result = null; 14137 } 14138 return result; 14139 } 14140 14141 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LayoutEditorTools.class); 14142}