001package jmri.jmrit.symbolicprog;
002
003import java.awt.event.ActionListener;
004import java.beans.PropertyChangeListener;
005import java.util.Vector;
006import javax.swing.BoxLayout;
007import javax.swing.ButtonGroup;
008import javax.swing.JComboBox;
009import javax.swing.JPanel;
010import javax.swing.JRadioButton;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014/* Represents a JComboBox as a JPanel of radio buttons.
015 *
016 * @author   Bob Jacobsen   Copyright (C) 2001
017 */
018public class ComboRadioButtons extends JPanel {
019
020    ButtonGroup g = new ButtonGroup();
021
022    ComboRadioButtons(JComboBox<String> box, EnumVariableValue var) {
023        super();
024        _var = var;
025        _value = var._value;
026        _box = box;
027
028        init();
029    }
030
031    void init() {
032        l1 = new ActionListener[_box.getItemCount()];
033        b1 = new JRadioButton[_box.getItemCount()];
034
035        // create the buttons, include in group, listen for changes by name
036        for (int i = 0; i < _box.getItemCount(); i++) {
037            String name = _box.getItemAt(i);
038            JRadioButton b = new JRadioButton(name);
039            b1[i] = b;
040            b.setActionCommand(name);
041            b.addActionListener(l1[i] = new java.awt.event.ActionListener() {
042                @Override
043                public void actionPerformed(java.awt.event.ActionEvent e) {
044                    thisActionPerformed(e);
045                }
046            });
047            v.addElement(b);
048            addToPanel(b, i);
049            g.add(b);
050        }
051        setColor();
052        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
053        // listen for changes to original
054        _box.addActionListener(l2 = new java.awt.event.ActionListener() {
055            @Override
056            public void actionPerformed(java.awt.event.ActionEvent e) {
057                originalActionPerformed(e);
058            }
059        });
060        // listen for changes to original state
061        _var.addPropertyChangeListener(p1 = new java.beans.PropertyChangeListener() {
062            @Override
063            public void propertyChange(java.beans.PropertyChangeEvent e) {
064                originalPropertyChanged(e);
065            }
066        });
067
068        // set initial value
069        v.elementAt(_box.getSelectedIndex()).setSelected(true);
070    }
071
072    /**
073     * Add a button to the panel if desired. In this class, its always added,
074     * but in the On and Off subclasses, its only added for certain ones
075     * @param b Radio button to add
076     * @param i (Not used)
077     */
078    void addToPanel(JRadioButton b, int i) {
079        add(b);
080    }
081
082    void thisActionPerformed(java.awt.event.ActionEvent e) {
083        // update original state to selected button
084        _box.setSelectedItem(e.getActionCommand());
085    }
086
087    void originalActionPerformed(java.awt.event.ActionEvent e) {
088        // update this state to original state if there's a button
089        // that corresponds
090        while (_box.getSelectedIndex() + 1 >= v.size()) {
091            // oops - box has grown; add buttons!
092            JRadioButton b;
093            v.addElement(b = new JRadioButton("Reserved value " + v.size()));
094            g.add(b);
095        }
096        v.elementAt(_box.getSelectedIndex()).setSelected(true);
097    }
098
099    void originalPropertyChanged(java.beans.PropertyChangeEvent e) {
100        // update this color from original state
101        if (e.getPropertyName().equals("State")) {
102            if (log.isDebugEnabled()) {
103                log.debug("State change seen");
104            }
105            setColor();
106        }
107    }
108
109    protected void setColor() {
110        for (int i = 0; i < v.size(); i++) {
111            v.elementAt(i).setBackground(_value.getBackground());
112            v.elementAt(i).setOpaque(true);
113        }
114    }
115
116    /**
117     * Setting tooltip both on this panel, and all buttons inside
118     */
119    @Override
120    public void setToolTipText(String t) {
121        super.setToolTipText(t);   // do default stuff
122        // include all buttons
123        for (JRadioButton b : b1) {
124            b.setToolTipText(t);
125        }
126    }
127
128    JRadioButton b1[];
129    transient ActionListener l1[];
130    transient ActionListener l2;
131    transient PropertyChangeListener p1;
132
133    transient VariableValue _var = null;
134    transient JComboBox<String> _box = null;
135    transient JComboBox<?> _value = null;
136    Vector<JRadioButton> v = new Vector<JRadioButton>();
137
138    public void dispose() {
139        for (int i = 0; i < l1.length; i++) {
140            b1[i].removeActionListener(l1[i]);
141        }
142        _box.removeActionListener(l2);
143        _var.removePropertyChangeListener(p1);
144        _var = null;
145        _box = null;
146    }
147
148    // initialize logging
149    private final static Logger log = LoggerFactory.getLogger(ComboRadioButtons.class);
150
151}