001package jmri.jmrit.beantable; 002 003import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 004 005import java.awt.*; 006import java.awt.event.ActionEvent; 007import java.util.ArrayList; 008import java.util.List; 009import java.util.Objects; 010import java.util.Vector; 011 012import javax.annotation.CheckForNull; 013import javax.annotation.Nonnull; 014import javax.swing.*; 015import javax.swing.border.Border; 016import javax.swing.border.TitledBorder; 017 018import jmri.*; 019import jmri.implementation.*; 020import jmri.jmrix.acela.*; 021import jmri.jmrix.grapevine.GrapevineSystemConnectionMemo; 022import jmri.jmrix.grapevine.SerialSignalHead; 023import jmri.util.*; 024import jmri.util.swing.*; 025 026/** 027 * Frame for creating / editing Signal Heads. 028 * 029 * Code originally located within SignalHeadTableAction.java 030 * 031 * @author Bob Jacobsen Copyright (C) 2003,2006,2007, 2008, 2009 032 * @author Petr Koud'a Copyright (C) 2007 033 * @author Egbert Broerse Copyright (C) 2016 034 * @author Steve Young Copyright (C) 2023 035 */ 036public class SignalHeadAddEditFrame extends JmriJFrame { 037 038 public SignalHeadAddEditFrame(@CheckForNull SignalHead head){ 039 super(Bundle.getMessage(head==null ? "TitleAddSignalHead" : "TitleEditSignalHead"), false, true); 040 041 signalHeadBeingEdited = head; 042 } 043 044 private final SignalHead signalHeadBeingEdited; 045 046 private final NamedBeanHandleManager nbhm = InstanceManager.getDefault(NamedBeanHandleManager.class); 047 048 private final JTextField systemNameField = new JTextField(5); 049 private final JTextField userNameField = new JTextField(10); 050 051 private final JLabel systemNameLabel = new JLabel(""); 052 private final JLabel userNameLabel = new JLabel(""); 053 054 private JPanel dccOptionsPanel = new JPanel(); 055 private JPanel dccAppearanceNumberingPanel = new JPanel(); 056 private JPanel dccAppearanceCopyPanel = new JPanel(); 057 058 private JPanel acelaHeadPanel = new JPanel(); 059 060 // we share input fields across boxes so that 061 // entries in one don't disappear when the user switches 062 // to a different type 063 private JPanel centrePanel1 = new JPanel(); 064 private JPanel centrePanel2 = new JPanel(); 065 private JPanel centrePanel3 = new JPanel(); 066 private JPanel centrePanel4 = new JPanel(); 067 private JPanel centrePanel5 = new JPanel(); 068 private JPanel centrePanel6 = new JPanel(); 069 private JPanel centrePanel7 = new JPanel(); 070 071 private final FlowLayout defaultFlow = new FlowLayout(FlowLayout.CENTER, 5, 0); 072 private final Border blackline = BorderFactory.createLineBorder(Color.black); 073 074 private final TitledBorder centrePanBorder1 = BorderFactory.createTitledBorder(blackline); 075 private final TitledBorder centrePanBorder2 = BorderFactory.createTitledBorder(blackline); 076 private final TitledBorder centrePanBorder3 = BorderFactory.createTitledBorder(blackline); 077 private final TitledBorder centrePanBorder4 = BorderFactory.createTitledBorder(blackline); 078 private final TitledBorder centrePanBorder5 = BorderFactory.createTitledBorder(blackline); 079 private final TitledBorder centrePanBorder6 = BorderFactory.createTitledBorder(blackline); 080 private final TitledBorder centrePanBorder7 = BorderFactory.createTitledBorder(blackline); 081 082 private BeanSelectCreatePanel<Turnout> turnoutSelect1; 083 private BeanSelectCreatePanel<Turnout> turnoutSelect2; 084 private BeanSelectCreatePanel<Turnout> turnoutSelect3; 085 private BeanSelectCreatePanel<Turnout> turnoutSelect4; 086 private BeanSelectCreatePanel<Turnout> turnoutSelect5; 087 private BeanSelectCreatePanel<Turnout> turnoutSelect6; 088 private BeanSelectCreatePanel<Turnout> turnoutSelect7; 089 090 private final static String TURNOUT_STATE_THROWN = InstanceManager.getDefault(TurnoutManager.class).getThrownText(); 091 private final static String TURNOUT_STATE_CLOSED = InstanceManager.getDefault(TurnoutManager.class).getClosedText(); 092 093 private final static int[] TURNOUT_STATE_VALUES = new int[]{Turnout.CLOSED, Turnout.THROWN}; 094 private final static String[] TURNOUT_STATE_STRINGS = new String[]{TURNOUT_STATE_CLOSED, TURNOUT_STATE_THROWN}; 095 096 private final static String[] SIGNAL_STATE_STRINGS = new String[]{ 097 Bundle.getMessage("SignalHeadStateDark"), 098 Bundle.getMessage("SignalHeadStateRed"), 099 Bundle.getMessage("SignalHeadStateLunar"), 100 Bundle.getMessage("SignalHeadStateYellow"), 101 Bundle.getMessage("SignalHeadStateGreen") 102 }; 103 104 private final static int[] SIGNAL_STATE_VALUES = new int[]{ 105 SignalHead.DARK, 106 SignalHead.RED, 107 SignalHead.LUNAR, 108 SignalHead.YELLOW, 109 SignalHead.GREEN 110 }; 111 112 private final static String ACELA_ASPECT = Bundle.getMessage("StringAcelaaspect"); 113 private final static String SE8C4_ASPECT = Bundle.getMessage("StringSE8c4aspect"); 114 private final static String TRIPLE_OUTPUT = Bundle.getMessage("StringTripleOutput"); 115 private final static String QUAD_OUTPUT = Bundle.getMessage("StringQuadOutput"); 116 private final static String SINGLE_TURNOUT = Bundle.getMessage("StringSingle"); 117 private final static String DOUBLE_TURNOUT = Bundle.getMessage("StringDoubleTurnout"); 118 private final static String TRIPLE_TURNOUT = Bundle.getMessage("StringTripleTurnout"); 119 private final static String VIRTUAL_HEAD = Bundle.getMessage("StringVirtual"); 120 private final static String GRAPEVINE = Bundle.getMessage("StringGrapevine"); 121 private final static String LSDEC = Bundle.getMessage("StringLsDec"); 122 private final static String DCC_SIGNAL_DECODER = Bundle.getMessage("StringDccSigDec"); 123 private final static String MERG_SIGNAL_DRIVER = Bundle.getMessage("StringMerg"); 124 125 private final static String ACELA_SIG_HEAD_DOUBLE = Bundle.getMessage("StringSignalheadDouble"); 126 private final static String ACELA_SIG_HEAD_TRIPLE = Bundle.getMessage("StringSignalheadTriple"); 127 // private final static String ACELA_SIG_HEAD_RGB = Bundle.getMessage("StringSignalheadRGB"); 128 private final static String ACELA_SIG_HEAD_BIPLOAR = Bundle.getMessage("StringSignalheadBiPolar"); 129 private final static String ACELA_SIG_HEAD_WIGWAG = Bundle.getMessage("StringSignalheadWigwag"); 130 131 private final static String[] ACELA_SIG_HEAD_TYPES = new String[]{ACELA_SIG_HEAD_DOUBLE, ACELA_SIG_HEAD_TRIPLE, 132 ACELA_SIG_HEAD_BIPLOAR, ACELA_SIG_HEAD_WIGWAG}; 133 134 private final static int[] ACELA_SIG_HEAD_TYPE_VALUES = new int[]{AcelaNode.DOUBLE, AcelaNode.TRIPLE, 135 AcelaNode.BPOLAR, AcelaNode.WIGWAG}; 136 137 private final static String[] UK_SEMAPHORE_TYPES = new String[]{Bundle.getMessage("HomeSignal"), Bundle.getMessage("DistantSignal")}; 138 private final static String[] UK_SIGNAL_ASPECTS = new String[]{"2", "3", "4"}; // NOI18N 139 140 private final JLabel dccPacketSendCount = new JLabel(Bundle.getMessage("DCCMastPacketSendCount")); 141 private final JSpinner dccPacketSendCountSpinner = new JSpinner(); 142 143 private JSpinner[] dccAspectSpinners; 144 private final JCheckBox dccOffSetAddressCheckBox = new JCheckBox(Bundle.getMessage("DccAccessoryAddressOffSet")); 145 146 private JComboBox<String> headTypeBox; 147 private final JLabel headTypeLabel = new JLabel(); 148 149 private final JComboBox<String> prefixBox = new JComboBox<>(); 150 private final JLabel prefixBoxLabel = new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("DCCSystem"))); 151 152 private final JLabel stateLabel1 = new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("TurnoutState"))); 153 private final JLabel stateLabel2 = new JLabel(stateLabel1.getText()); // faster than Bundle? 154 private final JLabel stateLabel3 = new JLabel(stateLabel1.getText()); 155 private final JLabel stateLabel4 = new JLabel(stateLabel1.getText()); 156 private final JLabel stateLabel5 = new JLabel(stateLabel1.getText()); 157 private final JLabel stateLabel6 = new JLabel(stateLabel1.getText()); 158 private final JLabel stateLabel7 = new JLabel(stateLabel1.getText()); 159 160 private final JComboBox<String> turnoutStateBox1 = new JComboBox<>(TURNOUT_STATE_STRINGS); 161 private final JComboBox<String> turnoutStateBox2 = new JComboBox<>(TURNOUT_STATE_STRINGS); 162 private final JComboBox<String> turnoutStateBox3 = new JComboBox<>(TURNOUT_STATE_STRINGS); 163 private final JComboBox<String> turnoutStateBox4 = new JComboBox<>(TURNOUT_STATE_STRINGS); 164 private final JComboBox<String> turnoutStateBox5 = new JComboBox<>(TURNOUT_STATE_STRINGS); 165 private final JComboBox<String> turnoutStateBox6 = new JComboBox<>(TURNOUT_STATE_STRINGS); 166 private final JComboBox<String> turnoutStateBox7 = new JComboBox<>(TURNOUT_STATE_STRINGS); 167 168 private final JComboBox<String> signalStateBox2 = new JComboBox<>(SIGNAL_STATE_STRINGS); 169 private final JComboBox<String> signalStateBox3 = new JComboBox<>(SIGNAL_STATE_STRINGS); 170 171 private final JComboBox<String> acelaHeadTypeBox = new JComboBox<>(ACELA_SIG_HEAD_TYPES); 172 173 private final JComboBox<String> ukSignalSemaphoreTypeBox = new JComboBox<>(UK_SEMAPHORE_TYPES); 174 private final JComboBox<String> numberUkAspectsBox = new JComboBox<>(UK_SIGNAL_ASPECTS); 175 176 protected SignalHead getSignalHead(){ 177 return signalHeadBeingEdited; 178 } 179 180 protected void resetAddressFields(){ 181 this.systemNameField.setText(""); 182 this.userNameField.setText(""); 183 } 184 185 @Override 186 public void initComponents(){ 187 188 addHelpMenu("package.jmri.jmrit.beantable.SignalAddEdit", true); 189 190 for (CommandStation station : InstanceManager.getList(CommandStation.class)) { 191 prefixBox.addItem(station.getUserName()); 192 } 193 194 initDccAppearancePanel(); 195 turnoutSelect1 = new BeanSelectCreatePanel<>(InstanceManager.getDefault(TurnoutManager.class), null); 196 turnoutSelect2 = new BeanSelectCreatePanel<>(InstanceManager.getDefault(TurnoutManager.class), null); 197 turnoutSelect3 = new BeanSelectCreatePanel<>(InstanceManager.getDefault(TurnoutManager.class), null); 198 turnoutSelect4 = new BeanSelectCreatePanel<>(InstanceManager.getDefault(TurnoutManager.class), null); 199 turnoutSelect5 = new BeanSelectCreatePanel<>(InstanceManager.getDefault(TurnoutManager.class), null); 200 turnoutSelect6 = new BeanSelectCreatePanel<>(InstanceManager.getDefault(TurnoutManager.class), null); 201 turnoutSelect7 = new BeanSelectCreatePanel<>(InstanceManager.getDefault(TurnoutManager.class), null); 202 203 getContentPane().setLayout(new BorderLayout()); 204 getContentPane().add(getHeaderPanel(), BorderLayout.PAGE_START); 205 getContentPane().add(new JScrollPane(getCentrePanel()), BorderLayout.CENTER); 206 getContentPane().add(getBottomButtonsPanel(), BorderLayout.PAGE_END); 207 208 typeChanged(); 209 setHeadToFrame(); 210 211 setEscapeKeyClosesWindow(true); 212 pack(); 213 setVisible(true); 214 } 215 216 private JPanel getHeaderPanel(){ 217 218 JPanel panelHeader = new JPanel(); 219 panelHeader.setLayout(new BoxLayout(panelHeader, BoxLayout.Y_AXIS)); 220 221 initTypeBox(); 222 panelHeader.add(new JSeparator()); 223 panelHeader.add(headTypeBox); 224 panelHeader.add(new JSeparator()); 225 JPanel labelPanel = new JPanel(); 226 labelPanel.setLayout(new GridBagLayout()); 227 labelPanel.add(headTypeLabel); 228 229 panelHeader.add(labelPanel); 230 panelHeader.add(new JSeparator()); 231 232 JPanel p = new JPanel(); 233 p.setLayout(new FlowLayout()); 234 p.add(prefixBoxLabel); 235 prefixBoxLabel.setLabelFor(prefixBox); 236 p.add(prefixBox); 237 panelHeader.add(p); 238 239 p = new JPanel(); 240 p.setLayout(new FlowLayout()); 241 p.add(systemNameLabel); 242 systemNameLabel.setLabelFor(systemNameField); 243 p.add(systemNameField); 244 panelHeader.add(p); 245 246 p = new JPanel(); 247 p.setLayout(new FlowLayout()); 248 p.add(userNameLabel); 249 userNameLabel.setLabelFor(userNameField); 250 userNameField.setToolTipText(Bundle.getMessage("SignalHeadUserNameTooltip")); 251 p.add(userNameField); 252 panelHeader.add(p); 253 254 return panelHeader; 255 } 256 257 private JPanel getCentrePanel() { 258 259 JPanel panelCentre = new JPanel(); 260 panelCentre.setLayout(new BoxLayout(panelCentre, BoxLayout.Y_AXIS)); 261 262 dccOptionsPanel = new JPanel(); 263 dccOptionsPanel.add(dccOffSetAddressCheckBox); 264 dccOffSetAddressCheckBox.setToolTipText(Bundle.getMessage("DccOffsetTooltip")); 265 dccOptionsPanel.add(dccPacketSendCount); 266 dccPacketSendCountSpinner.setModel(new SpinnerNumberModel(3, 1, 4, 1)); 267 dccPacketSendCountSpinner.setToolTipText(Bundle.getMessage("DCCMastPacketSendCountToolTip")); 268 dccOptionsPanel.add(dccPacketSendCountSpinner); 269 panelCentre.add(dccOptionsPanel); 270 271 centrePanel1 = new JPanel(); 272 centrePanel1.setLayout(defaultFlow); 273 centrePanel1.add(turnoutSelect1); 274 centrePanel1.add(stateLabel1); 275 centrePanel1.add(turnoutStateBox1); 276 turnoutStateBox1.setToolTipText(Bundle.getMessage("SignalHeadStateTooltip")); 277 centrePanel1.add(numberUkAspectsBox); 278 numberUkAspectsBox.setToolTipText(Bundle.getMessage("SignalHeadMergTooltip")); 279 numberUkAspectsBox.addActionListener(e -> ukAspectChange()); 280 centrePanel1.setBorder(centrePanBorder1); 281 panelCentre.add(centrePanel1); 282 283 centrePanel2 = new JPanel(); 284 centrePanel2.setLayout(defaultFlow); 285 centrePanel2.add(turnoutSelect2); 286 centrePanel2.add(stateLabel2); 287 centrePanel2.add(turnoutStateBox2); 288 turnoutStateBox2.setToolTipText(Bundle.getMessage("SignalHeadStateTooltip")); 289 centrePanel2.add(signalStateBox2); 290 centrePanel2.add(ukSignalSemaphoreTypeBox); 291 ukSignalSemaphoreTypeBox.setToolTipText(Bundle.getMessage("SignalHeadUseTooltip")); 292 centrePanel2.add(dccAppearanceNumberingPanel); 293 centrePanel2.setBorder(centrePanBorder2); 294 panelCentre.add(centrePanel2); 295 panelCentre.add(dccAppearanceCopyPanel); 296 297 centrePanel3 = new JPanel(); 298 centrePanel3.setLayout(defaultFlow); 299 centrePanel3.add(turnoutSelect3); 300 centrePanel3.add(stateLabel3); 301 centrePanel3.add(turnoutStateBox3); 302 turnoutStateBox3.setToolTipText(Bundle.getMessage("SignalHeadStateTooltip")); 303 centrePanel3.add(signalStateBox3); 304 centrePanel3.setBorder(centrePanBorder3); 305 panelCentre.add(centrePanel3); 306 307 centrePanel4 = new JPanel(); 308 centrePanel4.setLayout(defaultFlow); 309 centrePanel4.add(turnoutSelect4); 310 centrePanel4.add(stateLabel4); 311 centrePanel4.add(turnoutStateBox4); 312 turnoutStateBox4.setToolTipText(Bundle.getMessage("SignalHeadStateTooltip")); 313 centrePanel4.setBorder(centrePanBorder4); 314 panelCentre.add(centrePanel4); 315 316 centrePanel5 = new JPanel(); 317 centrePanel5.setLayout(defaultFlow); 318 centrePanel5.add(turnoutSelect5); 319 centrePanel5.add(stateLabel5); 320 centrePanel5.add(turnoutStateBox5); 321 turnoutStateBox5.setToolTipText(Bundle.getMessage("SignalHeadStateTooltip")); 322 centrePanel5.setBorder(centrePanBorder5); 323 panelCentre.add(centrePanel5); 324 325 centrePanel6 = new JPanel(); 326 centrePanel6.setLayout(defaultFlow); 327 centrePanel6.add(turnoutSelect6); 328 centrePanel6.add(stateLabel6); 329 centrePanel6.add(turnoutStateBox6); 330 turnoutStateBox6.setToolTipText(Bundle.getMessage("SignalHeadStateTooltip")); 331 centrePanel6.setBorder(centrePanBorder6); 332 panelCentre.add(centrePanel6); 333 334 centrePanel7 = new JPanel(); 335 centrePanel7.setLayout(defaultFlow); 336 centrePanel7.add(turnoutSelect7); 337 centrePanel7.add(stateLabel7); 338 centrePanel7.add(turnoutStateBox7); 339 turnoutStateBox7.setToolTipText(Bundle.getMessage("SignalHeadStateTooltip")); 340 centrePanel7.setBorder(centrePanBorder7); 341 panelCentre.add(centrePanel7); 342 343 acelaHeadPanel = new JPanel(); 344 acelaHeadPanel.setLayout(defaultFlow); 345 JLabel aspectTypeLabel = new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("LabelAspectType"))); 346 acelaHeadPanel.add(aspectTypeLabel); 347 acelaHeadPanel.add(acelaHeadTypeBox); 348 panelCentre.add(acelaHeadPanel); 349 350 return panelCentre; 351 } 352 353 private JPanel getBottomButtonsPanel(){ 354 JPanel panelBottom = new JPanel(); 355 panelBottom.setLayout(new BoxLayout(panelBottom, BoxLayout.Y_AXIS)); 356 // add buttons 357 JPanel p = new JPanel(); 358 p.setLayout(new FlowLayout(FlowLayout.TRAILING)); 359 360 JButton cancel = new JButton(Bundle.getMessage("ButtonCancel")); 361 p.add(cancel); 362 cancel.addActionListener(e1 -> dispose()); 363 364 JButton update = new JButton(Bundle.getMessage( 365 signalHeadBeingEdited == null ? "ButtonCreate" : "ButtonUpdate" )); 366 update.addActionListener(this::updateEditPressed); 367 getRootPane().setDefaultButton(update); 368 369 p.add(update ); 370 371 panelBottom.add(p); 372 return panelBottom; 373 } 374 375 public void hideAllPanels() { 376 377 prefixBoxLabel.setVisible(false); 378 prefixBox.setVisible(false); 379 380 systemNameField.setVisible(false); 381 systemNameLabel.setVisible(false); 382 383 userNameLabel.setVisible(false); 384 userNameField.setVisible(false); 385 386 dccOptionsPanel.setVisible(false); 387 centrePanel1.setVisible(false); 388 turnoutSelect1.setVisible(false); 389 stateLabel1.setVisible(false); 390 turnoutStateBox1.setVisible(false); 391 numberUkAspectsBox.setVisible(false); 392 393 centrePanel2.setVisible(false); 394 turnoutSelect2.setVisible(false); 395 stateLabel2.setVisible(false); 396 turnoutStateBox2.setVisible(false); 397 signalStateBox2.setVisible(false); 398 ukSignalSemaphoreTypeBox.setVisible(false); 399 dccAppearanceNumberingPanel.setVisible(false); 400 dccAppearanceCopyPanel.setVisible(false); 401 402 centrePanel3.setVisible(false); 403 turnoutSelect3.setVisible(false); 404 stateLabel3.setVisible(false); 405 turnoutStateBox3.setVisible(false); 406 signalStateBox3.setVisible(false); 407 408 centrePanel4.setVisible(false); 409 turnoutSelect4.setVisible(false); 410 stateLabel4.setVisible(false); 411 turnoutStateBox4.setVisible(false); 412 413 centrePanel5.setVisible(false); 414 turnoutSelect5.setVisible(false); 415 stateLabel5.setVisible(false); 416 turnoutStateBox5.setVisible(false); 417 418 centrePanel6.setVisible(false); 419 turnoutSelect6.setVisible(false); 420 stateLabel6.setVisible(false); 421 turnoutStateBox6.setVisible(false); 422 423 centrePanel7.setVisible(false); 424 turnoutSelect7.setVisible(false); 425 stateLabel7.setVisible(false); 426 turnoutStateBox7.setVisible(false); 427 428 acelaHeadPanel.setVisible(false); 429 } 430 431 private void setHeadToFrame() { 432 headTypeLabel.setVisible(signalHeadBeingEdited != null); 433 headTypeBox.setVisible(signalHeadBeingEdited == null); 434 if ( signalHeadBeingEdited == null ){ 435 headTypeBox.setSelectedItem(DOUBLE_TURNOUT); // force GUI status consistent. Default set to Double Head type 436 typeChanged(); 437 systemNameField.setToolTipText(Bundle.getMessage("SignalHeadSysNameTooltip")); 438 return; 439 } 440 headTypeBox.setSelectedItem(getNameFromClass(signalHeadBeingEdited.getClass().getName())); 441 headTypeLabel.setText("<html><h3>"+ getNameFromClass(signalHeadBeingEdited.getClass().getName())+"</h3></html>"); 442 443 typeChanged(); 444 systemNameField.setEditable(false); 445 systemNameField.setText(signalHeadBeingEdited.getSystemName()); 446 userNameField.setText(signalHeadBeingEdited.getUserName()); 447 448 String type = (String)headTypeBox.getSelectedItem(); 449 if ( QUAD_OUTPUT.equals(type)) { 450 var greenTt = ((QuadOutputSignalHead) signalHeadBeingEdited).getGreen(); 451 var yellowTt =((QuadOutputSignalHead) signalHeadBeingEdited).getYellow(); 452 var redTt = ((QuadOutputSignalHead) signalHeadBeingEdited).getRed(); 453 var lunarTt = ((QuadOutputSignalHead) signalHeadBeingEdited).getLunar(); 454 if (greenTt !=null) turnoutSelect1.setDefaultNamedBean(greenTt.getBean()); 455 if (yellowTt!=null) turnoutSelect2.setDefaultNamedBean(yellowTt.getBean()); 456 if (redTt !=null) turnoutSelect3.setDefaultNamedBean(redTt.getBean()); 457 if (lunarTt !=null) turnoutSelect4.setDefaultNamedBean(lunarTt.getBean()); 458 } else if (TRIPLE_TURNOUT.equals(type)) { 459 var greenTt = ((TripleTurnoutSignalHead) signalHeadBeingEdited).getGreen(); 460 var yellowTt =((TripleTurnoutSignalHead) signalHeadBeingEdited).getYellow(); 461 var redTt = ((TripleTurnoutSignalHead) signalHeadBeingEdited).getRed(); 462 if (greenTt !=null) turnoutSelect1.setDefaultNamedBean(greenTt.getBean()); 463 if (yellowTt!=null) turnoutSelect2.setDefaultNamedBean(yellowTt.getBean()); 464 if (redTt !=null) turnoutSelect3.setDefaultNamedBean(redTt.getBean()); 465 } else if ( TRIPLE_OUTPUT.equals(type)) { 466 var greenTt = ((TripleOutputSignalHead) signalHeadBeingEdited).getGreen(); 467 var blueTt =((TripleOutputSignalHead) signalHeadBeingEdited).getBlue(); 468 var redTt = ((TripleOutputSignalHead) signalHeadBeingEdited).getRed(); 469 if (greenTt !=null) turnoutSelect1.setDefaultNamedBean(greenTt.getBean()); 470 if (blueTt!=null) turnoutSelect2.setDefaultNamedBean(blueTt.getBean()); 471 if (redTt !=null) turnoutSelect3.setDefaultNamedBean(redTt.getBean()); 472 } else if ( DOUBLE_TURNOUT.equals(type)) { 473 var greenTt = ((DoubleTurnoutSignalHead) signalHeadBeingEdited).getGreen(); 474 var redTt = ((DoubleTurnoutSignalHead) signalHeadBeingEdited).getRed(); 475 if (greenTt !=null) turnoutSelect1.setDefaultNamedBean(greenTt.getBean()); 476 if (redTt !=null) turnoutSelect2.setDefaultNamedBean(redTt.getBean()); 477 } else if ( SINGLE_TURNOUT.equals(type)) { 478 var tTt = ((SingleTurnoutSignalHead) signalHeadBeingEdited).getOutput(); 479 if (tTt !=null) turnoutSelect1.setDefaultNamedBean(tTt.getBean()); 480 setSignalStateInBox(signalStateBox2, ((SingleTurnoutSignalHead) signalHeadBeingEdited).getOnAppearance()); 481 setSignalStateInBox(signalStateBox3, ((SingleTurnoutSignalHead) signalHeadBeingEdited).getOffAppearance()); 482 } else if (LSDEC.equals(type)) { // LDT LS-DEC 483 var greenT = ((LsDecSignalHead) signalHeadBeingEdited).getGreen(); 484 var yellowT = ((LsDecSignalHead) signalHeadBeingEdited).getYellow(); 485 var redT = ((LsDecSignalHead) signalHeadBeingEdited).getRed(); 486 var greenTFlash = ((LsDecSignalHead) signalHeadBeingEdited).getFlashGreen(); 487 var yellowTFlash = ((LsDecSignalHead) signalHeadBeingEdited).getFlashYellow(); 488 var redTFlash = ((LsDecSignalHead) signalHeadBeingEdited).getFlashRed(); 489 var darkT = ((LsDecSignalHead) signalHeadBeingEdited).getDark(); 490 if (greenT!=null) turnoutSelect1.setDefaultNamedBean(greenT.getBean()); 491 setTurnoutStateInBox(turnoutStateBox1, ((LsDecSignalHead) signalHeadBeingEdited).getGreenState(), TURNOUT_STATE_VALUES); 492 if (yellowT!=null) turnoutSelect2.setDefaultNamedBean(yellowT.getBean()); 493 setTurnoutStateInBox(turnoutStateBox2, ((LsDecSignalHead) signalHeadBeingEdited).getYellowState(), TURNOUT_STATE_VALUES); 494 if (redT!=null) turnoutSelect3.setDefaultNamedBean(redT.getBean()); 495 setTurnoutStateInBox(turnoutStateBox3, ((LsDecSignalHead) signalHeadBeingEdited).getRedState(), TURNOUT_STATE_VALUES); 496 if (greenTFlash!=null) turnoutSelect4.setDefaultNamedBean(greenTFlash.getBean()); 497 setTurnoutStateInBox(turnoutStateBox4, ((LsDecSignalHead) signalHeadBeingEdited).getFlashGreenState(), TURNOUT_STATE_VALUES); 498 if (yellowTFlash!=null) turnoutSelect5.setDefaultNamedBean(yellowTFlash.getBean()); 499 setTurnoutStateInBox(turnoutStateBox5, ((LsDecSignalHead) signalHeadBeingEdited).getFlashYellowState(), TURNOUT_STATE_VALUES); 500 if (redTFlash!=null) turnoutSelect6.setDefaultNamedBean(redTFlash.getBean()); 501 setTurnoutStateInBox(turnoutStateBox6, ((LsDecSignalHead) signalHeadBeingEdited).getFlashRedState(), TURNOUT_STATE_VALUES); 502 if (darkT!=null) turnoutSelect7.setDefaultNamedBean(darkT.getBean()); 503 setTurnoutStateInBox(turnoutStateBox7, ((LsDecSignalHead) signalHeadBeingEdited).getDarkState(), TURNOUT_STATE_VALUES); 504 } else if (ACELA_ASPECT.equals(type)) { 505 AcelaNode tNode = AcelaAddress.getNodeFromSystemName(signalHeadBeingEdited.getSystemName(), InstanceManager.getDefault(AcelaSystemConnectionMemo.class)); 506 if (tNode == null) { 507 // node does not exist, ignore call 508 log.error("Can't find new Acela Signal with name '{}", signalHeadBeingEdited.getSystemName()); 509 return; 510 } 511 int headnumber = Integer.parseInt(signalHeadBeingEdited.getSystemName().substring(2)); 512 setSignalheadTypeInBox(acelaHeadTypeBox, tNode.getOutputSignalHeadType(headnumber), ACELA_SIG_HEAD_TYPE_VALUES); 513 } else if (DCC_SIGNAL_DECODER.equals(type)) { 514 for (int i = 0; i < DccSignalHead.getDefaultValidStates().length; i++) { 515 dccAspectSpinners[i].setValue(((DccSignalHead) signalHeadBeingEdited).getOutputForAppearance(signalHeadBeingEdited.getValidStates()[i])); 516 } 517 dccOffSetAddressCheckBox.setSelected(((DccSignalHead) signalHeadBeingEdited).useAddressOffSet()); 518 dccPacketSendCountSpinner.setValue(((DccSignalHead) signalHeadBeingEdited).getDccSignalHeadPacketSendCount()); 519 520 for (CommandStation cs : InstanceManager.getList(CommandStation.class)) { 521 if ( signalHeadBeingEdited.getSystemName().startsWith(cs.getSystemPrefix())) { 522 prefixBox.setSelectedItem(cs.getUserName()); 523 } 524 } 525 } else if (MERG_SIGNAL_DRIVER.equals(type)) { 526 setUkSignalAspectsFromBox(numberUkAspectsBox, ((MergSD2SignalHead) signalHeadBeingEdited).getAspects()); 527 528 if (((MergSD2SignalHead) signalHeadBeingEdited).getHome()) { 529 setUkSignalType(ukSignalSemaphoreTypeBox, Bundle.getMessage("HomeSignal")); // "Home" 530 } else { 531 setUkSignalType(ukSignalSemaphoreTypeBox, Bundle.getMessage("DistantSignal")); //"Distant" 532 } 533 534 var input1 = ((MergSD2SignalHead) signalHeadBeingEdited).getInput1(); 535 var input2 = ((MergSD2SignalHead) signalHeadBeingEdited).getInput2(); 536 var input3 = ((MergSD2SignalHead) signalHeadBeingEdited).getInput3(); 537 if (input1!=null) turnoutSelect3.setDefaultNamedBean(input1.getBean()); 538 if (input2!=null) turnoutSelect4.setDefaultNamedBean(input2.getBean()); 539 if (input3!=null) turnoutSelect5.setDefaultNamedBean(input3.getBean()); 540 541 } 542 543 } 544 545 private String getNameFromClass(@Nonnull String className){ 546 switch (className) { 547 case "jmri.implementation.QuadOutputSignalHead": 548 return QUAD_OUTPUT; 549 case "jmri.implementation.TripleTurnoutSignalHead": 550 return TRIPLE_TURNOUT; 551 case "jmri.implementation.TripleOutputSignalHead": 552 return TRIPLE_OUTPUT; 553 case "jmri.implementation.DoubleTurnoutSignalHead": 554 return DOUBLE_TURNOUT; 555 case "jmri.implementation.SingleTurnoutSignalHead": 556 return SINGLE_TURNOUT; 557 case "jmri.implementation.VirtualSignalHead": 558 return VIRTUAL_HEAD; 559 case "jmri.implementation.LsDecSignalHead": // LDT LS-DEC 560 return LSDEC; 561 case "jmri.implementation.SE8cSignalHead": 562 return SE8C4_ASPECT; 563 case "jmri.jmrix.grapevine.SerialSignalHead": 564 return GRAPEVINE; 565 case "jmri.jmrix.acela.AcelaSignalHead": 566 return ACELA_ASPECT; 567 case "jmri.implementation.DccSignalHead": 568 return DCC_SIGNAL_DECODER; 569 case "jmri.implementation.MergSD2SignalHead": 570 return MERG_SIGNAL_DRIVER; 571 default: 572 throw new IllegalArgumentException("No implementation for " + className); 573 } 574 } 575 576 private void typeChanged() { 577 hideAllPanels(); 578 579 if ( signalHeadBeingEdited == null ){ 580 systemNameField.setToolTipText(Bundle.getMessage("SignalHeadSysNameTooltip")); 581 } else { 582 systemNameField.setToolTipText(null); 583 } 584 585 systemNameLabel.setText(Bundle.getMessage("LabelSystemName")); 586 systemNameLabel.setVisible(true); 587 systemNameField.setVisible(true); 588 userNameLabel.setText(Bundle.getMessage("LabelUserName")); 589 userNameLabel.setVisible(true); 590 userNameField.setVisible(true); 591 592 String type = (String)headTypeBox.getSelectedItem(); 593 if ( QUAD_OUTPUT.equals(type)) { 594 centrePanBorder1.setTitle(Bundle.getMessage("LabelGreenTurnoutNumber")); 595 centrePanel1.setVisible(true); 596 turnoutSelect1.setVisible(true); 597 centrePanBorder2.setTitle(Bundle.getMessage("LabelYellowTurnoutNumber")); 598 centrePanel2.setVisible(true); 599 turnoutSelect2.setVisible(true); 600 centrePanBorder3.setTitle(Bundle.getMessage("LabelRedTurnoutNumber")); 601 centrePanel3.setVisible(true); 602 turnoutSelect3.setVisible(true); 603 centrePanBorder4.setTitle(Bundle.getMessage("LabelLunarTurnoutNumber")); 604 centrePanel4.setVisible(true); 605 turnoutSelect4.setVisible(true); 606 } else if (TRIPLE_TURNOUT.equals(type)) { 607 centrePanBorder1.setTitle(Bundle.getMessage("LabelGreenTurnoutNumber")); 608 centrePanel1.setVisible(true); 609 turnoutSelect1.setVisible(true); 610 centrePanBorder2.setTitle(Bundle.getMessage("LabelYellowTurnoutNumber")); 611 centrePanel2.setVisible(true); 612 turnoutSelect2.setVisible(true); 613 centrePanBorder3.setTitle(Bundle.getMessage("LabelRedTurnoutNumber")); 614 centrePanel3.setVisible(true); 615 turnoutSelect3.setVisible(true); 616 } else if ( TRIPLE_OUTPUT.equals(type)) { 617 centrePanBorder1.setTitle(Bundle.getMessage("LabelGreenTurnoutNumber")); 618 centrePanel1.setVisible(true); 619 turnoutSelect1.setVisible(true); 620 centrePanBorder2.setTitle(Bundle.getMessage("LabelBlueTurnoutNumber")); 621 centrePanel2.setVisible(true); 622 turnoutSelect2.setVisible(true); 623 centrePanBorder3.setTitle(Bundle.getMessage("LabelRedTurnoutNumber")); 624 centrePanel3.setVisible(true); 625 turnoutSelect3.setVisible(true); 626 } else if ( DOUBLE_TURNOUT.equals(type)) { 627 centrePanBorder1.setTitle(Bundle.getMessage("LabelGreenTurnoutNumber")); 628 centrePanel1.setVisible(true); 629 turnoutSelect1.setVisible(true); 630 centrePanBorder2.setTitle(Bundle.getMessage("LabelRedTurnoutNumber")); 631 centrePanel2.setVisible(true); 632 turnoutSelect2.setVisible(true); 633 } else if ( SINGLE_TURNOUT.equals(type)) { 634 centrePanBorder1.setTitle(Bundle.getMessage("LabelTurnoutNumber")); 635 centrePanel1.setVisible(true); 636 turnoutSelect1.setVisible(true); 637 centrePanBorder2.setTitle(Bundle.getMessage("LabelTurnoutThrownAppearance")); 638 centrePanel2.setVisible(true); 639 signalStateBox2.setVisible(true); 640 centrePanBorder3.setTitle(Bundle.getMessage("LabelTurnoutClosedAppearance")); 641 centrePanel3.setVisible(true); 642 signalStateBox3.setVisible(true); 643 } else if (LSDEC.equals(type)) { // LDT LS-DEC 644 centrePanBorder1.setTitle(Bundle.getMessage("LabelGreenTurnoutNumber")); 645 centrePanel1.setVisible(true); 646 turnoutSelect1.setVisible(true); 647 stateLabel1.setVisible(true); 648 turnoutStateBox1.setVisible(true); 649 650 centrePanBorder2.setTitle(Bundle.getMessage("LabelYellowTurnoutNumber")); 651 centrePanel2.setVisible(true); 652 turnoutSelect2.setVisible(true); 653 stateLabel2.setVisible(true); 654 turnoutStateBox2.setVisible(true); 655 656 centrePanBorder3.setTitle(Bundle.getMessage("LabelRedTurnoutNumber")); 657 centrePanel3.setVisible(true); 658 turnoutSelect3.setVisible(true); 659 stateLabel3.setVisible(true); 660 turnoutStateBox3.setVisible(true); 661 662 centrePanBorder4.setTitle(Bundle.getMessage("LabelFlashGreenTurnoutNumber")); 663 centrePanel4.setVisible(true); 664 turnoutSelect4.setVisible(true); 665 stateLabel4.setVisible(true); 666 turnoutStateBox4.setVisible(true); 667 668 centrePanBorder5.setTitle(Bundle.getMessage("LabelFlashYellowTurnoutNumber")); 669 centrePanel5.setVisible(true); 670 turnoutSelect5.setVisible(true); 671 stateLabel5.setVisible(true); 672 turnoutStateBox5.setVisible(true); 673 674 centrePanBorder6.setTitle(Bundle.getMessage("LabelFlashRedTurnoutNumber")); 675 centrePanel6.setVisible(true); 676 turnoutSelect6.setVisible(true); 677 stateLabel6.setVisible(true); 678 turnoutStateBox6.setVisible(true); 679 680 centrePanBorder7.setTitle(Bundle.getMessage("LabelDarkTurnoutNumber")); 681 centrePanel7.setVisible(true); 682 turnoutSelect7.setVisible(true); 683 stateLabel7.setVisible(true); 684 turnoutStateBox7.setVisible(true); 685 } else if (ACELA_ASPECT.equals(type)) { 686 acelaHeadPanel.setVisible(true); 687 if ( signalHeadBeingEdited == null ) { 688 systemNameLabel.setText(Bundle.getMessage("LabelSignalheadNumber")); // displays ID instead of -number 689 } 690 systemNameField.setToolTipText(Bundle.getMessage("SignalHeadAcelaTooltip")); 691 } else if (DCC_SIGNAL_DECODER.equals(type)) { 692 if ( signalHeadBeingEdited == null ) { 693 systemNameLabel.setText(Bundle.getMessage("LabelSignalheadNumber")); // displays ID instead of -number 694 } 695 dccOptionsPanel.setVisible(true); 696 prefixBox.setVisible(true); 697 prefixBox.setEnabled(signalHeadBeingEdited==null); 698 prefixBoxLabel.setVisible(true); 699 centrePanBorder2.setTitle(Bundle.getMessage("LabelAspectNumbering")); 700 centrePanel2.setVisible(true); 701 dccAppearanceNumberingPanel.setVisible(true); 702 dccAppearanceCopyPanel.setVisible(true); 703 } else if (MERG_SIGNAL_DRIVER.equals(type)) { 704 centrePanBorder1.setTitle(Bundle.getMessage("NumberOfAppearances")); // same as line 1054 705 centrePanel1.setVisible(true); 706 numberUkAspectsBox.setVisible(true); 707 708 centrePanBorder2.setTitle(Bundle.getMessage("UseAs")); // same as line 1090 709 centrePanel2.setVisible(true); 710 turnoutSelect2.setVisible(false); 711 ukSignalSemaphoreTypeBox.setVisible(true); 712 713 centrePanBorder3.setTitle(Bundle.getMessage("InputNum", " 1 ")); 714 centrePanel3.setVisible(true); 715 turnoutSelect3.setVisible(true); 716 centrePanBorder4.setTitle(Bundle.getMessage("InputNum", " 2 ")); 717 centrePanel4.setVisible(true); 718 turnoutSelect4.setVisible(true); 719 720 centrePanBorder5.setTitle(Bundle.getMessage("InputNum", " 3 ")); 721 centrePanel5.setVisible(true); 722 turnoutSelect5.setVisible(true); 723 724 setUkSignalAspectsFromBox(numberUkAspectsBox, 2); 725 ukAspectChange(); 726 } else if ( SE8C4_ASPECT.equals(type)) { 727 systemNameField.setVisible(signalHeadBeingEdited != null); 728 systemNameLabel.setVisible(signalHeadBeingEdited != null); 729 730 centrePanBorder1.setTitle(Bundle.getMessage("LabelTurnoutNumber")); 731 centrePanel1.setVisible(true); 732 turnoutSelect1.setVisible(true); 733 734 centrePanBorder2.setTitle(Bundle.getMessage("LabelSecondNumber")); 735 centrePanel2.setVisible(true); 736 turnoutSelect2.setVisible(true); 737 } 738 else if ( GRAPEVINE.equals(type)) {} 739 else if ( VIRTUAL_HEAD.equals(type)) {} 740 else { 741 log.error("Cannot edit SignalHead of unrecognized type: {}", type); 742 } 743 pack(); 744 } 745 746 private void initTypeBox() { 747 headTypeBox = new JComboBox<>(new String[]{ACELA_ASPECT, DCC_SIGNAL_DECODER, DOUBLE_TURNOUT, LSDEC, MERG_SIGNAL_DRIVER, QUAD_OUTPUT, SINGLE_TURNOUT, SE8C4_ASPECT, TRIPLE_TURNOUT, TRIPLE_OUTPUT, VIRTUAL_HEAD}); 748 // If no DCC Command station is found, remove the DCC Signal Decoder option. 749 if (prefixBox.getItemCount() == 0) { 750 headTypeBox.removeItem(DCC_SIGNAL_DECODER); 751 } 752 if (!InstanceManager.getList(GrapevineSystemConnectionMemo.class).isEmpty()) { 753 headTypeBox.addItem(GRAPEVINE); 754 } 755 if (InstanceManager.getList(AcelaSystemConnectionMemo.class).isEmpty()) { 756 headTypeBox.removeItem(ACELA_ASPECT); 757 } 758 headTypeBox.addActionListener(e1 -> typeChanged()); 759 JComboBoxUtil.setupComboBoxMaxRows(headTypeBox); 760 headTypeBox.setEnabled(signalHeadBeingEdited==null); 761 } 762 763 private void initDccAppearancePanel() { 764 dccAppearanceNumberingPanel = new JPanel(); 765 dccAppearanceNumberingPanel.setLayout(new GridLayout(0, 2)); 766 dccAspectSpinners = new JSpinner[DccSignalHead.getDefaultValidStates().length]; 767 for (int i = 0; i < DccSignalHead.getDefaultValidStates().length; i++) { 768 String aspect = DccSignalHead.getDefaultValidStateNames()[i]; 769 dccAppearanceNumberingPanel.add(new JLabel(aspect)); 770 771 SpinnerNumberModel DccSpinnerModel = new SpinnerNumberModel(1, 0, 31, 1); 772 JSpinner tmp = new JSpinner(DccSpinnerModel); 773 tmp.setValue(DccSignalHead.getDefaultNumberForAppearance(DccSignalHead.getDefaultValidStates()[i])); 774 dccAspectSpinners[i] = tmp; // store the whole JSpinner 775 dccAppearanceNumberingPanel.add(tmp); // and display that copy on the JPanel 776 tmp.setToolTipText(Bundle.getMessage("DccAccessoryAspect", i)); 777 } 778 779 // Use appearance numbers from signal head option 780 var copyPanel = new JPanel(); 781 copyPanel.add(new JLabel(Bundle.getMessage("LabelCopyAppearanceNumbers"))); 782 copyPanel.add(copyFromHeadSelection()); 783 dccAppearanceCopyPanel.add(copyPanel); 784 } 785 786 /** 787 * Create a combobox of DCC signal heads that can be used to supply a set of appearance numbers. 788 * This makes it easy to override the default appearance numbers. 789 * @return a combobox with the current DCC signal head display names. 790 */ 791 @Nonnull JComboBox<String> copyFromHeadSelection() { 792 List<String> headList = new ArrayList<>(); 793 for (SignalHead head : InstanceManager.getDefault(SignalHeadManager.class).getNamedBeanSet()) { 794 if (head instanceof DccSignalHead){ 795 headList.add(head.getDisplayName()); 796 } 797 } 798 799 headList.sort(null); 800 JComboBox<String> headSelect = new JComboBox<String>(new Vector<String>(headList)); 801 802 if (headList.size() == 0) { 803 headSelect.setEnabled(false); 804 } else { 805 headSelect.insertItemAt("", 0); 806 headSelect.setSelectedIndex(0); 807 headSelect.addActionListener((ActionEvent e) -> { 808 @SuppressWarnings("unchecked") // e.getSource() cast from mastSelect source 809 JComboBox<String> eb = (JComboBox<String>) e.getSource(); 810 String sourceHead = (String) eb.getSelectedItem(); 811 if (sourceHead != null && !sourceHead.isEmpty()) { 812 copyFromAnotherDCCHeadAppearances(sourceHead); 813 } 814 }); 815 } 816 return headSelect; 817 } 818 819 /** 820 * Change the appearance number spinners to the appearance numbers from a different signal head. 821 * @param headName User or system name of head to copy from 822 */ 823 void copyFromAnotherDCCHeadAppearances(@Nonnull String headName) { 824 DccSignalHead head = (DccSignalHead) InstanceManager.getDefault(SignalHeadManager.class).getNamedBean(headName); 825 if (head == null) { 826 log.error("can't copy appearance numbers from another signal head because {} doesn't exist", headName); 827 return; 828 } 829 830 var keys = head.getValidStateKeys(); 831 for (int i = 0; i < keys.length; i++) { 832 dccAspectSpinners[i].setValue(head.getOutputForAppearance(head.getValidStates()[i])); 833 } 834 } 835 836 private void setSignalStateInBox(JComboBox<String> box, int state) { 837 switch (state) { 838 case SignalHead.DARK: 839 box.setSelectedIndex(0); 840 break; 841 case SignalHead.RED: 842 box.setSelectedIndex(1); 843 break; 844 case SignalHead.LUNAR: 845 box.setSelectedIndex(2); 846 break; 847 case SignalHead.YELLOW: 848 box.setSelectedIndex(3); 849 break; 850 case SignalHead.GREEN: 851 box.setSelectedIndex(4); 852 break; 853 case SignalHead.FLASHRED: 854 box.setSelectedIndex(5); 855 break; 856 case SignalHead.FLASHLUNAR: 857 box.setSelectedIndex(6); 858 break; 859 case SignalHead.FLASHYELLOW: 860 box.setSelectedIndex(7); 861 break; 862 case SignalHead.FLASHGREEN: 863 box.setSelectedIndex(8); 864 break; 865 default: 866 log.error("unexpected Signal state value: {}", state); 867 } 868 } 869 870 private void setTurnoutStateInBox(JComboBox<String> box, int state, int[] iTurnoutStates) { 871 if (state == iTurnoutStates[0]) { 872 box.setSelectedIndex(0); 873 } else if (state == iTurnoutStates[1]) { 874 box.setSelectedIndex(1); 875 } else { 876 log.error("unexpected turnout state value: {}", state); 877 } 878 } 879 880 private int turnoutStateFromBox(JComboBox<String> box) { 881 String mode = (String) box.getSelectedItem(); 882 int result = StringUtil.getStateFromName(mode, TURNOUT_STATE_VALUES, TURNOUT_STATE_STRINGS); 883 if (result < 0) { 884 log.warn("unexpected mode string in turnoutMode: {}", mode); 885 throw new IllegalArgumentException(); 886 } 887 return result; 888 } 889 890 private void setSignalheadTypeInBox(JComboBox<String> box, int state, int[] iSignalheadTypes) { 891 if (state == iSignalheadTypes[0]) { 892 box.setSelectedIndex(0); 893 } else if (state == iSignalheadTypes[1]) { 894 box.setSelectedIndex(1); 895 } else if (state == iSignalheadTypes[2]) { 896 box.setSelectedIndex(2); 897 } else if (state == iSignalheadTypes[3]) { 898 box.setSelectedIndex(3); 899 } else { 900 log.error("unexpected signalhead type value: {}", state); 901 } 902 } 903 904 private int signalStateFromBox(JComboBox<String> box) { 905 String mode = (String) box.getSelectedItem(); 906 int result = StringUtil.getStateFromName(mode, SIGNAL_STATE_VALUES, SIGNAL_STATE_STRINGS); 907 908 if (result < 0) { 909 log.warn("unexpected mode string in signalMode: {}", mode); 910 throw new IllegalArgumentException(); 911 } 912 return result; 913 } 914 915 private int ukSignalAspectsFromBox(JComboBox<String> box) { 916 //String mode = (String)box.getSelectedItem(); 917 switch (box.getSelectedIndex()) { 918 case 0: 919 return 2; 920 case 1: 921 return 3; 922 case 2: 923 return 4; 924 default: 925 log.warn("unexpected appearance{}", box.getSelectedItem()); 926 throw new IllegalArgumentException(); 927 } 928 } 929 930 private void setUkSignalAspectsFromBox(JComboBox<String> box, int val) { 931 switch (val) { 932 case 2: 933 box.setSelectedIndex(0); 934 break; 935 case 3: 936 box.setSelectedIndex(1); 937 break; 938 case 4: 939 box.setSelectedIndex(2); 940 break; 941 default: 942 log.error("Unexpected Signal Appearance{}", val); 943 break; 944 } 945 } 946 947 private String ukSignalTypeFromBox(JComboBox<String> box) { 948 //String mode = (String)box.getSelectedItem(); 949 switch (box.getSelectedIndex()) { 950 case 0: 951 return "Home"; // NOI18N 952 case 1: 953 return "Distant"; // NOI18N 954 default: 955 log.warn("unexpected appearance{}", box.getSelectedItem()); 956 throw new IllegalArgumentException(); 957 } 958 } 959 960 private void setUkSignalType(JComboBox<String> box, String val) { 961 if (val.equals(UK_SEMAPHORE_TYPES[0])) { 962 box.setSelectedIndex(0); 963 } else if (val.equals(UK_SEMAPHORE_TYPES[1])) { 964 box.setSelectedIndex(1); 965 } else { 966 log.error("Unexpected Signal Type {}", val); 967 } 968 } 969 970 private void ukAspectChange() { 971 switch (ukSignalAspectsFromBox(numberUkAspectsBox)) { 972 case 2: 973 centrePanel2.setVisible(true); 974 centrePanel4.setVisible(false); 975 turnoutSelect4.setVisible(false); 976 centrePanel5.setVisible(false); 977 turnoutSelect5.setVisible(false); 978 ukSignalSemaphoreTypeBox.setVisible(true); 979 break; 980 case 3: 981 centrePanel2.setVisible(false); 982 centrePanel4.setVisible(true); 983 turnoutSelect4.setVisible(true); 984 centrePanel5.setVisible(false); 985 turnoutSelect5.setVisible(false); 986 ukSignalSemaphoreTypeBox.setVisible(false); 987 setUkSignalType(ukSignalSemaphoreTypeBox, Bundle.getMessage("HomeSignal")); 988 break; 989 case 4: 990 centrePanel2.setVisible(false); 991 centrePanel4.setVisible(true); 992 turnoutSelect4.setVisible(true); 993 centrePanel5.setVisible(true); 994 turnoutSelect5.setVisible(true); 995 ukSignalSemaphoreTypeBox.setVisible(false); 996 setUkSignalType(ukSignalSemaphoreTypeBox, Bundle.getMessage("HomeSignal")); 997 break; 998 default: 999 break; 1000 } 1001 pack(); 1002 } 1003 1004 @SuppressWarnings("fallthrough") 1005 @SuppressFBWarnings(value = "SF_SWITCH_FALLTHROUGH") 1006 private void updateEditPressed(ActionEvent e) { 1007 log.debug("newedit {}", e); 1008 if ( signalHeadBeingEdited==null ){ 1009 createNewSigHead(); 1010 return; 1011 } 1012 String nam = userNameField.getText(); 1013 // check if user name changed 1014 String uname = signalHeadBeingEdited.getUserName(); 1015 // TODO: not sure this if statement is right. I think (uname != null && !uname.equals(nam)) 1016 if (!((uname != null) && (uname.equals(nam)))) { 1017 if (checkUserName(nam)) { 1018 signalHeadBeingEdited.setUserName(nam); 1019 } else { 1020 return; 1021 } 1022 } 1023 // update according to class of signal head 1024 String className = signalHeadBeingEdited.getClass().getName(); 1025 switch (className) { 1026 case "jmri.implementation.QuadOutputSignalHead": { 1027 var headType = ((QuadOutputSignalHead) signalHeadBeingEdited).getGreen(); 1028 Turnout t1 = updateTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green", 1029 (headType==null ? null : headType.getBean()), centrePanBorder1.getTitle()); 1030 1031 if (t1 == null) { 1032 return; 1033 } else { 1034 ((QuadOutputSignalHead) signalHeadBeingEdited).setGreen(nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1)); 1035 } 1036 1037 headType = ((QuadOutputSignalHead) signalHeadBeingEdited).getYellow(); 1038 Turnout t2 = updateTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Yellow", 1039 (headType==null ? null : headType.getBean()), centrePanBorder2.getTitle()); 1040 if (t2 == null) { 1041 return; 1042 } else { 1043 ((QuadOutputSignalHead) signalHeadBeingEdited).setYellow(nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2)); 1044 } 1045 1046 headType = ((QuadOutputSignalHead) signalHeadBeingEdited).getRed(); 1047 Turnout t3 = updateTurnoutFromPanel(turnoutSelect3, "SignalHead:" + systemNameField.getText() + ":Red", 1048 (headType==null ? null : headType.getBean()), centrePanBorder3.getTitle()); 1049 if (t3 == null) { 1050 return; 1051 } else { 1052 ((QuadOutputSignalHead) signalHeadBeingEdited).setRed(nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t3)); 1053 } 1054 1055 headType = ((QuadOutputSignalHead) signalHeadBeingEdited).getLunar(); 1056 Turnout t4 = updateTurnoutFromPanel(turnoutSelect4, "SignalHead:" + systemNameField.getText() + ":Lunar", 1057 (headType==null ? null : headType.getBean()), centrePanBorder4.getTitle()); 1058 if (t4 == null) { 1059 return; 1060 } else { 1061 ((QuadOutputSignalHead) signalHeadBeingEdited).setLunar(nbhm.getNamedBeanHandle(turnoutSelect4.getDisplayName(), t4)); 1062 } 1063 break; 1064 } 1065 case "jmri.implementation.TripleTurnoutSignalHead": { 1066 1067 var headType = ((TripleTurnoutSignalHead) signalHeadBeingEdited).getGreen(); 1068 Turnout t1 = updateTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green", 1069 (headType==null ? null : headType.getBean()), centrePanBorder1.getTitle()); 1070 if (t1 == null) { 1071 return; 1072 } else { 1073 ((TripleTurnoutSignalHead) signalHeadBeingEdited).setGreen(nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1)); 1074 } 1075 1076 headType = ((TripleTurnoutSignalHead) signalHeadBeingEdited).getYellow(); 1077 Turnout t2 = updateTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Yellow", 1078 (headType==null ? null : headType.getBean()), centrePanBorder2.getTitle()); 1079 if (t2 == null) { 1080 return; 1081 } else { 1082 ((TripleTurnoutSignalHead) signalHeadBeingEdited).setYellow(nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2)); 1083 } 1084 1085 headType = ((TripleTurnoutSignalHead) signalHeadBeingEdited).getRed(); 1086 Turnout t3 = updateTurnoutFromPanel(turnoutSelect3, "SignalHead:" + systemNameField.getText() + ":Red", 1087 (headType==null ? null : headType.getBean()), centrePanBorder3.getTitle()); 1088 if (t3 == null) { 1089 return; 1090 } else { 1091 ((TripleTurnoutSignalHead) signalHeadBeingEdited).setRed(nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t3)); 1092 } 1093 break; 1094 } 1095 case "jmri.implementation.TripleOutputSignalHead": { 1096 1097 var headType = ((TripleOutputSignalHead) signalHeadBeingEdited).getGreen(); 1098 Turnout t1 = updateTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green", 1099 (headType==null ? null : headType.getBean()), centrePanBorder1.getTitle()); 1100 if (t1 == null) { 1101 return; 1102 } else { 1103 ((TripleOutputSignalHead) signalHeadBeingEdited).setGreen(nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1)); 1104 } 1105 1106 headType = ((TripleOutputSignalHead) signalHeadBeingEdited).getBlue(); 1107 Turnout t2 = updateTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Blue", 1108 (headType==null ? null : headType.getBean()), centrePanBorder2.getTitle()); 1109 if (t2 == null) { 1110 return; 1111 } else { 1112 ((TripleOutputSignalHead) signalHeadBeingEdited).setBlue(nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2)); 1113 } 1114 1115 headType = ((TripleOutputSignalHead) signalHeadBeingEdited).getRed(); 1116 Turnout t3 = updateTurnoutFromPanel(turnoutSelect3, "SignalHead:" + systemNameField.getText() + ":Red", 1117 (headType==null ? null : headType.getBean()), centrePanBorder3.getTitle()); 1118 if (t3 == null) { 1119 return; 1120 } else { 1121 ((TripleOutputSignalHead) signalHeadBeingEdited).setRed(nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t3)); 1122 } 1123 break; 1124 } 1125 case "jmri.implementation.DoubleTurnoutSignalHead": { 1126 var headType = ((DoubleTurnoutSignalHead) signalHeadBeingEdited).getGreen(); 1127 Turnout t1 = updateTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green", 1128 (headType==null ? null : headType.getBean()), centrePanBorder1.getTitle()); 1129 headType = ((DoubleTurnoutSignalHead) signalHeadBeingEdited).getRed(); 1130 Turnout t2 = updateTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Red", 1131 (headType==null ? null : headType.getBean()), centrePanBorder2.getTitle()); 1132 if (t1 == null) { 1133 return; 1134 } else { 1135 ((DoubleTurnoutSignalHead) signalHeadBeingEdited).setGreen(nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1)); 1136 } 1137 if (t2 == null) { 1138 return; 1139 } else { 1140 ((DoubleTurnoutSignalHead) signalHeadBeingEdited).setRed(nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2)); 1141 } 1142 break; 1143 } 1144 case "jmri.implementation.SingleTurnoutSignalHead": { 1145 var headType = ((SingleTurnoutSignalHead) signalHeadBeingEdited).getOutput(); 1146 Turnout t1 = updateTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":" + signalStateBox2.getSelectedItem() + ":" + signalStateBox3.getSelectedItem(), 1147 (headType==null ? null : headType.getBean()), centrePanBorder1.getTitle()); 1148 if (t1 == null) { 1149 noTurnoutMessage(centrePanBorder1.getTitle(), turnoutSelect1.getDisplayName()); 1150 return; 1151 } 1152 ((SingleTurnoutSignalHead) signalHeadBeingEdited).setOutput(nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1)); 1153 ((SingleTurnoutSignalHead) signalHeadBeingEdited).setOnAppearance(signalStateFromBox(signalStateBox2)); 1154 ((SingleTurnoutSignalHead) signalHeadBeingEdited).setOffAppearance(signalStateFromBox(signalStateBox3)); 1155 break; 1156 } 1157 case "jmri.implementation.LsDecSignalHead": { 1158 var headType = ((LsDecSignalHead) signalHeadBeingEdited).getGreen(); 1159 Turnout t1 = updateTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green", 1160 (headType==null ? null : headType.getBean()), centrePanBorder1.getTitle()); 1161 if (t1 == null) { 1162 return; 1163 } else { 1164 ((LsDecSignalHead) signalHeadBeingEdited).setGreen(nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1)); 1165 ((LsDecSignalHead) signalHeadBeingEdited).setGreenState(turnoutStateFromBox(turnoutStateBox1)); 1166 } 1167 1168 headType = ((LsDecSignalHead) signalHeadBeingEdited).getYellow(); 1169 Turnout t2 = updateTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Yellow", 1170 (headType==null ? null : headType.getBean()), centrePanBorder2.getTitle()); 1171 if (t2 == null) { 1172 return; 1173 } else { 1174 ((LsDecSignalHead) signalHeadBeingEdited).setYellow(nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2)); 1175 ((LsDecSignalHead) signalHeadBeingEdited).setYellowState(turnoutStateFromBox(turnoutStateBox2)); 1176 } 1177 1178 headType = ((LsDecSignalHead) signalHeadBeingEdited).getRed(); 1179 Turnout t3 = updateTurnoutFromPanel(turnoutSelect3, "SignalHead:" + systemNameField.getText() + ":Red", 1180 (headType==null ? null : headType.getBean()), centrePanBorder3.getTitle()); 1181 if (t3 == null) { 1182 return; 1183 } else { 1184 ((LsDecSignalHead) signalHeadBeingEdited).setRed(nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t3)); 1185 ((LsDecSignalHead) signalHeadBeingEdited).setRedState(turnoutStateFromBox(turnoutStateBox3)); 1186 } 1187 1188 headType = ((LsDecSignalHead) signalHeadBeingEdited).getFlashGreen(); 1189 Turnout t4 = updateTurnoutFromPanel(turnoutSelect4, "SignalHead:" + systemNameField.getText() + ":FlashGreen", 1190 (headType==null ? null : headType.getBean()), centrePanBorder4.getTitle()); 1191 if (t4 == null) { 1192 return; 1193 } else { 1194 ((LsDecSignalHead) signalHeadBeingEdited).setFlashGreen(nbhm.getNamedBeanHandle(turnoutSelect4.getDisplayName(), t4)); 1195 ((LsDecSignalHead) signalHeadBeingEdited).setFlashGreenState(turnoutStateFromBox(turnoutStateBox4)); 1196 } 1197 1198 headType = ((LsDecSignalHead) signalHeadBeingEdited).getFlashYellow(); 1199 Turnout t5 = updateTurnoutFromPanel(turnoutSelect5, "SignalHead:" + systemNameField.getText() + ":FlashYellow", 1200 (headType==null ? null : headType.getBean()), centrePanBorder5.getTitle()); 1201 if (t5 == null) { 1202 return; 1203 } else { 1204 ((LsDecSignalHead) signalHeadBeingEdited).setFlashYellow(nbhm.getNamedBeanHandle(turnoutSelect5.getDisplayName(), t5)); 1205 ((LsDecSignalHead) signalHeadBeingEdited).setFlashYellowState(turnoutStateFromBox(turnoutStateBox5)); 1206 } 1207 1208 headType = ((LsDecSignalHead) signalHeadBeingEdited).getFlashRed(); 1209 Turnout t6 = updateTurnoutFromPanel(turnoutSelect6, "SignalHead:" + systemNameField.getText() + ":FlashRed", 1210 (headType==null ? null : headType.getBean()), centrePanBorder6.getTitle()); 1211 if (t6 == null) { 1212 return; 1213 } else { 1214 ((LsDecSignalHead) signalHeadBeingEdited).setFlashRed(nbhm.getNamedBeanHandle(turnoutSelect6.getDisplayName(), t6)); 1215 ((LsDecSignalHead) signalHeadBeingEdited).setFlashRedState(turnoutStateFromBox(turnoutStateBox6)); 1216 } 1217 1218 headType = ((LsDecSignalHead) signalHeadBeingEdited).getDark(); 1219 Turnout t7 = updateTurnoutFromPanel(turnoutSelect7, "SignalHead:" + systemNameField.getText() + ":Dark", 1220 (headType==null ? null : headType.getBean()), centrePanBorder7.getTitle()); 1221 if (t7 == null) { 1222 return; 1223 } else { 1224 ((LsDecSignalHead) signalHeadBeingEdited).setDark(nbhm.getNamedBeanHandle(turnoutSelect7.getDisplayName(), t7)); 1225 ((LsDecSignalHead) signalHeadBeingEdited).setDarkState(turnoutStateFromBox(turnoutStateBox7)); 1226 } 1227 break; 1228 } 1229 case "jmri.jmrix.acela.AcelaSignalHead": 1230 AcelaNode tNode = AcelaAddress.getNodeFromSystemName(signalHeadBeingEdited.getSystemName(), InstanceManager.getDefault(AcelaSystemConnectionMemo.class)); 1231 if (tNode == null) { 1232 // node does not exist, ignore call 1233 log.error("Can't find new Acela Signal with name '{}'", signalHeadBeingEdited.getSystemName()); 1234 return; 1235 } 1236 int headnumber = Integer.parseInt(signalHeadBeingEdited.getSystemName().substring(2)); 1237 tNode.setOutputSignalHeadTypeString(headnumber, Objects.requireNonNull(acelaHeadTypeBox.getSelectedItem()).toString()); 1238 break; 1239 case "jmri.implementation.MergSD2SignalHead": 1240 switch (ukSignalAspectsFromBox(numberUkAspectsBox)) { 1241 case 4: 1242 var input3 = ((MergSD2SignalHead) signalHeadBeingEdited).getInput3(); 1243 Turnout t3 = updateTurnoutFromPanel(turnoutSelect5, (Bundle.getMessage("OutputComment", 1244 Bundle.getMessage("BeanNameSignalHead"), systemNameField.getText(), 1245 Bundle.getMessage("InputNum", "3"))), (input3==null ? null : input3.getBean()), 1246 centrePanBorder5.getTitle()); 1247 if (t3 == null) { 1248 return; 1249 } else { 1250 ((MergSD2SignalHead) signalHeadBeingEdited).setInput3(nbhm.getNamedBeanHandle(turnoutSelect5.getDisplayName(), t3)); 1251 } 1252 // fall through 1253 case 3: 1254 var input2 = ((MergSD2SignalHead) signalHeadBeingEdited).getInput2(); 1255 Turnout t2 = updateTurnoutFromPanel(turnoutSelect4, (Bundle.getMessage("OutputComment", 1256 Bundle.getMessage("BeanNameSignalHead"), systemNameField.getText(), 1257 Bundle.getMessage("InputNum", "2"))), (input2==null ? null : input2.getBean()), 1258 centrePanBorder4.getTitle()); 1259 if (t2 == null) { 1260 return; 1261 } else { 1262 ((MergSD2SignalHead) signalHeadBeingEdited).setInput2(nbhm.getNamedBeanHandle(turnoutSelect4.getDisplayName(), t2)); 1263 } 1264 // fall through 1265 case 2: 1266 var input1 = ((MergSD2SignalHead) signalHeadBeingEdited).getInput1(); 1267 Turnout t1 = updateTurnoutFromPanel(turnoutSelect3, (Bundle.getMessage("OutputComment", 1268 Bundle.getMessage("BeanNameSignalHead"), systemNameField.getText(), 1269 Bundle.getMessage("InputNum", "1"))), (input1==null ? null : input1.getBean()), 1270 centrePanBorder3.getTitle()); 1271 if (t1 == null) { 1272 return; 1273 } else { 1274 ((MergSD2SignalHead) signalHeadBeingEdited).setInput1(nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t1)); 1275 } 1276 ((MergSD2SignalHead) signalHeadBeingEdited).setAspects(ukSignalAspectsFromBox(numberUkAspectsBox)); 1277 ((MergSD2SignalHead) signalHeadBeingEdited).setHome(!ukSignalTypeFromBox(ukSignalSemaphoreTypeBox).equals("Distant")); 1278 break; 1279 default: 1280 break; 1281 } 1282 break; 1283 case "jmri.implementation.DccSignalHead": 1284 for (int i = 0; i < dccAspectSpinners.length; i++) { 1285 int number = (Integer) dccAspectSpinners[i].getValue(); 1286 try { 1287 ((DccSignalHead) signalHeadBeingEdited).setOutputForAppearance(signalHeadBeingEdited.getValidStates()[i], number); 1288 } catch (Exception ex) { 1289 //in theory JSpinner should already have caught a number conversion error. 1290 log.error("JSpinner for {} did not catch number conversion error", className, ex); 1291 } 1292 } 1293 ((DccSignalHead) signalHeadBeingEdited).useAddressOffSet(dccOffSetAddressCheckBox.isSelected()); 1294 ((DccSignalHead) signalHeadBeingEdited).setDccSignalHeadPacketSendCount(((int) dccPacketSendCountSpinner.getValue())); 1295 break; 1296 case "jmri.implementation.VirtualSignalHead": 1297 case "jmri.implementation.SE8cSignalHead": 1298 case "jmri.jmrix.grapevine.SerialSignalHead": 1299 break; 1300 default: 1301 log.error("Internal error - cannot update signal of type {}", className ); 1302 break; 1303 } 1304 // successful 1305 dispose(); 1306 } 1307 1308 private void createNewSigHead() { 1309 if (!checkUserName(userNameField.getText())) { 1310 return; 1311 } 1312 SignalHead s; 1313 try { 1314 if (SE8C4_ASPECT.equals(headTypeBox.getSelectedItem())) { 1315 handleSE8cOkPressed(); 1316 } else if (ACELA_ASPECT.equals(headTypeBox.getSelectedItem())) { 1317 String inputusername = userNameField.getText(); 1318 String inputsysname = systemNameField.getText(); 1319 int headnumber; 1320 1321 if (inputsysname.length() == 0) { 1322 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("signalHeadEntryWarning")); 1323 log.warn("must supply a signalhead number (i.e. AH23) using your prefix"); 1324 return; 1325 } 1326 1327 var acelaMemo = InstanceManager.getNullableDefault(AcelaSystemConnectionMemo.class); 1328 if ( acelaMemo == null ){ 1329 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("SystemNotActiveWarning", "Acela")); 1330 log.warn("No active Acela connection to create Signal Head"); 1331 return; 1332 } 1333 1334 String acelaPrefix = acelaMemo.getSystemPrefix(); 1335 if (inputsysname.length() > 2) { 1336 int offset = Manager.getSystemPrefixLength(inputsysname); 1337 if (inputsysname.startsWith(acelaPrefix)) { 1338 headnumber = Integer.parseInt(inputsysname.substring(offset)); 1339 } else if (checkIntegerOnly(inputsysname)) { 1340 headnumber = Integer.parseInt(inputsysname); 1341 } else { 1342 log.warn("skipping creation of signal head, '{}' does not start with AxH", inputsysname); 1343 String msg = Bundle.getMessage("acelaSkippingCreation", systemNameField.getText()); 1344 JmriJOptionPane.showMessageDialog(this, msg, 1345 Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 1346 return; 1347 } 1348 } else { 1349 headnumber = Integer.parseInt(inputsysname); 1350 } 1351 1352 AcelaNode acelaNode = AcelaAddress.getNodeFromSystemName(acelaPrefix + "H" + headnumber, InstanceManager.getDefault(AcelaSystemConnectionMemo.class)); 1353 if (acelaNode==null) { 1354 JmriJOptionPane.showMessageDialog(this, 1355 Bundle.getMessage("acelaNoNodeFound",Bundle.getMessage("BeanNameSignalHead"),headnumber), 1356 Bundle.getMessage("ErrorSignalHeadAddFailed",headnumber), JmriJOptionPane.ERROR_MESSAGE); 1357 return; 1358 } 1359 1360 if (checkSysNameOkBeforeCreating(acelaPrefix + "H" + headnumber)) { 1361 if (inputusername.length() == 0) { 1362 s = new AcelaSignalHead(acelaPrefix + "H" + headnumber, InstanceManager.getDefault(AcelaSystemConnectionMemo.class)); 1363 } else { 1364 s = new AcelaSignalHead(acelaPrefix + "H" + headnumber, inputusername, InstanceManager.getDefault(AcelaSystemConnectionMemo.class)); 1365 } 1366 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1367 } 1368 1369 int st = acelaSignalheadTypeFromBox(acelaHeadTypeBox); 1370 switch (st) { 1371 case 1: 1372 acelaNode.setOutputSignalHeadType(headnumber, AcelaNode.DOUBLE); 1373 break; 1374 case 2: 1375 acelaNode.setOutputSignalHeadType(headnumber, AcelaNode.TRIPLE); 1376 break; 1377 case 3: 1378 acelaNode.setOutputSignalHeadType(headnumber, AcelaNode.BPOLAR); 1379 break; 1380 case 4: 1381 acelaNode.setOutputSignalHeadType(headnumber, AcelaNode.WIGWAG); 1382 break; 1383 default: 1384 log.warn("Unexpected Acela Aspect type: {}", st); 1385 acelaNode.setOutputSignalHeadType(headnumber, AcelaNode.UKNOWN); 1386 break; // default to triple 1387 } 1388 1389 } else if (GRAPEVINE.equals(headTypeBox.getSelectedItem())) { 1390 // the turnout field must hold a GxH system name (Gx = multichar prefix) 1391 if (systemNameField.getText().length() == 0) { 1392 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("signalHeadEntryWarning")); 1393 log.warn("must supply a signalhead number (i.e. GH23) using your prefix"); 1394 return; 1395 } 1396 String inputsysname = systemNameField.getText(); 1397 int offset = Manager.getSystemPrefixLength(inputsysname); 1398 String grapevinePrefix = InstanceManager.getDefault(GrapevineSystemConnectionMemo.class).getSystemPrefix(); 1399 if (!inputsysname.startsWith(grapevinePrefix) || inputsysname.charAt(offset) != 'H') { 1400 log.warn("skipping creation of signal head, '{}' does not start with GxH", inputsysname); 1401 String msg = Bundle.getMessage("GrapevineSkippingCreation", inputsysname); 1402 JmriJOptionPane.showMessageDialog(this, msg, 1403 Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 1404 return; 1405 } 1406 if (checkSysNameOkBeforeCreating(inputsysname)) { 1407 s = new SerialSignalHead(inputsysname, userNameField.getText(), InstanceManager.getDefault(GrapevineSystemConnectionMemo.class)); 1408 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1409 } 1410 } else if (QUAD_OUTPUT.equals(headTypeBox.getSelectedItem())) { 1411 if (checkSysNameOkBeforeCreating(systemNameField.getText())) { 1412 Turnout t1 = getTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green"); 1413 Turnout t2 = getTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Yellow"); 1414 Turnout t3 = getTurnoutFromPanel(turnoutSelect3, "SignalHead:" + systemNameField.getText() + ":Red"); 1415 Turnout t4 = getTurnoutFromPanel(turnoutSelect4, "SignalHead:" + systemNameField.getText() + ":Lunar"); 1416 1417 if (t1 == null) { 1418 addTurnoutMessage(centrePanBorder1.getTitle(), turnoutSelect1.getDisplayName()); 1419 } 1420 if (t2 == null) { 1421 addTurnoutMessage(centrePanBorder2.getTitle(), turnoutSelect2.getDisplayName()); 1422 } 1423 if (t3 == null) { 1424 addTurnoutMessage(centrePanBorder3.getTitle(), turnoutSelect3.getDisplayName()); 1425 } 1426 if (t4 == null) { 1427 addTurnoutMessage(centrePanBorder4.getTitle(), turnoutSelect4.getDisplayName()); 1428 } 1429 if (t4 == null || t3 == null || t2 == null || t1 == null) { 1430 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1431 return; 1432 } 1433 s = new QuadOutputSignalHead(systemNameField.getText(), userNameField.getText(), 1434 nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1), 1435 nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2), 1436 nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t3), 1437 nbhm.getNamedBeanHandle(turnoutSelect4.getDisplayName(), t4)); 1438 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1439 1440 } 1441 } else if (TRIPLE_TURNOUT.equals(headTypeBox.getSelectedItem())) { 1442 if (checkSysNameOkBeforeCreating(systemNameField.getText())) { 1443 Turnout t1 = getTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green"); 1444 Turnout t2 = getTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Yellow"); 1445 Turnout t3 = getTurnoutFromPanel(turnoutSelect3, "SignalHead:" + systemNameField.getText() + ":Red"); 1446 1447 if (t1 == null) { 1448 addTurnoutMessage(centrePanBorder1.getTitle(), turnoutSelect1.getDisplayName()); 1449 } 1450 if (t2 == null) { 1451 addTurnoutMessage(centrePanBorder2.getTitle(), turnoutSelect2.getDisplayName()); 1452 } 1453 if (t3 == null) { 1454 addTurnoutMessage(centrePanBorder3.getTitle(), turnoutSelect3.getDisplayName()); 1455 } 1456 if (t3 == null || t2 == null || t1 == null) { 1457 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1458 return; 1459 } 1460 1461 s = new TripleTurnoutSignalHead(systemNameField.getText(), userNameField.getText(), 1462 nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1), 1463 nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2), 1464 nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t3)); 1465 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1466 } 1467 } else if (TRIPLE_OUTPUT.equals(headTypeBox.getSelectedItem())) { 1468 if (checkSysNameOkBeforeCreating(systemNameField.getText())) { 1469 Turnout t1 = getTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green"); 1470 Turnout t2 = getTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Blue"); 1471 Turnout t3 = getTurnoutFromPanel(turnoutSelect3, "SignalHead:" + systemNameField.getText() + ":Red"); 1472 1473 if (t1 == null) { 1474 addTurnoutMessage(centrePanBorder1.getTitle(), turnoutSelect1.getDisplayName()); 1475 } 1476 if (t2 == null) { 1477 addTurnoutMessage(centrePanBorder2.getTitle(), turnoutSelect2.getDisplayName()); 1478 } 1479 if (t3 == null) { 1480 addTurnoutMessage(centrePanBorder3.getTitle(), turnoutSelect3.getDisplayName()); 1481 } 1482 if (t3 == null || t2 == null || t1 == null) { 1483 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1484 return; 1485 } 1486 1487 s = new TripleOutputSignalHead(systemNameField.getText(), userNameField.getText(), 1488 nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1), 1489 nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2), 1490 nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t3)); 1491 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1492 } 1493 } else if (DOUBLE_TURNOUT.equals(headTypeBox.getSelectedItem())) { 1494 if (checkSysNameOkBeforeCreating(systemNameField.getText())) { 1495 Turnout t1 = getTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green"); 1496 Turnout t2 = getTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Red"); 1497 1498 if (t1 == null) { 1499 addTurnoutMessage(centrePanBorder1.getTitle(), turnoutSelect1.getDisplayName()); 1500 } 1501 if (t2 == null) { 1502 addTurnoutMessage(centrePanBorder2.getTitle(), turnoutSelect2.getDisplayName()); 1503 } 1504 if (t2 == null || t1 == null) { 1505 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1506 return; 1507 } 1508 1509 s = new DoubleTurnoutSignalHead(systemNameField.getText(), userNameField.getText(), 1510 nbhm.getNamedBeanHandle(turnoutSelect1.getDisplayName(), t1), 1511 nbhm.getNamedBeanHandle(turnoutSelect2.getDisplayName(), t2)); 1512 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1513 } 1514 } else if (SINGLE_TURNOUT.equals(headTypeBox.getSelectedItem())) { 1515 if (checkSysNameOkBeforeCreating(systemNameField.getText())) { 1516 Turnout t1 = getTurnoutFromPanel(turnoutSelect1, 1517 "SignalHead:" + systemNameField.getText() + ":" + signalStateBox2.getSelectedItem() + ":" + signalStateBox3.getSelectedItem()); 1518 1519 int on = signalStateFromBox(signalStateBox2); 1520 int off = signalStateFromBox(signalStateBox3); 1521 if (t1 == null) { 1522 addTurnoutMessage(centrePanBorder1.getTitle(), turnoutSelect1.getDisplayName()); 1523 } 1524 if (t1 == null) { 1525 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1526 return; 1527 } 1528 1529 s = new SingleTurnoutSignalHead(systemNameField.getText(), userNameField.getText(), 1530 nbhm.getNamedBeanHandle(t1.getDisplayName(), t1), on, off); 1531 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1532 } 1533 } else if (VIRTUAL_HEAD.equals(headTypeBox.getSelectedItem())) { 1534 if (checkSysNameOkBeforeCreating(systemNameField.getText())) { 1535 s = new VirtualSignalHead(systemNameField.getText(), userNameField.getText()); 1536 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1537 } 1538 } else if (LSDEC.equals(headTypeBox.getSelectedItem())) { // LDT LS-DEC 1539 if (checkSysNameOkBeforeCreating(systemNameField.getText())) { 1540 Turnout t1 = getTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":Green"); 1541 Turnout t2 = getTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":Yellow"); 1542 Turnout t3 = getTurnoutFromPanel(turnoutSelect3, "SignalHead:" + systemNameField.getText() + ":Red"); 1543 Turnout t4 = getTurnoutFromPanel(turnoutSelect4, "SignalHead:" + systemNameField.getText() + ":FlashGreen"); 1544 Turnout t5 = getTurnoutFromPanel(turnoutSelect5, "SignalHead:" + systemNameField.getText() + ":FlashYellow"); 1545 Turnout t6 = getTurnoutFromPanel(turnoutSelect6, "SignalHead:" + systemNameField.getText() + ":FlashRed"); 1546 Turnout t7 = getTurnoutFromPanel(turnoutSelect7, "SignalHead:" + systemNameField.getText() + ":Dark"); 1547 1548 int s1 = turnoutStateFromBox(turnoutStateBox1); 1549 int s2 = turnoutStateFromBox(turnoutStateBox2); 1550 int s3 = turnoutStateFromBox(turnoutStateBox3); 1551 int s4 = turnoutStateFromBox(turnoutStateBox4); 1552 int s5 = turnoutStateFromBox(turnoutStateBox5); 1553 int s6 = turnoutStateFromBox(turnoutStateBox6); 1554 int s7 = turnoutStateFromBox(turnoutStateBox7); 1555 1556 if (t1 == null) { 1557 addTurnoutMessage(centrePanBorder1.getTitle(), turnoutSelect1.getDisplayName()); 1558 } 1559 if (t2 == null) { 1560 addTurnoutMessage(centrePanBorder2.getTitle(), turnoutSelect2.getDisplayName()); 1561 } 1562 if (t3 == null) { 1563 addTurnoutMessage(centrePanBorder3.getTitle(), turnoutSelect3.getDisplayName()); 1564 } 1565 if (t4 == null) { 1566 addTurnoutMessage(centrePanBorder4.getTitle(), turnoutSelect4.getDisplayName()); 1567 } 1568 if (t5 == null) { 1569 addTurnoutMessage(centrePanBorder5.getTitle(), turnoutSelect5.getDisplayName()); 1570 } 1571 if (t6 == null) { 1572 addTurnoutMessage(centrePanBorder6.getTitle(), turnoutSelect6.getDisplayName()); 1573 } 1574 if (t7 == null) { 1575 addTurnoutMessage(centrePanBorder7.getTitle(), turnoutSelect7.getDisplayName()); 1576 } 1577 if (t7 == null || t6 == null || t5 == null || t4 == null || t3 == null || t2 == null || t1 == null) { 1578 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1579 return; 1580 } 1581 s = new LsDecSignalHead(systemNameField.getText(), 1582 nbhm.getNamedBeanHandle(t1.getDisplayName(), t1), s1, 1583 nbhm.getNamedBeanHandle(t2.getDisplayName(), t2), s2, 1584 nbhm.getNamedBeanHandle(t3.getDisplayName(), t3), s3, 1585 nbhm.getNamedBeanHandle(t4.getDisplayName(), t4), s4, 1586 nbhm.getNamedBeanHandle(t5.getDisplayName(), t5), s5, 1587 nbhm.getNamedBeanHandle(t6.getDisplayName(), t6), s6, 1588 nbhm.getNamedBeanHandle(t7.getDisplayName(), t7), s7); 1589 s.setUserName(userNameField.getText()); 1590 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1591 } 1592 } else if (DCC_SIGNAL_DECODER.equals(headTypeBox.getSelectedItem())) { 1593 handleDCCOkPressed(); 1594 } else if (MERG_SIGNAL_DRIVER.equals(headTypeBox.getSelectedItem())) { 1595 handleMergSignalDriverOkPressed(); 1596 } else { 1597 throw new UnsupportedOperationException("Unexpected type: " + headTypeBox.getSelectedItem()); 1598 } 1599 1600 } catch (NumberFormatException ex) { 1601 handleCreateException(ex, systemNameField.getText()); 1602 // return; // without creating 1603 } 1604 1605 } 1606 1607 private void addTurnoutMessage(String s1, String s2) { 1608 log.warn("Could not provide turnout {}", s2); 1609 String msg = Bundle.getMessage("AddNoTurnout", s1, s2); 1610 JmriJOptionPane.showMessageDialog(this, msg, 1611 Bundle.getMessage("WarningTitle") + " " + s1, JmriJOptionPane.ERROR_MESSAGE); 1612 } 1613 1614 private void handleCreateException(Exception ex, String sysName) { 1615 if (ex.getLocalizedMessage() != null) { 1616 JmriJOptionPane.showMessageDialog(this, 1617 ex.getLocalizedMessage(), 1618 Bundle.getMessage("ErrorTitle"), 1619 JmriJOptionPane.ERROR_MESSAGE); 1620 } else if (ex.getMessage() != null) { 1621 JmriJOptionPane.showMessageDialog(this, 1622 ex.getMessage(), 1623 Bundle.getMessage("ErrorTitle"), 1624 JmriJOptionPane.ERROR_MESSAGE); 1625 } else { 1626 JmriJOptionPane.showMessageDialog(this, 1627 Bundle.getMessage("ErrorSignalHeadAddFailed", sysName) + "\n" + Bundle.getMessage("ErrorAddFailedCheck"), 1628 Bundle.getMessage("ErrorTitle"), 1629 JmriJOptionPane.ERROR_MESSAGE); 1630 } 1631 } 1632 1633 private int acelaSignalheadTypeFromBox(JComboBox<String> box) { 1634 String mode = (String) box.getSelectedItem(); 1635 int result = StringUtil.getStateFromName(mode, ACELA_SIG_HEAD_TYPE_VALUES, ACELA_SIG_HEAD_TYPES); 1636 1637 if (result < 0) { 1638 log.warn("unexpected mode string in signalhead appearance type: {}", mode); 1639 throw new IllegalArgumentException(); 1640 } 1641 return result; 1642 } 1643 1644 private void handleSE8cOkPressed() { 1645 1646 Turnout t1 = getTurnoutFromPanel(turnoutSelect1, "SignalHead:" + systemNameField.getText() + ":low"); 1647 Turnout t2 = getTurnoutFromPanel(turnoutSelect2, "SignalHead:" + systemNameField.getText() + ":high"); 1648 1649 // check validity 1650 if (t1 != null && t2 != null) { 1651 // OK, process 1652 SignalHead s; 1653 try { 1654 s = new SE8cSignalHead( 1655 nbhm.getNamedBeanHandle(t1.getSystemName(), t1), 1656 nbhm.getNamedBeanHandle(t2.getSystemName(), t2), 1657 userNameField.getText()); 1658 } catch (NumberFormatException ex) { 1659 // user input no good 1660 handleCreate2TurnoutException(t1.getSystemName(), 1661 t2.getSystemName(), userNameField.getText()); 1662 return; // without creating any 1663 } 1664 try { 1665 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1666 } catch ( jmri.NamedBean.DuplicateSystemNameException ex) { 1667 s.dispose(); 1668 JmriJOptionPane.showMessageDialog(this,"<html>" 1669 + Bundle.getMessage("ErrorSe8cDuplicateSysName", t1.getDisplayName(), t2.getDisplayName()) 1670 + "<br>" + Bundle.getMessage("ErrorReplaceHead") 1671 + "<br>" + ex.getLocalizedMessage() + "</html>", 1672 Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 1673 } 1674 } else { 1675 // couldn't create turnouts, error 1676 String msg; 1677 if (t1 == null) { 1678 msg = Bundle.getMessage("se8c4SkippingDueToErrorInFirst"); 1679 } else { 1680 msg = Bundle.getMessage("se8c4SkippingDueToErrorInSecond"); 1681 } 1682 JmriJOptionPane.showMessageDialog(this, msg, 1683 Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 1684 } 1685 } 1686 1687 private void handleDCCOkPressed() { 1688 DccSignalHead s; 1689 String systemNameText = null; 1690 String prefix = (String) prefixBox.getSelectedItem(); 1691 if (prefix != null) { 1692 systemNameText = ConnectionNameFromSystemName.getPrefixFromName(prefix); 1693 } 1694 // if we return a null string then we will set it to use internal, thus picking up the default command station at a later date. 1695 if (systemNameText == null) { 1696 systemNameText = "I"; 1697 } 1698 systemNameText = systemNameText + "H$" + systemNameField.getText(); 1699 1700 if (checkSysNameOkBeforeCreating(systemNameText)) { 1701 s = new DccSignalHead(systemNameText); 1702 s.setUserName(userNameField.getText()); 1703 log.debug("dccAspect Length = {}", dccAspectSpinners.length); 1704 for (int i = 0; i < DccSignalHead.getDefaultValidStates().length; i++) { // no need to check DCC ID input when using JSpinner 1705 log.debug("i = {}", i); 1706 int number = (Integer) dccAspectSpinners[i].getValue(); 1707 try { 1708 s.setOutputForAppearance(s.getValidStates()[i], number); 1709 } catch (RuntimeException ex) { 1710 log.warn("error setting \"{}\" output for appearance \"{}\"", systemNameText, number); 1711 } 1712 } 1713 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1714 s.useAddressOffSet(dccOffSetAddressCheckBox.isSelected()); 1715 s.setDccSignalHeadPacketSendCount((int)dccPacketSendCountSpinner.getValue()); 1716 } 1717 } 1718 1719 @SuppressWarnings("fallthrough") 1720 @SuppressFBWarnings(value = "SF_SWITCH_FALLTHROUGH") 1721 private void handleMergSignalDriverOkPressed() { 1722 SignalHead s; 1723 // Adding Merg Signal Driver. 1724 Turnout t3; 1725 Turnout t2; 1726 Turnout t1; 1727 NamedBeanHandle<Turnout> nbt1 = null; 1728 NamedBeanHandle<Turnout> nbt2 = null; 1729 NamedBeanHandle<Turnout> nbt3 = null; 1730 if (checkSysNameOkBeforeCreating(systemNameField.getText())) { 1731 switch (ukSignalAspectsFromBox(numberUkAspectsBox)) { 1732 case 4: 1733 t3 = getTurnoutFromPanel(turnoutSelect5, 1734 (Bundle.getMessage("OutputComment", Bundle.getMessage("BeanNameSignalHead"), systemNameField.getText(), Bundle.getMessage("InputNum", "3")))); 1735 if (t3 == null) { 1736 addTurnoutMessage(centrePanBorder5.getTitle(), turnoutSelect5.getDisplayName()); 1737 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1738 return; 1739 } else { 1740 nbt3 = nbhm.getNamedBeanHandle(turnoutSelect5.getDisplayName(), t3); 1741 } 1742 1743 // fall through 1744 case 3: 1745 t2 = getTurnoutFromPanel(turnoutSelect4, 1746 (Bundle.getMessage("OutputComment", Bundle.getMessage("BeanNameSignalHead"), systemNameField.getText(), Bundle.getMessage("InputNum", "2")))); 1747 if (t2 == null) { 1748 addTurnoutMessage(centrePanBorder4.getTitle(), turnoutSelect4.getDisplayName()); 1749 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1750 return; 1751 } else { 1752 nbt2 = nbhm.getNamedBeanHandle(turnoutSelect4.getDisplayName(), t2); 1753 } 1754 // fall through 1755 case 2: 1756 t1 = getTurnoutFromPanel(turnoutSelect3, 1757 (Bundle.getMessage("OutputComment", Bundle.getMessage("BeanNameSignalHead"), systemNameField.getText(), Bundle.getMessage("InputNum", "1")))); 1758 if (t1 == null) { 1759 addTurnoutMessage(centrePanBorder3.getTitle(), turnoutSelect3.getDisplayName()); 1760 log.warn("skipping creation of signal {} due to error", systemNameField.getText()); 1761 return; 1762 } else { 1763 nbt1 = nbhm.getNamedBeanHandle(turnoutSelect3.getDisplayName(), t1); 1764 } 1765 break; 1766 default: 1767 break; 1768 } 1769 boolean home = !ukSignalTypeFromBox(ukSignalSemaphoreTypeBox).equals(Bundle.getMessage("DistantSignal")); 1770 1771 s = new MergSD2SignalHead(systemNameField.getText(), ukSignalAspectsFromBox(numberUkAspectsBox), nbt1, nbt2, nbt3, false, home); 1772 s.setUserName(userNameField.getText()); 1773 InstanceManager.getDefault(SignalHeadManager.class).register(s); 1774 1775 } 1776 } 1777 1778 private boolean checkSysNameOkBeforeCreating(String sysName) { 1779 if (DCC_SIGNAL_DECODER.equals(headTypeBox.getSelectedItem())) { 1780 try { 1781 Integer.valueOf(sysName.substring(sysName.indexOf("$") + 1)); 1782 } catch (NumberFormatException ex) { 1783 String msg = Bundle.getMessage("ShouldBeNumber", "Hardware Address"); 1784 JmriJOptionPane.showMessageDialog(this, msg, 1785 Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 1786 return false; 1787 } 1788 } else { 1789 boolean ok = true; 1790 try { 1791 int i = Manager.getSystemPrefixLength(sysName); 1792 if (sysName.length() < i+2) { 1793 ok = false; 1794 } else { 1795 if (sysName.charAt(i) != 'H') ok = false; 1796 } 1797 } catch (NamedBean.BadSystemNameException e) { 1798 ok = false; 1799 } 1800 if (!ok) { 1801 String msg = Bundle.getMessage("InvalidSignalSystemName", sysName); 1802 JmriJOptionPane.showMessageDialog(this, msg, 1803 Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 1804 return false; 1805 } 1806 } 1807 // check for pre-existing signal head with same system name 1808 SignalHead s = InstanceManager.getDefault(SignalHeadManager.class).getBySystemName(sysName); 1809 // return true if signal head does not exist 1810 if (s == null) { 1811 //Need to check that the Systemname doesn't already exists as a UserName 1812 SignalHead nB = InstanceManager.getDefault(SignalHeadManager.class).getByUserName(sysName); 1813 if (nB != null) { 1814 log.error("System name is not unique {} It already exists as a User name", sysName); 1815 String msg = Bundle.getMessage("WarningSystemNameAsUser", ("" + sysName)); 1816 JmriJOptionPane.showMessageDialog(this, msg, 1817 Bundle.getMessage("WarningTitle"), 1818 JmriJOptionPane.ERROR_MESSAGE); 1819 return false; 1820 } 1821 return true; 1822 } 1823 // inform the user if signal head already exists, and return false so creation can be bypassed 1824 log.warn("Attempt to create signal with duplicate system name {}", sysName); 1825 String msg = Bundle.getMessage("DuplicateSignalSystemName", sysName); 1826 JmriJOptionPane.showMessageDialog(this, msg, 1827 Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 1828 return false; 1829 } 1830 1831 private boolean checkIntegerOnly(String s) { 1832 for (int i = 0; i < s.length(); i++) { 1833 if (!Character.isDigit(s.charAt(i))) { 1834 return false; 1835 } 1836 } 1837 return true; 1838 } 1839 1840 private void handleCreate2TurnoutException(String t1, String t2, String uName) { 1841 JmriJOptionPane.showMessageDialog(this, 1842 Bundle.getMessage("ErrorSe8cAddFailed", uName, t1, t2) + "\n" + Bundle.getMessage("ErrorAddFailedCheck"), 1843 Bundle.getMessage("ErrorTitle"), 1844 JmriJOptionPane.ERROR_MESSAGE); 1845 } 1846 1847 /** 1848 * Update Turnout object for a signal mast output. 1849 * 1850 * @param bp Pane in which the new output/bean was entered by user 1851 * @param reference Turnout application description 1852 * @param oldTurnout Previously used output 1853 * @param title for warning pane 1854 * @return The newly defined output as Turnout object 1855 */ 1856 @CheckForNull 1857 private Turnout updateTurnoutFromPanel(@Nonnull BeanSelectCreatePanel<Turnout> bp, String reference, @CheckForNull Turnout oldTurnout, String title) { 1858 Turnout newTurnout = getTurnoutFromPanel(bp, reference); 1859 if (newTurnout == null) { 1860 noTurnoutMessage(title, bp.getDisplayName()); 1861 } 1862 String comment; 1863 if (newTurnout != null) { 1864 comment = newTurnout.getComment(); 1865 if (comment == null || comment.isEmpty()) { 1866 newTurnout.setComment(reference); // enter turnout application description into new turnout Comment 1867 } 1868 } 1869 if (oldTurnout == null || newTurnout == oldTurnout) { 1870 return newTurnout; 1871 } 1872 comment = oldTurnout.getComment(); 1873 if (comment != null && comment.equals(reference)) { 1874 // wont delete old Turnout Comment if Locale or Bundle was changed in between, but user could have type something in the Comment as well 1875 oldTurnout.setComment(null); // deletes current Comment in bean 1876 } 1877 return newTurnout; 1878 } 1879 1880 /** 1881 * Create Turnout object for a signal mast output. 1882 * 1883 * @param bp Pane in which the new output/bean was entered by user 1884 * @param reference Turnout application description 1885 * @return The new output as Turnout object 1886 */ 1887 @CheckForNull 1888 private Turnout getTurnoutFromPanel(@Nonnull BeanSelectCreatePanel<Turnout> bp, String reference) { 1889 bp.setReference(reference); // pass turnout application description to be put into turnout Comment 1890 try { 1891 return bp.getNamedBean(); 1892 } catch (JmriException ex) { 1893 log.warn("skipping creation of turnout not found for {}", reference); 1894 return null; 1895 } 1896 } 1897 1898 private boolean checkUserName(String nam) { 1899 if (!((nam == null) || (nam.isEmpty()))) { 1900 // user name changed, check if new name already exists 1901 NamedBean nB = InstanceManager.getDefault(SignalHeadManager.class).getByUserName(nam); 1902 if (nB != null) { 1903 log.error("User name is not unique {}", nam); 1904 String msg = Bundle.getMessage("WarningUserName", ("" + nam)); 1905 JmriJOptionPane.showMessageDialog(this, msg, 1906 Bundle.getMessage("InvalidUserNameAlreadyExists", Bundle.getMessage("BeanNameSignalHead"),nam), 1907 JmriJOptionPane.ERROR_MESSAGE); 1908 return false; 1909 } 1910 //Check to ensure that the username doesn't exist as a systemname. 1911 nB = InstanceManager.getDefault(SignalHeadManager.class).getBySystemName(nam); 1912 if (nB != null) { 1913 log.error("User name is not unique {} It already exists as a System name", nam); 1914 String msg = Bundle.getMessage("WarningUserNameAsSystem", ("" + nam)); 1915 JmriJOptionPane.showMessageDialog(this, msg, 1916 Bundle.getMessage("InvalidUserNameAlreadyExists", Bundle.getMessage("BeanNameSignalHead"),nam), 1917 JmriJOptionPane.ERROR_MESSAGE); 1918 return false; 1919 } 1920 } 1921 return true; 1922 } 1923 1924 private void noTurnoutMessage(String s1, String s2) { 1925 log.warn("Could not provide turnout {}", s2); 1926 String msg = Bundle.getMessage("WarningNoTurnout", s1, s2); 1927 JmriJOptionPane.showMessageDialog(this, msg, 1928 Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE); 1929 } 1930 1931 @Override 1932 public void dispose() { 1933 if (turnoutSelect1 != null) { 1934 turnoutSelect1.dispose(); 1935 } 1936 if (turnoutSelect2 != null) { 1937 turnoutSelect2.dispose(); 1938 } 1939 if (turnoutSelect3 != null) { 1940 turnoutSelect3.dispose(); 1941 } 1942 if (turnoutSelect4 != null) { 1943 turnoutSelect4.dispose(); 1944 } 1945 if (turnoutSelect5 != null) { 1946 turnoutSelect5.dispose(); 1947 } 1948 if (turnoutSelect6 != null) { 1949 turnoutSelect6.dispose(); 1950 } 1951 if (turnoutSelect7 != null) { 1952 turnoutSelect7.dispose(); 1953 } 1954 super.dispose(); 1955 } 1956 1957 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SignalHeadAddEditFrame.class); 1958 1959}