html updates + version number 1.1.1pre
[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 == null) {
80                         // Clear selection - huh?
81                         return;
82                 }
83                 if (item instanceof String) {
84                         if (currentValue != null)
85                                 setMethod.invoke(source, (Object)null);
86                         return;
87                 }
88                 
89                 if (!(item instanceof Enum<?>)) {
90                         throw new IllegalArgumentException("Not String or Enum, item="+item);
91                 }
92                 
93                 // Comparison with == ok, since both are enums
94                 if (currentValue == item)
95                         return;
96                 setMethod.invoke(source, item);
97         }
98
99         @Override
100         public Object getElementAt(int index) {
101                 if (values[index] == null)
102                         return nullText;
103                 return values[index];
104         }
105
106         @Override
107         public int getSize() {
108                 return values.length;
109         }
110
111
112
113
114
115         @SuppressWarnings("unchecked")
116         @Override
117         public void stateChanged(ChangeEvent e) {
118                 Enum<T> value = (Enum<T>) getMethod.invoke(source);
119                 if (value != currentValue) {
120                         currentValue = value;
121                         this.fireContentsChanged(this, 0, values.length);
122                 }
123         }
124         
125         
126
127         @Override
128         public String toString() {
129                 return "EnumModel["+source.getClass().getCanonicalName()+":"+valueName+"]";
130         }
131
132 }