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