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