001package jmri.jmrit.simpleturnoutctrl;
002
003import java.awt.GridBagConstraints;
004import java.awt.GridBagLayout;
005
006import javax.swing.BorderFactory;
007import javax.swing.BoxLayout;
008import javax.swing.JButton;
009import javax.swing.JLabel;
010import javax.swing.JPanel;
011
012import jmri.InstanceManager;
013import jmri.Turnout;
014
015/**
016 * Frame to control a single turnout.
017 *
018 * @author Bob Jacobsen Copyright (C) 2001
019 */
020public class SimpleTurnoutCtrlFrame extends jmri.util.JmriJFrame implements java.beans.PropertyChangeListener {
021
022    private static final String LOCKED = Bundle.getMessage("Locked");
023    private static final String UNLOCKED = Bundle.getMessage("Normal");
024
025    // GUI member declarations
026    private final javax.swing.JTextField adrTextField = new javax.swing.JTextField(8);
027
028    private final JButton throwButton = new JButton();
029    private final JButton closeButton = new JButton();
030
031    private final JLabel nowStateLabel = new JLabel();
032
033    private final JLabel nowFeedbackLabel = new JLabel();
034
035    private final JLabel lockButtonLabel = new JLabel();
036    private final JButton lockButton = new JButton();
037
038    private final JLabel lockPushButtonLabel = new JLabel();
039    private final JButton lockPushButton = new JButton();
040
041    public SimpleTurnoutCtrlFrame() {
042        super();
043
044        // configure items for GUI        
045        adrTextField.setText("");
046        adrTextField.setVisible(true);
047        adrTextField.setToolTipText(Bundle.getMessage("AddressToolTip"));
048
049        throwButton.setText(InstanceManager.turnoutManagerInstance().getThrownText());
050        throwButton.setVisible(true);
051        throwButton.setToolTipText(Bundle.getMessage("ThrowButtonToolTip",
052                InstanceManager.turnoutManagerInstance().getThrownText()));
053        throwButton.addActionListener(this::throwButtonActionPerformed);
054
055        closeButton.setText(InstanceManager.turnoutManagerInstance().getClosedText());
056        closeButton.setVisible(true);
057        closeButton.setToolTipText(Bundle.getMessage("ThrowButtonToolTip",
058                InstanceManager.turnoutManagerInstance().getClosedText()));
059        closeButton.addActionListener(this::closeButtonActionPerformed);
060
061        nowStateLabel.setText(Bundle.getMessage("BeanStateUnknown"));
062        nowStateLabel.setVisible(true);
063
064        nowFeedbackLabel.setText(Bundle.getMessage("BeanStateUnknown"));
065        nowFeedbackLabel.setVisible(true);
066
067        lockButtonLabel.setText(Bundle.getMessage("LockButtonLabel") + " ");
068        lockButtonLabel.setVisible(true);
069
070        lockButton.setText(UNLOCKED);
071        lockButton.setVisible(true);
072        lockButton.setEnabled(false);
073        lockButton.setToolTipText(Bundle.getMessage("LockButtonToolTip"));
074        lockButton.addActionListener(this::lockButtonActionPerformed);
075
076        lockPushButtonLabel.setText(Bundle.getMessage("PushButtonLabel"));
077        lockPushButtonLabel.setVisible(true);
078
079        lockPushButton.setText(UNLOCKED);
080        lockPushButton.setVisible(true);
081        lockPushButton.setEnabled(false);
082        lockPushButton.setToolTipText(Bundle.getMessage("PushButtonToolTip"));
083        lockPushButton.addActionListener(this::lockPushButtonActionPerformed);
084        // general GUI config
085        setTitle(Bundle.getMessage("FrameTitle"));
086        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
087        GridBagConstraints c = new GridBagConstraints();
088        c.gridwidth = 1;
089        c.gridheight = 1;
090        c.weightx = 1.0;
091
092        // install items in GUI
093        JPanel tPanel = new JPanel();
094        tPanel.setLayout(new GridBagLayout());
095        tPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BeanNameTurnout") + " "));
096
097        c.gridx = 0;
098        c.gridy = 0;
099        c.anchor = GridBagConstraints.EAST;
100        tPanel.add(adrTextField, c);
101
102        c.gridx = 0;
103        c.gridy = 1;
104        c.anchor = GridBagConstraints.EAST;
105        tPanel.add(throwButton, c);
106        c.gridx = 2;
107        c.anchor = GridBagConstraints.WEST;
108        tPanel.add(closeButton, c);
109
110        JPanel sPanel = new JPanel();
111        sPanel.setLayout(new GridBagLayout());
112        sPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("CurrentStateTitle") + " "));
113
114        sPanel.add(nowStateLabel);
115
116        JPanel fPanel = new JPanel();
117        fPanel.setLayout(new GridBagLayout());
118        fPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("FeedbackModeTitle") + " "));
119
120        fPanel.add(nowFeedbackLabel);
121
122        JPanel avPanel = new JPanel();
123        avPanel.setLayout(new GridBagLayout());
124        avPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("AdvancedFeaturesTitle") + " "));
125
126        c.gridx = 0;
127        c.gridy = 5;
128        c.anchor = GridBagConstraints.EAST;
129        avPanel.add(lockButtonLabel, c);
130        c.gridx = 1;
131        c.anchor = GridBagConstraints.WEST;
132        avPanel.add(lockButton, c);
133
134        c.gridx = 0;
135        c.gridy = 6;
136        c.anchor = GridBagConstraints.EAST;
137        avPanel.add(lockPushButtonLabel, c);
138        c.gridx = 1;
139        c.anchor = GridBagConstraints.WEST;
140        avPanel.add(lockPushButton, c);
141
142        getContentPane().add(tPanel);
143        getContentPane().add(sPanel);
144        getContentPane().add(fPanel);
145        getContentPane().add(avPanel);
146
147        // add help menu to window
148        addHelpMenu("package.jmri.jmrit.simpleturnoutctrl.SimpleTurnoutCtrl", true);
149
150        pack();
151    }
152
153    public void closeButtonActionPerformed(java.awt.event.ActionEvent e) {
154        // load address from switchAddrTextField
155        if (adrTextField.getText().length() < 1) {
156            nowStateLabel.setText(Bundle.getMessage("NoAddressHint"));
157            return;
158        }
159        try {
160            if (turnout != null) {
161                turnout.removePropertyChangeListener(this);
162            }
163            turnout = InstanceManager.turnoutManagerInstance().provideTurnout(
164                    adrTextField.getText());
165
166            turnout.addPropertyChangeListener(this);
167
168            log.debug("about to command CLOSED");
169            // and set commanded state to CLOSED
170            turnout.setCommandedState(Turnout.CLOSED);
171
172            updateTurnoutStatusFields();
173
174        } catch (IllegalArgumentException ex1) {
175            invalidTurnout(adrTextField.getText(), ex1);
176        } catch (Exception ex2) {
177            log.error("exception during closeButtonActionPerformed", ex2); // NOI18N
178            nowStateLabel.setText(Bundle.getMessage("ErrorTitle"));
179            nowFeedbackLabel.setText(Bundle.getMessage("BeanStateUnknown"));
180        }
181    }
182
183    public void throwButtonActionPerformed(java.awt.event.ActionEvent e) {
184        // load address from switchAddrTextField
185        if (adrTextField.getText().length() < 1) {
186            nowStateLabel.setText(Bundle.getMessage("NoAddressHint"));
187            return;
188        }
189        try {
190            if (turnout != null) {
191                turnout.removePropertyChangeListener(this);
192            }
193            turnout = InstanceManager.turnoutManagerInstance().provideTurnout(
194                    adrTextField.getText());
195
196            turnout.addPropertyChangeListener(this);
197
198            log.debug("about to command THROWN");
199            // and set commanded state to THROWN
200            turnout.setCommandedState(Turnout.THROWN);
201            
202            updateTurnoutStatusFields();
203            
204        } catch (IllegalArgumentException ex1) {
205            invalidTurnout(adrTextField.getText(), ex1);
206        } catch (Exception ex2) {
207            log.error("exception during throwButtonActionPerformed", ex2); // NOI18N
208            nowStateLabel.setText(Bundle.getMessage("ErrorTitle"));
209            nowFeedbackLabel.setText(Bundle.getMessage("BeanStateUnknown"));
210        }
211    }
212
213    public void lockButtonActionPerformed(java.awt.event.ActionEvent e) {
214        // load address from switchAddrTextField
215        try {
216            if (turnout != null) {
217                turnout.removePropertyChangeListener(this);
218            }
219            turnout = InstanceManager.turnoutManagerInstance().provideTurnout(
220                    adrTextField.getText());
221
222            turnout.addPropertyChangeListener(this);
223            updateTurnoutStatusFields();
224
225            if (lockButton.getText().equals(LOCKED)) {
226                turnout.setLocked(Turnout.CABLOCKOUT, false);
227            } else if (turnout.canLock(Turnout.CABLOCKOUT)) {
228                turnout.setLocked(Turnout.CABLOCKOUT, true);
229            }
230        } catch (IllegalArgumentException ex1) {
231            invalidTurnout(adrTextField.getText(), ex1);
232        } catch (Exception ex2) {
233            log.error("exception during lockButtonActionPerformed", ex2); // NOI18N
234            nowStateLabel.setText(Bundle.getMessage("ErrorTitle"));
235            nowFeedbackLabel.setText(Bundle.getMessage("BeanStateUnknown"));
236        }
237    }
238
239    public void lockPushButtonActionPerformed(java.awt.event.ActionEvent e) {
240        // load address from switchAddrTextField
241        try {
242            if (turnout != null) {
243                turnout.removePropertyChangeListener(this);
244            }
245
246            turnout = InstanceManager.turnoutManagerInstance().provideTurnout(
247                    adrTextField.getText());
248            turnout.addPropertyChangeListener(this);
249            updateTurnoutStatusFields();
250
251            if (lockPushButton.getText().equals(LOCKED)) {
252                turnout.setLocked(Turnout.PUSHBUTTONLOCKOUT, false);
253            } else if (turnout.canLock(Turnout.PUSHBUTTONLOCKOUT)) {
254                turnout.setLocked(Turnout.PUSHBUTTONLOCKOUT, true);
255            }
256        } catch (IllegalArgumentException ex1) {
257            invalidTurnout(adrTextField.getText(), ex1);
258        } catch (Exception ex2) {
259            log.error("exception during lockPushButtonActionPerformed", ex2); // NOI18N
260            nowStateLabel.setText(Bundle.getMessage("ErrorTitle"));
261            nowFeedbackLabel.setText(Bundle.getMessage("BeanStateUnknown"));
262        }
263    }
264
265    /**
266     * Update state field in GUI as state of turnout changes.
267     * @param e The Event received from the Turnout.
268     */
269    @Override
270    public void propertyChange(java.beans.PropertyChangeEvent e) {
271        // If the Commanded State changes, show transition state as "<inconsistent>" 
272        if ( Turnout.PROPERTY_COMMANDED_STATE.equals(e.getPropertyName())) {
273            nowStateLabel.setText(Bundle.getMessage("BeanStateInconsistent"));
274        }
275        if ( Turnout.PROPERTY_KNOWN_STATE.equals(e.getPropertyName())) {
276            int now = ((Integer) e.getNewValue());
277            switch (now) {
278                case Turnout.UNKNOWN:
279                    nowStateLabel.setText(Bundle.getMessage("BeanStateUnknown"));
280                    return;
281                case Turnout.CLOSED:
282                    nowStateLabel.setText(InstanceManager.turnoutManagerInstance().getClosedText());
283                    return;
284                case Turnout.THROWN:
285                    nowStateLabel.setText(InstanceManager.turnoutManagerInstance().getThrownText());
286                    return;
287                default:
288                    nowStateLabel.setText(Bundle.getMessage("BeanStateInconsistent"));
289                    return;
290            }
291        }
292        if ( Turnout.PROPERTY_LOCKED.equals(e.getPropertyName())) {
293            if (turnout.canLock(Turnout.CABLOCKOUT)) {
294                if (turnout.getLocked(Turnout.CABLOCKOUT)) {
295                    lockButton.setText(LOCKED);
296                } else {
297                    lockButton.setText(UNLOCKED);
298                }
299                lockButton.setEnabled(true);
300            } else {
301                lockButton.setText(UNLOCKED);
302                lockButton.setEnabled(false);
303            }
304            if (turnout.canLock(Turnout.PUSHBUTTONLOCKOUT)) {
305                if (turnout.getLocked(Turnout.PUSHBUTTONLOCKOUT)) {
306                    lockPushButton.setText(LOCKED);
307                } else {
308                    lockPushButton.setText(UNLOCKED);
309                }
310                lockPushButton.setEnabled(true);
311            } else {
312                lockPushButton.setText(UNLOCKED);
313                lockPushButton.setEnabled(false);
314            }
315        }
316        if (e.getPropertyName().equals("feedbackchange")) { // NOI18N
317            updateTurnoutStatusFields();
318        }
319    }
320
321    private void updateTurnoutStatusFields() {
322
323        nowFeedbackLabel.setText(turnout.getFeedbackModeName());
324        if (turnout.canLock(Turnout.CABLOCKOUT)) {
325            if (turnout.getLocked(Turnout.CABLOCKOUT)) {
326                lockButton.setText(LOCKED);
327            } else {
328                lockButton.setText(UNLOCKED);
329            }
330            lockButton.setEnabled(true);
331        } else {
332            lockButton.setText(UNLOCKED);
333            lockButton.setEnabled(false);
334        }
335        if (turnout.canLock(Turnout.PUSHBUTTONLOCKOUT)) {
336            if (turnout.getLocked(Turnout.PUSHBUTTONLOCKOUT)) {
337                lockPushButton.setText(LOCKED);
338            } else {
339                lockPushButton.setText(UNLOCKED);
340            }
341            lockPushButton.setEnabled(true);
342        } else {
343            lockPushButton.setText(UNLOCKED);
344            lockPushButton.setEnabled(false);
345        }
346        int knownState = turnout.getKnownState();
347        switch (knownState) {
348            case Turnout.UNKNOWN:
349                nowStateLabel.setText(Bundle.getMessage("BeanStateUnknown"));
350                return;
351            case Turnout.CLOSED:
352                nowStateLabel.setText(InstanceManager.turnoutManagerInstance().getClosedText());
353                return;
354            case Turnout.THROWN:
355                nowStateLabel.setText(InstanceManager.turnoutManagerInstance().getThrownText());
356                return;
357            default:
358                nowStateLabel.setText(Bundle.getMessage("BeanStateInconsistent"));
359        }
360    }
361
362    void invalidTurnout(String name, Exception ex) {
363        InstanceManager.getDefault(jmri.UserPreferencesManager.class)
364                .showErrorMessage(this, Bundle.getMessage("ErrorTitle"),
365                        (Bundle.getMessage("ErrorConvertHW", name)),
366                        ex.toString(), "", true, false);
367    }
368
369    private Turnout turnout = null;
370
371    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SimpleTurnoutCtrlFrame.class);
372
373}