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 }