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