View Javadoc

1   /***
2    * JMultistateButton.java
3    *
4    * This file is part of the creme library.
5    * The creme library intends to ease the development effort of large
6    * applications by providing easy to use support classes.
7    *
8    * Copyright (C) 2003 Denis Bregeon
9    *
10   * This library is free software; you can redistribute it and/or
11   * modify it under the terms of the GNU Lesser General Public
12   * License as published by the Free Software Foundation; either
13   * version 2.1 of the License, or (at your option) any later version.
14   *
15   * This library is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18   * Lesser General Public License for more details.
19   *
20   * You should have received a copy of the GNU Lesser General Public
21   * License along with this library; if not, write to the Free Software
22   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23   *
24   * contact information: dbregeon@sourceforge.net
25   */
26  package org.jcreme.swing;
27  
28  import java.awt.event.ItemEvent;
29  import java.awt.event.ItemListener;
30  import java.text.Format;
31  import java.util.Arrays;
32  import java.util.Vector;
33  
34  import javax.swing.DefaultButtonModel;
35  import javax.swing.Icon;
36  import javax.swing.JButton;
37  
38  /***
39   * This class models a button associated to a list of values. Pressing the
40   * button enables to go through the list, the label displayed on the button
41   * changing accordingly. This may be used to represent short lists (2 to 4
42   * items) as an extension of the ToggleButtons.
43   * 
44   * @author $Author: dbregeon $
45   * @version $Revision: 1.1 $
46   */
47  public class JMultistateButton extends JButton {
48      /***
49       * The Format used to display String representations of the values.
50       */
51      private Format formatter = null;
52  
53      /***
54       * The IconSelector used to display String representations of the values.
55       */
56      private IconSelector iconSelector = null;
57  
58      private final ItemListener modelListener = new ItemListener() {
59          public void itemStateChanged(ItemEvent e) {
60              if (e.getStateChange() == ItemEvent.SELECTED) {
61                  Object selection = e.getItem();
62                  if (e != null) {
63                      String text = null;
64                      Icon icon = null;
65                      if (getFormatter() != null) {
66                          text = getFormatter().format(selection);
67                      } else {
68                          text = selection.toString();
69                      }
70                      if (getIconSelector() != null) {
71                          icon = getIconSelector().getIcon(selection);
72                      }
73                      setText(text);
74                      setIcon(icon);
75                  }
76              }
77          }
78      };
79  
80      /***
81       * Creates a JMultistateButton using the given Vector as values.
82       * 
83       * @param values
84       *            the Objects that are selected through actions on the button.
85       */
86      public JMultistateButton(Vector values) {
87          setModel(new MultistateButtonModel(values));
88          getModel().addItemListener(this.modelListener);
89      }
90  
91      /***
92       * Creates a JMultistateButton using the given array as values.
93       * 
94       * @param values
95       *            the Objects that are selected through actions on the button.
96       */
97      public JMultistateButton(Object[] values) {
98          this(new Vector(Arrays.asList(values)));
99      }
100 
101     /***
102      * This method enables to change the currently selected value of the button.
103      * 
104      * @param item
105      *            the value to select.
106      */
107     public void setSelectedItem(Object item) {
108         if (getModel() instanceof MultistateButtonModel) {
109             ((MultistateButtonModel) getModel()).setSelectedValue(item);
110         }
111     }
112 
113     /***
114      * This method enables to access the value currently selected in the button.
115      * 
116      * @return the current selection. Null if the selection is empty.
117      */
118     public Object getSelectionItem() {
119         Object result = null;
120         if (getModel() instanceof MultistateButtonModel) {
121             result = ((MultistateButtonModel) getModel()).getSelectedValue();
122         }
123         return result;
124     }
125 
126     /***
127      * This method enables to modify the formatter used to create the text of
128      * the button label. By default, the String representation of the selected
129      * value will be used.
130      * 
131      * @param f
132      *            a Format implementation for the values in the button.
133      */
134     public void setFormatter(Format f) {
135         this.formatter = f;
136     }
137 
138     /***
139      * This method enables to access the Format implementation currently in in
140      * use to display the values.
141      * 
142      * @return the Format instance currently in use. Null is none has been set.
143      */
144     public Format getFormatter() {
145         return this.formatter;
146     }
147 
148     /***
149      * This method enables to provide an IconSelector for the button. The icons
150      * provided by this selector will be used when displaying a value.
151      * 
152      * @param s
153      *            An IconSelector instance.
154      */
155     public void setIconSelector(IconSelector s) {
156         this.iconSelector = s;
157     }
158 
159     /***
160      * This method enables to access the current IconSelector in use in this
161      * button.
162      * 
163      * @return the current IconSelector. Null if none was set.
164      */
165     public IconSelector getIconSelector() {
166         return this.iconSelector;
167     }
168 
169     /***
170      * This interface describes a way to select an Icon from a value. It is used
171      * to enable JMultistateButton to display an Icon associated to the
172      * selectedValue.
173      * 
174      * @author $Author: dbregeon $
175      * @version $Revision: 1.1 $
176      */
177     public interface IconSelector {
178         /***
179          * Retrieves an Icon associated to the value.
180          * 
181          * @param value
182          *            any Object.
183          * @return the Icon associated to this value. Null if no Icon was was
184          *         associated to the given value.
185          */
186         public Icon getIcon(Object value);
187     }
188 
189     /***
190      * 
191      * 
192      * @author $Author: dbregeon $
193      * @version $Revision: 1.1 $
194      */
195     public class MultistateButtonModel extends DefaultButtonModel {
196         protected Vector values = new Vector();
197 
198         protected Object selectedValue = null;
199 
200         protected int eventId = 0;
201 
202         /***
203          * 
204          * @param v
205          */
206         public MultistateButtonModel(Vector v) {
207             if (v != null) {
208                 this.values = (Vector) v.clone();
209             }
210         }
211 
212         /***
213          * 
214          * @param value
215          */
216         public void setSelectedValue(Object value) {
217             fireItemStateChanged(new ItemEvent(this, this.eventId++,
218                     this.selectedValue, ItemEvent.DESELECTED));
219             this.selectedValue = value;
220             fireItemStateChanged(new ItemEvent(this, this.eventId++,
221                     this.selectedValue, ItemEvent.SELECTED));
222         }
223 
224         /***
225          * 
226          * @return the currently selected value for the Button.
227          */
228         public Object getSelectedValue() {
229             return this.selectedValue;
230         }
231 
232         /***
233          * @see javax.swing.ButtonModel#setPressed(boolean)
234          */
235         public void setPressed(boolean b) {
236             super.setPressed(b);
237             if (isArmed() && isPressed()) {
238                 int index = 0;
239                 if (this.selectedValue != null) {
240                     index = this.values.indexOf(this.selectedValue);
241                 }
242                 if ((index >= 0) && (index < this.values.size() - 1)) {
243                     index++;
244                 } else {
245                     index = 0;
246                 }
247                 setSelectedItem(this.values.elementAt(index));
248             }
249         }
250 
251     }
252 }