001package jmri.jmrit.throttle.preferences; 002 003import java.awt.*; 004import java.awt.event.ActionEvent; 005import java.awt.event.ActionListener; 006import java.io.File; 007import java.io.IOException; 008 009import javax.swing.*; 010 011import jmri.InstanceManager; 012import jmri.jmrit.throttle.LoadXmlThrottlesLayoutAction; 013import jmri.jmrit.throttle.implementation.ThrottleUICore; 014import jmri.util.swing.JmriJOptionPane; 015 016import org.jdom2.Element; 017import org.jdom2.JDOMException; 018 019/** 020 * A preferences panel to display and edit JMRI throttle preferences 021 * 022 * @author Lionel Jeanson - 2009 - 2021 023 * 024 */ 025public class ThrottlesPreferencesUISettingsPane extends JPanel { 026 027 private JCheckBox cbUseToolBar; 028 private JCheckBox cbUseFunctionIcon; 029 private JCheckBox cbUseLargeSpeedSlider; 030 private JCheckBox cbResizeWinImg; 031 private JCheckBox cbUseExThrottle; 032 private JCheckBox cbUseRosterImage; 033 private JCheckBox cbEnableRosterSearch; 034 private JCheckBox cbEnableAutoLoad; 035 private JCheckBox cbHideUndefinedButtons; 036 private JCheckBox cbHideSpeedSelector; 037 private JCheckBox cbIgnoreThrottlePosition; 038 private JCheckBox cbSaveThrottleOnLayoutSave; 039 private JCheckBox cbAddressSelectorShowingAllRosterGroup; 040 private JCheckBox cbSilentSteal; 041 private JCheckBox cbSilentShare; 042 private JTextField tfDefaultThrottleLocation; 043 private boolean isDirty = false; 044 045 /** 046 * Creates new form ThrottlesPreferencesPane 047 * @param tp the throttle preferences to init the component 048 */ 049 public ThrottlesPreferencesUISettingsPane(ThrottlesPreferences tp) { 050 initComponents(); 051 resetComponents(tp); 052 checkConsistancy(); 053 } 054 055 private void initComponents() { 056 057 cbUseExThrottle = new JCheckBox(); 058 cbUseToolBar = new JCheckBox(); 059 cbUseFunctionIcon = new JCheckBox(); 060 cbUseLargeSpeedSlider = new JCheckBox(); 061 cbUseRosterImage = new JCheckBox(); 062 cbResizeWinImg = new JCheckBox(); 063 cbEnableRosterSearch = new JCheckBox(); 064 cbEnableAutoLoad = new JCheckBox(); 065 cbHideUndefinedButtons = new JCheckBox(); 066 cbHideSpeedSelector = new JCheckBox(); 067 cbAddressSelectorShowingAllRosterGroup = new JCheckBox(); 068 cbIgnoreThrottlePosition = new JCheckBox(); 069 cbSaveThrottleOnLayoutSave = new JCheckBox(); 070 cbSilentSteal = new JCheckBox(); 071 cbSilentShare = new JCheckBox(); 072 tfDefaultThrottleLocation = new JTextField(); 073 074 cbUseExThrottle.setText(Bundle.getMessage("UseExThrottle")); 075 cbResizeWinImg.setText(Bundle.getMessage("ExThrottleForceResize")); 076 cbUseToolBar.setText(Bundle.getMessage("ExThrottleUseToolBar")); 077 cbUseFunctionIcon.setText(Bundle.getMessage("ExThrottleUseFunctionIcons")); 078 cbUseLargeSpeedSlider.setText(Bundle.getMessage("ExThrottleUseLargeSpeedSlider")); 079 cbUseRosterImage.setText(Bundle.getMessage("ExThrottleUseRosterImageBkg")); 080 cbEnableRosterSearch.setText(Bundle.getMessage("ExThrottleEnableRosterSearch")); 081 cbEnableAutoLoad.setText(Bundle.getMessage("ExThrottleEnableAutoSave")); 082 cbHideUndefinedButtons.setText(Bundle.getMessage("ExThrottleHideUndefinedFunctionButtons")); 083 cbHideSpeedSelector.setText(Bundle.getMessage("ExThrottleCheckBoxHideSpeedStepSelector")); 084 cbAddressSelectorShowingAllRosterGroup.setText(Bundle.getMessage("ExThrottleCheckBoxAddressSelectorShowingAllRosterGroup")); 085 cbIgnoreThrottlePosition.setText(Bundle.getMessage("ExThrottleIgnoreThrottlePosition")); 086 cbSaveThrottleOnLayoutSave.setText(Bundle.getMessage("ExThrottleSaveThrottleOnLayoutSave")); 087 cbSilentSteal.setText(Bundle.getMessage("ExThrottleSilentSteal")); 088 cbSilentShare.setText(Bundle.getMessage("ExThrottleSilentShare")); 089 090 ActionListener dirtyAL = (ActionEvent evt) -> { 091 isDirty = true; 092 }; 093 cbUseExThrottle.addActionListener(dirtyAL); 094 cbResizeWinImg.addActionListener(dirtyAL); 095 cbUseToolBar.addActionListener(dirtyAL); 096 cbUseFunctionIcon.addActionListener(dirtyAL); 097 cbUseLargeSpeedSlider.addActionListener(dirtyAL); 098 cbUseRosterImage.addActionListener(dirtyAL); 099 cbEnableRosterSearch.addActionListener(dirtyAL); 100 cbEnableAutoLoad.addActionListener(dirtyAL); 101 cbHideUndefinedButtons.addActionListener(dirtyAL); 102 cbHideSpeedSelector.addActionListener(dirtyAL); 103 cbAddressSelectorShowingAllRosterGroup.addActionListener(dirtyAL); 104 cbIgnoreThrottlePosition.addActionListener(dirtyAL); 105 cbSaveThrottleOnLayoutSave.addActionListener(dirtyAL); 106 cbSilentSteal.addActionListener(dirtyAL); 107 cbSilentShare.addActionListener(dirtyAL); 108 109 ActionListener al = (ActionEvent evt) -> { 110 checkConsistancy(); 111 }; 112 cbUseExThrottle.addActionListener(al); 113 cbUseToolBar.addActionListener(al); 114 cbUseRosterImage.addActionListener(al); 115 cbEnableAutoLoad.addActionListener(al); 116 117 // only the steal checkbox OR the share checkbox should be selected 118 ActionListener stealCheck = (ActionEvent evt) -> { 119 checkStealButtonOk(); 120 }; 121 ActionListener shareCheck = (ActionEvent evt) -> { 122 checkShareButtonOk(); 123 }; 124 cbSilentSteal.addActionListener(stealCheck); 125 cbSilentShare.addActionListener(shareCheck); 126 127 ActionListener tal = (ActionEvent evt) -> { 128 checkDefaultThrottleFile(); 129 }; 130 tfDefaultThrottleLocation.addActionListener(tal); 131 132 setLayout(new GridBagLayout()); 133 134 GridBagConstraints constraints = new GridBagConstraints(); 135 constraints.anchor = GridBagConstraints.WEST; 136 constraints.fill = GridBagConstraints.HORIZONTAL; 137 constraints.gridheight = 1; 138 constraints.gridwidth = 1; 139 constraints.ipadx = 5; 140 constraints.ipady = 5; 141 Insets x0 = new Insets(2, 2, 2, 2); 142 Insets x1 = new Insets(2, 18, 2, 2); 143 Insets x2 = new Insets(2, 32, 2, 2); 144 constraints.insets = x0; 145 constraints.weightx = 1; 146 constraints.weighty = 1; 147 148 constraints.gridx = 0; 149 constraints.gridy = 0; 150 this.add(cbUseExThrottle, constraints); 151 152 constraints.gridy++; 153 constraints.insets = x1; 154 this.add(cbSaveThrottleOnLayoutSave, constraints); 155 156 constraints.gridy++; 157 this.add(cbUseRosterImage, constraints); 158 159 constraints.gridy++; 160 constraints.insets = x2; 161 this.add(cbResizeWinImg, constraints); 162 163 constraints.gridy++; 164 constraints.insets = x1; 165 this.add(cbEnableRosterSearch, constraints); 166 167 constraints.gridy++; 168 this.add(cbEnableAutoLoad, constraints); 169 170 constraints.gridy++; 171 constraints.insets = x2; 172 this.add(cbIgnoreThrottlePosition, constraints); 173 174 constraints.gridy++; 175 constraints.insets = x1; 176 this.add(cbHideUndefinedButtons, constraints); 177 178 constraints.gridy++; 179 this.add(cbUseToolBar, constraints); 180 181 constraints.gridy++; 182 this.add(cbHideSpeedSelector, constraints); 183 184 constraints.gridy++; 185 this.add(cbAddressSelectorShowingAllRosterGroup, constraints); 186 187 constraints.gridy++; 188 this.add(cbUseFunctionIcon, constraints); 189 190 constraints.gridy++; 191 this.add(cbUseLargeSpeedSlider, constraints); 192 193 constraints.gridy++; 194 constraints.insets = x0; 195 this.add(new JSeparator(),constraints ); 196 constraints.gridy++; 197 this.add(cbSilentSteal,constraints ); 198 199 constraints.gridy++; 200 this.add(cbSilentShare,constraints ); 201 202 constraints.gridy++; 203 this.add(new JSeparator(),constraints ); 204 205 constraints.gridy++; 206 this.add(defaultThrottleLocationPanel(), constraints); 207 208 if (InstanceManager.getNullableDefault(jmri.ThrottleManager.class) != null) { 209 cbSilentSteal.setEnabled(InstanceManager.throttleManagerInstance().enablePrefSilentStealOption()); 210 cbSilentShare.setEnabled(InstanceManager.throttleManagerInstance().enablePrefSilentShareOption()); 211 } 212 213 } 214 215 public final void resetComponents(ThrottlesPreferences tp) { 216 if (tp == null) { 217 return; 218 } 219 cbSaveThrottleOnLayoutSave.setSelected(tp.isSavingThrottleOnLayoutSave()); 220 cbResizeWinImg.setSelected(tp.isResizingWindow()); 221 cbUseToolBar.setSelected(tp.isUsingToolBar()); 222 cbUseFunctionIcon.setSelected(tp.isUsingFunctionIcon()); 223 cbUseRosterImage.setSelected(tp.isUsingRosterImage()); 224 cbUseExThrottle.setSelected(tp.isUsingExThrottle()); 225 cbEnableRosterSearch.setSelected(tp.isEnablingRosterSearch()); 226 cbEnableAutoLoad.setSelected(tp.isAutoLoading()); 227 cbHideUndefinedButtons.setSelected(tp.isHidingUndefinedFuncButt()); 228 cbHideSpeedSelector.setSelected(tp.isHidingSpeedStepSelector()); 229 cbAddressSelectorShowingAllRosterGroup.setSelected(tp.isAddressSelectorShowingAllRosterGroup()); 230 cbIgnoreThrottlePosition.setSelected(tp.isIgnoringThrottlePosition()); 231 cbUseLargeSpeedSlider.setSelected(tp.isUsingLargeSpeedSlider()); 232 cbSilentSteal.setSelected(tp.isSilentSteal()); 233 cbSilentShare.setSelected(tp.isSilentShare()); 234 tfDefaultThrottleLocation.setText(tp.getDefaultThrottleFilePath()); 235 checkConsistancy(); 236 isDirty = false; 237 } 238 239 public ThrottlesPreferences updateThrottlesPreferences(ThrottlesPreferences tp) { 240 tp.setUseExThrottle(cbUseExThrottle.isSelected()); 241 tp.setUsingToolBar(cbUseToolBar.isSelected()); 242 tp.setUsingFunctionIcon(cbUseFunctionIcon.isSelected()); 243 tp.setResizeWindow(cbResizeWinImg.isSelected()); 244 tp.setUseRosterImage(cbUseRosterImage.isSelected()); 245 tp.setSaveThrottleOnLayoutSave(cbSaveThrottleOnLayoutSave.isSelected()); 246 tp.setSilentSteal(cbSilentSteal.isSelected()); 247 tp.setSilentShare(cbSilentShare.isSelected()); 248 tp.setEnableRosterSearch(cbEnableRosterSearch.isSelected()); 249 tp.setAutoLoad(cbEnableAutoLoad.isSelected()); 250 tp.setHideUndefinedFuncButt(cbHideUndefinedButtons.isSelected()); 251 tp.setHideSpeedStepSelector(cbHideSpeedSelector.isSelected()); 252 tp.setAddressSelectorShowingAllRosterGroup(cbAddressSelectorShowingAllRosterGroup.isSelected()); 253 tp.setIgnoreThrottlePosition(cbIgnoreThrottlePosition.isSelected()); 254 tp.setUseLargeSpeedSlider(cbUseLargeSpeedSlider.isSelected()); 255 tp.setDefaultThrottleFilePath(tfDefaultThrottleLocation.getText()); 256 return tp; 257 } 258 259 private void checkConsistancy() { 260 cbSaveThrottleOnLayoutSave.setEnabled(cbUseExThrottle.isSelected()); 261 cbUseToolBar.setEnabled(cbUseExThrottle.isSelected()); 262 cbUseFunctionIcon.setEnabled(cbUseExThrottle.isSelected()); 263 cbEnableRosterSearch.setEnabled(cbUseExThrottle.isSelected()); 264 cbEnableAutoLoad.setEnabled(cbUseExThrottle.isSelected()); 265 cbUseRosterImage.setEnabled(cbUseExThrottle.isSelected()); 266 cbResizeWinImg.setEnabled(cbUseExThrottle.isSelected() && cbUseRosterImage.isSelected()); 267 cbHideUndefinedButtons.setEnabled(cbUseExThrottle.isSelected()); 268 cbHideSpeedSelector.setEnabled(cbUseExThrottle.isSelected()); 269 cbAddressSelectorShowingAllRosterGroup.setEnabled(cbUseExThrottle.isSelected()); 270 cbIgnoreThrottlePosition.setEnabled(cbUseExThrottle.isSelected() && cbEnableAutoLoad.isSelected()); 271 cbUseLargeSpeedSlider.setEnabled(cbUseExThrottle.isSelected()); 272 if (cbUseExThrottle.isSelected()) { 273 if (cbUseToolBar.isSelected()) { 274 cbIgnoreThrottlePosition.setSelected(true); 275 cbIgnoreThrottlePosition.setEnabled(false); 276 } 277 } 278 } 279 280 private void checkStealButtonOk() { 281 if (cbSilentShare.isSelected()){ 282 cbSilentShare.setSelected(false); 283 } 284 } 285 286 private void checkShareButtonOk() { 287 if (cbSilentSteal.isSelected()){ 288 cbSilentSteal.setSelected(false); 289 } 290 } 291 292 private void checkDefaultThrottleFile() { 293 boolean isBad = false; 294 try { 295 LoadXmlThrottlesLayoutAction.ThrottlePrefs prefs = new LoadXmlThrottlesLayoutAction.ThrottlePrefs(); 296 Element root = prefs.rootFromFile(new File (tfDefaultThrottleLocation.getText())); 297 // simply test for root element 298 299 if (root == null || (root.getChildren("ThrottleFrame").size() != 1)) { 300 isBad = true; 301 } 302 } catch (IOException | JDOMException ex) { 303 isBad = true; 304 } 305 if (isBad) { 306 tfDefaultThrottleLocation.setText(null); 307 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("DefaultThrottleFileNotValid"), 308 Bundle.getMessage("DefaultThrottleFile"), JmriJOptionPane.ERROR_MESSAGE); 309 } 310 } 311 312 private JPanel defaultThrottleLocationPanel() { 313 final JFileChooser fileChooser = jmri.jmrit.XmlFile.userFileChooser(Bundle.getMessage("PromptXmlFileTypes"), "xml"); 314 fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); 315 fileChooser.setDialogTitle(Bundle.getMessage("MessageSelectDefaultThrottleFile")); 316 317 JButton bScript = new JButton(Bundle.getMessage("ButtonSetDots")); 318 bScript.addActionListener(new ThrottlesPreferencesUISettingsPane.OpenAction(fileChooser, tfDefaultThrottleLocation)); 319 JPanel p = new JPanel(new BorderLayout()); 320 p.add(new JLabel(Bundle.getMessage("DefaultThrottleFile")), BorderLayout.LINE_START); 321 p.add(tfDefaultThrottleLocation, BorderLayout.CENTER); 322 p.add(bScript, BorderLayout.LINE_END); 323 324 return p; 325 } 326 327 boolean isDirty() { 328 return isDirty; 329 } 330 331 private class OpenAction extends AbstractAction { 332 333 JFileChooser chooser; 334 JTextField field; 335 private boolean firstOpen = true; 336 337 OpenAction(JFileChooser chooser, JTextField field) { 338 this.chooser = chooser; 339 this.field = field; 340 } 341 342 @Override 343 public void actionPerformed(ActionEvent e) { 344 if ( firstOpen ) { 345 chooser.setCurrentDirectory(new File(ThrottleUICore.getDefaultThrottleFolder())); 346 firstOpen = false; 347 } 348 // get the file 349 int retVal = chooser.showOpenDialog(field); 350 if ( (retVal != JFileChooser.APPROVE_OPTION) || (chooser.getSelectedFile() == null) ) { 351 return; // cancelled 352 } 353 field.setText(chooser.getSelectedFile().toString()); 354 checkDefaultThrottleFile(); 355 } 356 } 357 358 // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ThrottlesPreferencesUISettingsPane.class); 359 360}