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