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