updates for 0.9.4
[debian/openrocket] / src / net / sf / openrocket / gui / adaptors / EnumModel.java
1 package net.sf.openrocket.gui.adaptors;
2
3 import javax.swing.AbstractListModel;
4 import javax.swing.ComboBoxModel;
5 import javax.swing.event.ChangeEvent;
6 import javax.swing.event.ChangeListener;
7
8 import net.sf.openrocket.util.ChangeSource;
9 import net.sf.openrocket.util.Reflection;
10
11
12 public class EnumModel<T extends Enum<T>> extends AbstractListModel 
13                 implements ComboBoxModel, ChangeListener {
14
15         private final ChangeSource source;
16         private final String valueName;
17         private final String nullText;
18         
19         private final Enum<T>[] values;
20         private Enum<T> currentValue = null;
21         
22         private final Reflection.Method getMethod;
23         private final Reflection.Method setMethod;
24         
25         
26         
27         public EnumModel(ChangeSource source, String valueName) {
28                 this(source,valueName,null,null);
29         }
30         
31         public EnumModel(ChangeSource source, String valueName, Enum<T>[] values) {
32                 this(source, valueName, values, null);
33         }
34         
35         @SuppressWarnings("unchecked")
36         public EnumModel(ChangeSource source, String valueName, Enum<T>[] values, String nullText) {
37                 Class<? extends Enum<T>> enumClass;
38                 this.source = source;
39                 this.valueName = valueName;
40                 
41                 try {
42                         java.lang.reflect.Method getM = source.getClass().getMethod("get" + valueName);
43                         enumClass = (Class<? extends Enum<T>>) getM.getReturnType();
44                         if (!enumClass.isEnum()) {
45                                 throw new IllegalArgumentException("Return type of get" + valueName +
46                                                 " not an enum type");
47                         }
48                         
49                         getMethod = new Reflection.Method(getM);
50                         setMethod = new Reflection.Method(source.getClass().getMethod("set" + valueName,
51                                         enumClass));
52                 } catch (NoSuchMethodException e) {
53                         throw new IllegalArgumentException("get/is methods for enum '"+valueName+
54                                         "' not present in class "+source.getClass().getCanonicalName());
55                 }
56                 
57                 if (values != null)
58                         this.values = values;
59                 else 
60                         this.values = enumClass.getEnumConstants();
61                 
62                 this.nullText = nullText;
63                 
64                 stateChanged(null);  // Update current value
65                 source.addChangeListener(this);
66         }
67
68         
69                 
70         @Override
71         public Object getSelectedItem() {
72                 if (currentValue==null)
73                         return nullText;
74                 return currentValue;
75         }
76
77         @Override
78         public void setSelectedItem(Object item) {
79                 if (item instanceof String) {
80                         if (currentValue != null)
81                                 setMethod.invoke(source, (Object)null);
82                         return;
83                 }
84                 
85                 if (!(item instanceof Enum<?>)) {
86                         throw new IllegalArgumentException("Not String or Enum, item="+item);
87                 }
88                 
89                 // Comparison with == ok, since both are enums
90                 if (currentValue == item)
91                         return;
92                 setMethod.invoke(source, item);
93         }
94
95         @Override
96         public Object getElementAt(int index) {
97                 if (values[index] == null)
98                         return nullText;
99                 return values[index];
100         }
101
102         @Override
103         public int getSize() {
104                 return values.length;
105         }
106
107
108
109
110
111         @SuppressWarnings("unchecked")
112         @Override
113         public void stateChanged(ChangeEvent e) {
114                 Enum<T> value = (Enum<T>) getMethod.invoke(source);
115                 if (value != currentValue) {
116                         currentValue = value;
117                         this.fireContentsChanged(this, 0, values.length);
118                 }
119         }
120         
121         
122
123         @Override
124         public String toString() {
125                 return "EnumModel["+source.getClass().getCanonicalName()+":"+valueName+"]";
126         }
127
128 }