001package jmri.jmrit.symbolicprog;
002
003import java.awt.Color;
004import java.awt.Component;
005import java.util.ArrayList;
006import java.util.HashMap;
007import java.util.List;
008import javax.swing.JCheckBox;
009import javax.swing.JComboBox;
010import javax.swing.JLabel;
011import javax.swing.JRadioButton;
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015/**
016 * Extends VariableValue to represent a constant enum-like-thing.
017 * Note that there's no CV associated with this.
018 *
019 * @author Bob Jacobsen Copyright (C) 2001
020 */
021public class ConstantValue extends VariableValue {
022
023    public ConstantValue(String name, String comment, String cvName,
024            boolean readOnly, boolean infoOnly, boolean writeOnly, boolean opsOnly,
025            String cvNum, String mask, int minVal, int maxVal,
026            HashMap<String, CvValue> v, JLabel status, String stdname) {
027        super(name, comment, cvName, readOnly, infoOnly, writeOnly, opsOnly, cvNum, mask, v, status, stdname);
028        _maxVal = maxVal;
029        _minVal = minVal;
030        _value = new JComboBox<Integer>();
031        for (int i = 0; i <= maxVal; i++) {
032            _value.addItem(i);
033        }
034        // simplifyMask(); // not required as mask is ignored
035    }
036
037    /**
038     * Create a null object. Normally only used for tests and to pre-load
039     * classes.
040     */
041    public ConstantValue() {
042    }
043
044    @Override
045    public CvValue[] usesCVs() {
046        return new CvValue[]{};
047    }
048
049    /**
050     * Provide a user-readable description of the CVs accessed by this variable.
051     */
052    @Override
053    public String getCvDescription() {
054        return null;
055    }
056
057    // stored value
058    JComboBox<Integer> _value = null;
059
060    @Override
061    public void setToolTipText(String t) {
062        super.setToolTipText(t);   // do default stuff
063        _value.setToolTipText(t);  // set our value
064    }
065
066    // place to keep the items
067    String[] _itemArray = null;
068    int _nstored;
069
070    private int _maxVal;
071    private int _minVal;
072    Color _defaultColor;
073
074    @Override
075    public Object rangeVal() {
076        return "constant: " + _minVal + " - " + _maxVal;
077    }
078
079    // to complete this class, fill in the routines to handle "Value" parameter
080    // and to read/write/hear parameter changes.
081    @Override
082    public String getValueString() {
083        return "" + _value.getSelectedIndex();
084    }
085
086    @Override
087    public void setIntValue(int i) {
088        _value.setSelectedIndex(i);  // automatically fires a change event
089    }
090
091    @Override
092    public int getIntValue() {
093        return _value.getSelectedIndex();
094    }
095
096    @Override
097    public Object getValueObject() {
098        return _value.getSelectedIndex();
099    }
100
101    @Override
102    public Component getCommonRep() {
103        return _value;
104    }
105
106    public void setValue(int value) {
107        int oldVal = _value.getSelectedIndex();
108        _value.setSelectedIndex(value);
109        if (oldVal != value || getState() == ValueState.UNKNOWN) {
110            prop.firePropertyChange("Value", null, value);
111        }
112    }
113
114    @Override
115    public Component getNewRep(String format) {
116        // sort on format type
117        if (format.equals("checkbox")) {
118            // this only makes sense if there are exactly two options
119            JCheckBox b = new JCheckBox();
120            b.setEnabled(false);
121            b.setSelected((getIntValue() == 1));
122            comboCBs.add(b);
123            updateRepresentation(b);
124            return b;
125        } else if (format.equals("radiobuttons")) {
126            JRadioButton b = new JRadioButton();
127            comboRBs.add(b);
128            updateRepresentation(b);
129            return b;
130        } else if (format.equals("onradiobutton")) {
131            JRadioButton b = new JRadioButton();
132            comboRBs.add(b);
133            updateRepresentation(b);
134            return b;
135        } else if (format.equals("offradiobutton")) {
136            JRadioButton b = new JRadioButton();
137            comboRBs.add(b);
138            updateRepresentation(b);
139            return b;
140        } else {
141            log.error("Did not recognize a value format: {}", format);
142            return null;
143        }
144    }
145
146    List<JCheckBox> comboCBs = new ArrayList<JCheckBox>();
147    List<JRadioButton> comboRBs = new ArrayList<JRadioButton>();
148
149    // implement an abstract member to set colors
150    @Override
151    void setColor(Color c) {
152    }
153
154    /**
155     * No connected CV, so this notify does nothing
156     *
157     */
158    @Override
159    public void setCvState(ValueState state) {
160    }
161
162    @Override
163    public boolean isChanged() {
164        return false;
165    }
166
167    @Override
168    public void setToRead(boolean state) {
169    }
170
171    @Override
172    public boolean isToRead() {
173        return false;
174    }
175
176    @Override
177    public void setToWrite(boolean state) {
178    }
179
180    @Override
181    public boolean isToWrite() {
182        return false;
183    }
184
185    @Override
186    public void readChanges() {
187        if (isChanged()) {
188            readAll();
189        }
190    }
191
192    @Override
193    public void writeChanges() {
194        if (isChanged()) {
195            writeAll();
196        }
197    }
198
199    /**
200     * Skip actually reading, but set states and notifications anyway.
201     * <p>
202     * This sets the state to READ so that you can have algorithms like "write
203     * all variables that aren't in READ state" This is different from the
204     * 'normal' VariableValue objects, which rely on the associated CV objects
205     * to drive state changes at the end of the write.
206     */
207    @Override
208    public void readAll() {
209        log.debug("read invoked");
210        setToRead(false);
211        setState(ValueState.READ);
212        setBusy(true);
213        setBusy(false);
214    }
215
216    /**
217     * Skip actually writing, but set states and notifications anyway.
218     * <p>
219     * This sets the state to STORED so that you can have algorithms like "write
220     * all variables that aren't in STORED state" This is different from the
221     * 'normal' VariableValue objects, which rely on the associated CV objects
222     * to drive state changes at the end of the write.
223     */
224    @Override
225    public void writeAll() {
226        log.debug("write invoked");
227        setToWrite(false);
228        setState(ValueState.STORED);
229        setBusy(true);
230        setBusy(false);
231    }
232
233    @Override
234    public void propertyChange(java.beans.PropertyChangeEvent e) {
235        log.warn("Unexpected propertyChange: {}", e);
236    }
237
238    // clean up connections when done
239    @Override
240    public void dispose() {
241        log.debug("dispose");
242
243        _value = null;
244        // do something about the VarComboBox
245    }
246
247    // initialize logging
248    private final static Logger log = LoggerFactory.getLogger(ConstantValue.class);
249
250}