001package jmri.jmrix.can.cbus.swing.modeswitcher; 002 003import java.awt.BorderLayout; 004import java.awt.event.ActionListener; 005 006import javax.swing.*; 007 008import jmri.InstanceManager; 009import jmri.jmrix.can.*; 010import jmri.jmrix.can.cbus.CbusConsistManager; 011import jmri.util.swing.JmriJOptionPane; 012 013/** 014 * Mode Switcher to switch modes between programmer and command station for simple 015 * hardware with a single track output. 016 * 017 * @author Andrew Crosland Copyright (C) 2020, 2021 018 */ 019public class SprogCbusSimpleModeSwitcherFrame extends SprogCbusModeSwitcherFrame { 020 021 protected static final int PROG_MODE = 0; // Original SPROG Programnmer mode 022 protected static final int CMD_MODE = 1; // Original SPROG Command Station mode 023 024 private JRadioButton progModeButton; 025 private JRadioButton cmdModeButton; 026 027 public SprogCbusSimpleModeSwitcherFrame(CanSystemConnectionMemo memo) { 028 super(memo, Bundle.getMessage("SprogCbusSimpleModeSwitcher")); 029 } 030 031 032 /** 033 * Display radio buttons to select between Programmer mode (service mode 034 * programming) and command station mode (ops mode programming). 035 * <p> 036 * Only one mode may be selected at a time. 037 * <p> 038 * At least one mode must be enabled and the default is programmer mode if 039 * all modes are deselected. 040 * 041 * {@inheritDoc} 042 */ 043 @Override 044 public void initComponents() { 045 if (initSetup()) { 046 // Create selection buttons, add to exclusive group and set initial state from preferences 047 progModeButton = new JRadioButton(Bundle.getMessage("ProgMode")); 048 cmdModeButton = new JRadioButton(Bundle.getMessage("CmdMode")); 049 ButtonGroup buttons = new ButtonGroup(); 050 buttons.add(progModeButton); 051 buttons.add(cmdModeButton); 052 053 // Get current preferences 054 // It is expected that the saved preferences will usually match the hardware. 055 if (pm.isGlobalProgrammerAvailable() && preferences.isGlobalProgrammerAvailable()) { 056 // Programmer (service) mode 057 progModeButton.setSelected(true); 058 cmdModeButton.setSelected(false); 059 mode = PROG_MODE; 060 _memo.setMultipleThrottles(false); 061 } else if (pm.isAddressedModePossible() && preferences.isAddressedModePossible()) { 062 // Command Station (ops, addressed) mode 063 progModeButton.setSelected(false); 064 cmdModeButton.setSelected(true); 065 mode = CMD_MODE; 066 _memo.setMultipleThrottles(true); 067 } else { 068 // Default to programmer (service) mode if inconsistent preference 069 progModeButton.setSelected(true); 070 cmdModeButton.setSelected(false); 071 mode = PROG_MODE; 072 _memo.setMultipleThrottles(false); 073 } 074 // Reset hardware mode and preferences in case there was any inconsistency 075 setHardwareMode(mode); 076 preferences.setProgrammersAvailable(progModeButton.isSelected(), cmdModeButton.isSelected()); 077 078 // Handle Programmer mode button activity 079 ActionListener listener = ae -> { 080 CbusConsistManager cm = (CbusConsistManager)InstanceManager.getNullableDefault(jmri.ConsistManager.class); 081 if (progModeButton.isSelected() && mode != PROG_MODE) { 082 // Switch to programmer mode 083 log.info("Setting Global Programmer Available"); 084 pm.setGlobalProgrammerAvailable(true); 085 log.info("Setting Addressed Programmer Unavailable"); 086 pm.setAddressedModePossible(false); 087 _memo.setMultipleThrottles(false); 088 showServiceModeWarningDialogue(); 089 closeProgrammerWarningDialogue(); 090 if (cm != null) { 091 cm.setEnabled(false); 092 } 093 mode = PROG_MODE; 094 } else if (cmdModeButton.isSelected() && mode != CMD_MODE) { 095 // Switch to command station mode 096 log.info("Setting Global Programmer Unavailable"); 097 pm.setGlobalProgrammerAvailable(false); 098 log.info("Setting Addressed Programmer Available"); 099 pm.setAddressedModePossible(true); 100 _memo.setMultipleThrottles(true); 101 closeProgrammerWarningDialogue(); 102 if (cm != null) { 103 cm.setEnabled(true); 104 } 105 mode = CMD_MODE; 106 } 107 setHardwareMode(mode); 108 preferences.setProgrammersAvailable(progModeButton.isSelected(), cmdModeButton.isSelected()); 109 }; 110 111 progModeButton.addActionListener(listener); 112 cmdModeButton.addActionListener(listener); 113 modePane.add(progModeButton); 114 modePane.add(cmdModeButton); 115 116 panel.add(label, BorderLayout.NORTH); 117 panel.add(modePane, BorderLayout.CENTER); 118 } 119 120 // add help menu to window 121 setHelp(); 122 123 this.add(panel); 124 pack(); 125 setVisible(true); 126 } 127 128 private boolean _hideProgWarning = false; 129 130 protected void closeProgrammerWarningDialogue(){ 131 if ((!java.awt.GraphicsEnvironment.isHeadless()) && (!_hideProgWarning)){ 132 jmri.util.ThreadingUtil.runOnGUI(() -> { 133 javax.swing.JCheckBox checkbox = new javax.swing.JCheckBox(Bundle.getMessage("HideFurtherWarnings")); 134 java.awt.event.ActionListener progPopUpCheckBox = (java.awt.event.ActionEvent evt) -> hideProgWarning(checkbox.isSelected()); 135 checkbox.addActionListener(progPopUpCheckBox); 136 Object[] params = {Bundle.getMessage("ProgWarning"), checkbox}; 137 JmriJOptionPane.showMessageDialogNonModal(null, params, 138 Bundle.getMessage("switchMode"), 139 JmriJOptionPane.WARNING_MESSAGE, null); 140 }); 141 } 142 } 143 144 /** 145 * Receive notification from a mode switcher dialogue to close programmer when 146 * switching modes. This so buttons correctly reflect available operations. 147 * False by default to show notifications 148 * 149 * @param hide set True to hide notifications, else False. 150 */ 151 public void hideProgWarning(boolean hide){ 152 _hideProgWarning = hide; 153 } 154 155 private boolean _hideProgModeWarning = false; 156 157 protected void showServiceModeWarningDialogue(){ 158 if ((!java.awt.GraphicsEnvironment.isHeadless()) && (!_hideProgModeWarning)){ 159 jmri.util.ThreadingUtil.runOnGUI(() -> { 160 javax.swing.JCheckBox checkbox = new javax.swing.JCheckBox(Bundle.getMessage("HideFurtherWarnings")); 161 Object[] params = {Bundle.getMessage("ProgModeWarning"), checkbox}; 162 java.awt.event.ActionListener progPopUpCheckBox = (java.awt.event.ActionEvent evt) -> hideProgModeWarning(checkbox.isSelected()); 163 checkbox.addActionListener(progPopUpCheckBox); 164 JmriJOptionPane.showMessageDialogNonModal(null,params, 165 Bundle.getMessage("switchToProgMode"), 166 JmriJOptionPane.WARNING_MESSAGE, null); 167 }); 168 } 169 } 170 171 /** 172 * Receive notification from a mode switcher dialogue to display warning 173 * message about service mode programminf. 174 * False by default to show notifications 175 * 176 * @param hide set True to hide notifications, else False. 177 */ 178 public void hideProgModeWarning(boolean hide){ 179 _hideProgModeWarning = hide; 180 } 181 182 /** 183 * Define help menu for this window. 184 */ 185 protected void setHelp() { 186 addHelpMenu("package.jmri.jmrix.can.cbus.swing.modeswitcher.SprogCbusSimpleModeSwitcherFrame", true); // NOI18N 187 } 188 189 190 /** 191 * disconnect from the CBUS 192 */ 193 @Override 194 public void dispose() { 195 super.dispose(); 196 } 197 198 199 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SprogCbusSimpleModeSwitcherFrame.class); 200 201}