001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.demos.sandbox.video.gt;
031
032import java.awt.event.ActionEvent;
033import java.awt.event.ActionListener;
034import java.awt.event.ItemEvent;
035import java.awt.event.ItemListener;
036import java.util.ArrayList;
037import java.util.List;
038
039import javax.swing.AbstractButton;
040
041/**
042 * A replacement for the AWT ButtonGroup class.
043 * 
044 * @author David Dupplaw (dpd@ecs.soton.ac.uk)
045 * @created 17 Jul 2012
046 * @version $Author$, $Revision$, $Date$
047 */
048public class ButtonGroup 
049{
050        /** The buttons */
051        private final List<AbstractButton> buttons = new ArrayList<AbstractButton>();
052        
053        /** The listeners */
054        private final List<ItemListener> listeners = new ArrayList<ItemListener>();
055
056        /**
057         * Add a button
058         * 
059         * @param b
060         */
061        public void add(final AbstractButton b) {
062                this.buttons.add(b);
063                b.addActionListener(new ActionListener()
064                {
065                        @Override
066                        public void actionPerformed(final ActionEvent e)
067                        {
068                                ButtonGroup.this.updateButtons(b);
069                                ButtonGroup.this.fireListenerEvent( b );
070                        }
071                });
072        }
073
074        /**
075         * Remove the given button from the group.
076         * 
077         * @param b The button to remove
078         */
079        public void remove(final AbstractButton b) {
080                this.buttons.remove(b);
081        }
082
083        /**
084         * Make sure only the given button is selected.
085         * 
086         * @param b The button to select.
087         */
088        private void updateButtons(final AbstractButton b) {
089                for (final AbstractButton button : this.buttons)
090                        button.setSelected(button == b);
091        }
092
093        /**
094         * Returns the selected button in the group.
095         * 
096         * @return The selected button in the group or null if no buttons are
097         *         selected.
098         */
099        public AbstractButton getSelected() {
100                for (final AbstractButton button : this.buttons)
101                        if (button.isSelected())
102                                return button;
103                return null;
104        }
105
106        /**
107         * Sets all buttons in the group to unselected.
108         */
109        public void selectNone() {
110                for (final AbstractButton button : this.buttons)
111                        button.setSelected(false);
112        }
113
114        /**
115         * Set the selected button to the given one. Note that this method will
116         * select the button whether or not the button is in the button group.
117         * 
118         * @param b The button to select
119         */
120        public void setSelected(final AbstractButton b) {
121                b.setSelected(true);
122                this.updateButtons(b);
123        }
124        
125        /**
126         *      Add the given item listener to listen for button change events from
127         *      this button group.
128         *      @param il the item listener
129         */
130        public void addItemListener( final ItemListener il )
131        {
132                this.listeners.add( il );
133        }
134        
135        /**
136         *      Remove the given item listener from this button group.
137         *      @param il The item listener to remove.
138         */
139        public void removeItemListener( final ItemListener il )
140        {
141                this.listeners.remove( il );
142        }
143        
144        /**
145         *      Fire an itemStateChange event to the item listeners.
146         *      @param b The button that was selected
147         */
148        protected void fireListenerEvent( final AbstractButton b )
149        {
150                if( b.isSelected() )
151                        for( final ItemListener il : this.listeners )
152                        {
153                                final ItemEvent ie = new ItemEvent( b, b.hashCode(), b, 
154                                                ItemEvent.SELECTED );
155                                il.itemStateChanged( ie );
156                        }
157        }
158        
159        /**
160         *      Removes all the buttons being controlled by this button group.
161         */
162        public void clear()
163        {
164                this.buttons.clear();
165        }
166}