001 /*
002 * $Id: EnumComboBoxModel.java,v 1.5 2006/04/18 23:43:30 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 package org.jdesktop.swingx.combobox;
022
023 import java.util.ArrayList;
024 import java.util.EnumSet;
025 import java.util.List;
026 import javax.swing.AbstractListModel;
027 import javax.swing.BoxLayout;
028 import javax.swing.ComboBoxModel;
029 import javax.swing.JComboBox;
030 import javax.swing.JFrame;
031
032 /**
033 * <p>A ComboBoxModel implementation that safely wraps an Enum. It allows the
034 * developer to directly use an enum as their model for a combobox without any
035 * extra work, though the display can can be further customized. </p>
036 *
037 * <h4>Simple Usage</h4>
038 *
039 * <p>The simplest usage is to wrap an <code>enum</code> inside the
040 * <code>EnumComboBoxModel</code> and then set it as the model on the
041 * combo box. The combo box will then appear on screen with each value
042 * in the <code>enum</code> as a value in the combobox.
043 * </p>
044 * <p>ex:</p>
045 * <pre><code>
046 * enum MyEnum { GoodStuff, BadStuff };
047 * ...
048 * JComboBox combo = new JComboBox();
049 * combo.setModel(new EnumComboBoxModel(MyEnum.class));
050 * </code></pre>
051 *
052 * <h4>Type safe access</h4>
053 * <p>By using generics and co-variant types you can make accessing elements from the model
054 * be completely typesafe. ex:
055 *</p>
056 *
057 *<pre><code>
058 * EnumComboBoxModel<MyEnum> enumModel = new EnumComboBoxModel<MyEnum1>(MyEnum1.class);
059 * MyEnum first = enumModel.getElement(0);
060 * MyEnum selected = enumModel.getSelectedItem();
061 *</code></pre>
062 *
063 * <h4>Advanced Usage</h4>
064 * <p>Since the exact <code>toString()</code> value of each enum constant
065 * may not be exactly what you want on screen (the values
066 * won't have spaces, for example) you can override to
067 * toString() method on the values when you declare your
068 * enum. Thus the display value is localized to the enum
069 * and not in your GUI code. ex:
070 * <pre><code>
071 * private enum MyEnum {GoodStuff, BadStuff;
072 * public String toString() {
073 * switch(this) {
074 * case GoodStuff: return "Some Good Stuff";
075 * case BadStuff: return "Some Bad Stuff";
076 * }
077 * return "ERROR";
078 * }
079 * };
080 * </code></pre>
081 *
082 *
083 * @author joshy
084 */
085 public class EnumComboBoxModel<E extends Enum<E>>
086 extends AbstractListModel implements ComboBoxModel {
087 private E selected = null;
088 private List<E> list;
089
090 public EnumComboBoxModel(Class<E> en) {
091 EnumSet<E> ens = EnumSet.allOf(en);
092 list = new ArrayList<E>(ens);
093 selected = list.get(0);
094 }
095
096 public int getSize() {
097 return list.size();
098 }
099
100 public E getElementAt(int index) {
101 return list.get(index);
102 }
103
104 public void setSelectedItem(Object anItem) {
105 try {
106 selected = (E)anItem;
107 } catch (ClassCastException e) {
108 throw new IllegalArgumentException(anItem + " not of the expected type", e);
109 }
110 this.fireContentsChanged(this,0,getSize());
111 }
112
113 public E getSelectedItem() {
114 return selected;
115 }
116
117 /*
118 public static void main(String[] args) {
119 JFrame frame = new JFrame();
120 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
121 frame.setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.Y_AXIS));
122
123
124 JComboBox combo1 = new JComboBox();
125 combo1.setModel(new EnumComboBoxModel(MyEnum1.class));
126 frame.add(combo1);
127
128 JComboBox combo2 = new JComboBox();
129 combo2.setModel(new EnumComboBoxModel(MyEnum2.class));
130 frame.add(combo2);
131
132 EnumComboBoxModel<MyEnum1> enumModel = new EnumComboBoxModel<MyEnum1>(MyEnum1.class);
133 JComboBox combo3 = new JComboBox();
134 combo3.setModel(enumModel);
135 frame.add(combo3);
136
137 MyEnum1 selected = enumModel.getSelectedItem();
138
139 //uncomment to see the ClassCastException
140 // enumModel.setSelectedItem("Die clown");
141
142 frame.pack();
143 frame.setVisible(true);
144 }
145
146 private enum MyEnum1 {GoodStuff, BadStuff};
147 private enum MyEnum2 {GoodStuff, BadStuff;
148 public String toString() {
149 switch(this) {
150 case GoodStuff: return "Some Good Stuff";
151 case BadStuff: return "Some Bad Stuff";
152 }
153 return "ERROR";
154 }
155 };
156 */
157
158 }