001package jmri.jmrit.vsdecoder.swing;
002
003import java.awt.GridBagConstraints;
004import java.awt.GridBagLayout;
005import java.awt.Insets;
006import java.beans.PropertyChangeEvent;
007import java.beans.PropertyChangeListener;
008import javax.swing.BorderFactory;
009import javax.swing.JButton;
010import javax.swing.JFileChooser;
011import javax.swing.JFrame;
012import javax.swing.JPanel;
013import jmri.jmrit.vsdecoder.VSDecoderManager;
014import jmri.jmrit.vsdecoder.VSDecoderPreferences;
015
016/**
017 * Pane to show VSDecoder Preferences.
018 *
019 * <hr>
020 * This file is part of JMRI.
021 * <p>
022 * JMRI is free software; you can redistribute it and/or modify it under
023 * the terms of version 2 of the GNU General Public License as published
024 * by the Free Software Foundation. See the "COPYING" file for a copy
025 * of this license.
026 * <p>
027 * JMRI is distributed in the hope that it will be useful, but WITHOUT
028 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
029 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
030 * for more details.
031 *
032 * @author Mark Underwood Copyright (C) 2011
033 */
034class VSDecoderPreferencesPane extends JPanel implements PropertyChangeListener {
035
036    private javax.swing.JCheckBox cbAutoStartEngine;
037    private javax.swing.JCheckBox cbAutoLoadVSDFile;
038    private javax.swing.JCheckBox cbUseBlocks;
039    private javax.swing.JTextField tfDefaultVSDFilePath;
040    private javax.swing.JLabel labelDefaultVSDFilePath;
041
042    private javax.swing.JButton jbApply;
043    private javax.swing.JButton jbCancel;
044    private javax.swing.JButton jbSave;
045    private JFrame m_container = null;
046
047    /**
048     * Creates new form VSDecoderPreferencesPane
049     * @param tp Preferences information
050     */
051    public VSDecoderPreferencesPane(VSDecoderPreferences tp) {
052        initComponents();
053        setComponents(tp);
054        tp.addPropertyChangeListener(this);
055    }
056
057    public VSDecoderPreferencesPane() {
058        this(VSDecoderManager.instance().getVSDecoderPreferences());
059    }
060
061    private GridBagConstraints setConstraints(Insets i, int x, int y, int width, int fill) {
062        GridBagConstraints gbc = new GridBagConstraints();
063        gbc.insets = i;
064        gbc.gridx = x;
065        gbc.gridy = y;
066        gbc.gridwidth = width;
067        gbc.anchor = GridBagConstraints.LINE_START;
068        gbc.fill = fill;
069        return gbc;
070    }
071
072    private void initComponents() {
073
074        JPanel prefsPane = new JPanel();
075        JPanel controlPane = new JPanel();
076
077        this.setLayout(new GridBagLayout());
078        this.setBorder(BorderFactory.createEmptyBorder());
079
080        jbCancel = new javax.swing.JButton();
081        jbSave = new javax.swing.JButton();
082        jbApply = new javax.swing.JButton();
083
084        labelDefaultVSDFilePath = new javax.swing.JLabel();
085
086        cbAutoStartEngine = new javax.swing.JCheckBox();
087        cbAutoLoadVSDFile = new javax.swing.JCheckBox();
088        cbUseBlocks       = new javax.swing.JCheckBox();
089        tfDefaultVSDFilePath = new javax.swing.JTextField(40);
090        JButton jbPathBrowse = new javax.swing.JButton(Bundle.getMessage("Browse"));
091        jbPathBrowse.addActionListener(new java.awt.event.ActionListener() {
092            @Override
093            public void actionPerformed(java.awt.event.ActionEvent evt) {
094                jbPathBrowseActionPerformed(evt);
095            }
096        });
097
098        // Get label strings from the resource bundle and assign it.
099        cbAutoStartEngine.setText(Bundle.getMessage("AutoStartEngine"));
100        cbAutoLoadVSDFile.setText(Bundle.getMessage("AutoLoadVSDFile"));
101        cbUseBlocks.setText(Bundle.getMessage("UseBlocks"));
102        tfDefaultVSDFilePath.setColumns(30);
103        labelDefaultVSDFilePath.setText(Bundle.getMessage("DefaultVSDFilePath"));
104
105        // Set action listeners for save / cancel / reset buttons
106        jbSave.setText(Bundle.getMessage("ButtonSave"));
107        jbSave.addActionListener(new java.awt.event.ActionListener() {
108            @Override
109            public void actionPerformed(java.awt.event.ActionEvent evt) {
110                jbSaveActionPerformed(evt);
111            }
112        });
113        jbSave.setVisible(false);
114
115        jbCancel.setText(Bundle.getMessage("ButtonCancel"));
116        jbCancel.addActionListener(new java.awt.event.ActionListener() {
117            @Override
118            public void actionPerformed(java.awt.event.ActionEvent evt) {
119                jbCancelActionPerformed(evt);
120            }
121        });
122
123        jbApply.setText(Bundle.getMessage("ButtonApply"));
124        jbApply.addActionListener(new java.awt.event.ActionListener() {
125            @Override
126            public void actionPerformed(java.awt.event.ActionEvent evt) {
127                jbApplyActionPerformed(evt);
128            }
129        });
130
131        prefsPane.setLayout(new GridBagLayout());
132        prefsPane.setBorder(BorderFactory.createEmptyBorder());
133        controlPane.setLayout(new GridBagLayout());
134        controlPane.setBorder(BorderFactory.createEmptyBorder());
135
136        prefsPane.add(cbAutoStartEngine, setConstraints(new Insets(2, 10, 2, 2), 0, 0, 2, GridBagConstraints.NONE)); //1
137        prefsPane.add(cbAutoLoadVSDFile, setConstraints(new Insets(2, 10, 2, 2), 0, 1, 2, GridBagConstraints.NONE)); //2
138        prefsPane.add(cbUseBlocks, setConstraints(new Insets(2, 10, 2, 2), 0, 2, 2, GridBagConstraints.NONE)); //3
139
140        prefsPane.add(labelDefaultVSDFilePath, setConstraints(new Insets(2, 10, 2, 2), 0, 3, 1, GridBagConstraints.NONE)); //4
141        prefsPane.add(tfDefaultVSDFilePath, setConstraints(new Insets(2, 10, 2, 2), 1, 3, 3, GridBagConstraints.HORIZONTAL)); //4
142        prefsPane.add(jbPathBrowse, setConstraints(new Insets(2, 2, 2, 2), 5, 3, 1, GridBagConstraints.NONE)); //4
143
144        controlPane.add(jbSave, setConstraints(new Insets(5, 3, 5, 2), 2, 100, 1, GridBagConstraints.NONE)); //5
145        controlPane.add(jbCancel, setConstraints(new Insets(5, 3, 5, 2), 0, 100, 1, GridBagConstraints.NONE)); //6
146        controlPane.add(jbApply, setConstraints(new Insets(5, 3, 5, 5), 1, 100, 1, GridBagConstraints.NONE)); //7
147
148        this.add(prefsPane, setConstraints(new Insets(2, 2, 2, 2), 0, 0, 1, GridBagConstraints.NONE));
149        this.add(controlPane, setConstraints(new Insets(2, 2, 2, 2), 0, 1, 1, GridBagConstraints.NONE));
150
151        this.setVisible(true);
152    }
153
154    private void setComponents(VSDecoderPreferences tp) {
155        if (tp == null) {
156            return;
157        }
158        cbAutoStartEngine.setSelected(tp.isAutoStartingEngine());
159        cbAutoLoadVSDFile.setSelected(tp.isAutoLoadingVSDFile());
160        cbUseBlocks.setSelected(tp.getUseBlocksSetting());
161        tfDefaultVSDFilePath.setText(tp.getDefaultVSDFilePath());
162    }
163
164    private VSDecoderPreferences getVSDecoderPreferences() {
165        VSDecoderPreferences tp = new VSDecoderPreferences();
166        tp.setAutoStartEngine(cbAutoStartEngine.isSelected());
167        tp.setAutoLoadVSDFile(cbAutoLoadVSDFile.isSelected());
168        tp.setUseBlocksSetting(cbUseBlocks.isSelected());
169        tp.setDefaultVSDFilePath(tfDefaultVSDFilePath.getText());
170        tp.setListenerPosition(VSDecoderManager.instance().getVSDecoderPreferences().getListenerPosition());
171        tp.setMasterVolume(VSDecoderManager.instance().getVSDecoderPreferences().getMasterVolume());
172        return tp;
173    }
174
175    private void jbPathBrowseActionPerformed(java.awt.event.ActionEvent evt) {
176        // Browse for a path.  Update the UI
177        // use the path currently in the window text field, if possible.
178        String path;
179        if (tfDefaultVSDFilePath.getText() != null) {
180            path = tfDefaultVSDFilePath.getText();
181        } else {
182            path = VSDecoderManager.instance().getVSDecoderPreferences().getDefaultVSDFilePath();
183        }
184        final JFileChooser fc = new jmri.util.swing.JmriJFileChooser(jmri.util.FileUtil.getExternalFilename(path));
185        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
186        int rv = fc.showOpenDialog(this);
187        if (rv == JFileChooser.APPROVE_OPTION) {
188            try {
189                tfDefaultVSDFilePath.setText(fc.getSelectedFile().getCanonicalPath());
190            } catch (java.io.IOException e) {
191                // do nothing.
192            }
193        }
194    }
195
196    private void jbApplyActionPerformed(java.awt.event.ActionEvent evt) {
197        VSDecoderManager.instance().getVSDecoderPreferences().set(getVSDecoderPreferences());
198    }
199
200    private void jbSaveActionPerformed(java.awt.event.ActionEvent evt) {
201        VSDecoderManager.instance().getVSDecoderPreferences().set(getVSDecoderPreferences());
202        VSDecoderManager.instance().getVSDecoderPreferences().save();
203        if (m_container != null) {
204            VSDecoderManager.instance().getVSDecoderPreferences().removePropertyChangeListener(this);
205            m_container.setVisible(false); // should do with events...
206            m_container.dispose();
207        }
208    }
209
210    private void jbCancelActionPerformed(java.awt.event.ActionEvent evt) {
211        setComponents(VSDecoderManager.instance().getVSDecoderPreferences());
212        if (m_container != null) {
213            VSDecoderManager.instance().getVSDecoderPreferences().removePropertyChangeListener(this);
214            m_container.setVisible(false); // should do with events...
215            m_container.dispose();
216        }
217    }
218
219    public void setContainer(JFrame f) {
220        m_container = f;
221        jbSave.setVisible(true);
222        jbCancel.setText(Bundle.getMessage("ButtonCancel"));
223    }
224
225    @Override
226    public void propertyChange(PropertyChangeEvent evt) {
227        if ((evt == null) || (evt.getPropertyName() == null)) {
228            return;
229        }
230        if (evt.getPropertyName().equals("VSDecoderPreferences")) {
231            if ((evt.getNewValue() != null) && (evt.getNewValue() instanceof VSDecoderPreferences)) {
232                setComponents((VSDecoderPreferences) evt.getNewValue());
233            }
234        }
235    }
236
237}