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