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