001    /*
002     * $Id: JXRadioGroup.java,v 1.5 2005/10/10 18:01:54 rbair Exp $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     * 
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     * 
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    
022    package org.jdesktop.swingx;
023    
024    import java.awt.Component;
025    import java.awt.event.ActionEvent;
026    import java.awt.event.ActionListener;
027    import java.awt.event.ItemEvent;
028    import java.awt.event.ItemListener;
029    import java.util.ArrayList;
030    import java.util.List;
031    
032    import javax.swing.AbstractButton;
033    import javax.swing.Box;
034    import javax.swing.BoxLayout;
035    import javax.swing.ButtonGroup;
036    import javax.swing.ButtonModel;
037    import javax.swing.JPanel;
038    import javax.swing.JRadioButton;
039    
040    
041    /**
042     * @author Amy Fowler
043     * @version 1.0
044     */
045    
046    public class JXRadioGroup extends JPanel {
047        private static final long serialVersionUID = 3257285842266567986L;
048        private ButtonGroup buttonGroup;
049        private List<Object> values = new ArrayList<Object>();
050        private ActionSelectionListener actionHandler;
051        private List<ActionListener> actionListeners;
052        private int gapWidth;
053    
054        public JXRadioGroup() {
055            this(0);
056        }
057    
058        public JXRadioGroup(int gapWidth) {
059            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
060            buttonGroup = new ButtonGroup();
061            this.gapWidth = gapWidth;
062            
063        }
064        public JXRadioGroup(Object radioValues[]) {
065            this();
066            for(int i = 0; i < radioValues.length; i++) {
067                add(radioValues[i]);
068            }
069        }
070    
071        public void setValues(Object[] radioValues) {
072            clearAll();
073            for(int i = 0; i < radioValues.length; i++) {
074                add(radioValues[i]);
075            }
076        }
077        
078        private void clearAll() {
079            values.clear();
080            removeAll();
081            buttonGroup = new ButtonGroup();
082        }
083    
084        public void add(Object radioValue) {
085            values.add(radioValue);
086            addButton(new JRadioButton(radioValue.toString()));
087        }
088    
089        public void add(AbstractButton button) {
090            values.add(button.getText());
091            // PENDING: mapping needs cleanup...
092            addButton(button);
093        }
094    
095        private void addButton(AbstractButton button) {
096            buttonGroup.add(button);
097            super.add(button);
098            if (actionHandler == null) {
099                actionHandler = new ActionSelectionListener();
100    //            actionHandler = new ActionListener() {
101    //                public void actionPerformed(ActionEvent e) {
102    //                    fireActionEvent(e);
103    //                }
104    //            };
105            }
106            button.addActionListener(actionHandler);
107            button.addItemListener(actionHandler);
108        }
109    
110        private class ActionSelectionListener implements ActionListener,
111        ItemListener {
112    
113            public void actionPerformed(ActionEvent e) {
114                fireActionEvent(e);
115            
116            }
117            
118            public void itemStateChanged(ItemEvent e) {
119                fireActionEvent(null);
120            
121            }
122    
123    }
124       
125        private void checkGap() {
126            if ((getGapWidth() > 0) && (getComponentCount() > 0)) {
127                add(Box.createHorizontalStrut(getGapWidth()));
128            }
129        }
130    
131        private int getGapWidth() {
132            return gapWidth;
133        }
134    
135        public AbstractButton getSelectedButton() {
136            ButtonModel selectedModel = buttonGroup.getSelection();
137            AbstractButton children[] = getButtonComponents();
138            for(int i = 0; i < children.length; i++) {
139                AbstractButton button = (AbstractButton)children[i];
140                if (button.getModel() == selectedModel) {
141                    return button;
142                }
143            }
144            return null;
145        }
146    
147        private AbstractButton[] getButtonComponents() {
148            Component[] children = getComponents();
149            List buttons = new ArrayList();
150            for (int i = 0; i < children.length; i++) {
151                if (children[i] instanceof AbstractButton) {
152                    buttons.add(children[i]);
153                }
154            }
155            return (AbstractButton[]) buttons.toArray(new AbstractButton[buttons.size()]);
156        }
157    
158        private int getSelectedIndex() {
159            ButtonModel selectedModel = buttonGroup.getSelection();
160            Component children[] = getButtonComponents();
161            for (int i = 0; i < children.length; i++) {
162                AbstractButton button = (AbstractButton) children[i];
163                if (button.getModel() == selectedModel) {
164                    return i;
165                }
166            }
167            return -1;
168        }
169    
170        public Object getSelectedValue() {
171            int index = getSelectedIndex();
172            return (index < 0 || index >= values.size()) ? null : values.get(index);
173        }
174    
175        public void setSelectedValue(Object value) {
176            int index = values.indexOf(value);
177            AbstractButton button = getButtonComponents()[index];
178            button.setSelected(true);
179        }
180    
181        public void addActionListener(ActionListener l) {
182            if (actionListeners == null) {
183                actionListeners = new ArrayList<ActionListener>();
184            }
185            actionListeners.add(l);
186        }
187    
188        public void removeActionListener(ActionListener l) {
189            if (actionListeners != null) {
190                actionListeners.remove(l);
191            }
192        }
193    
194        public ActionListener[] getActionListeners() {
195            if (actionListeners != null) {
196                return (ActionListener[])actionListeners.toArray(new ActionListener[0]);
197            }
198            return new ActionListener[0];
199        }
200    
201        protected void fireActionEvent(ActionEvent e) {
202            if (actionListeners != null) {
203                for (int i = 0; i < actionListeners.size(); i++) {
204                    ActionListener l = (ActionListener) actionListeners.get(i);
205                    l.actionPerformed(e);
206                }
207            }
208        }
209    }