move gui to another source package
[sw/motorsim] / gui / com / billkuker / rocketry / motorsim / visual / Editor.java
1 package com.billkuker.rocketry.motorsim.visual;\r
2 \r
3 import java.awt.Component;\r
4 import java.awt.Dimension;\r
5 import java.beans.IntrospectionException;\r
6 import java.beans.Introspector;\r
7 import java.beans.PropertyChangeEvent;\r
8 import java.beans.PropertyChangeListener;\r
9 import java.beans.PropertyDescriptor;\r
10 import java.beans.PropertyEditorManager;\r
11 import java.beans.PropertyEditorSupport;\r
12 import java.text.DecimalFormat;\r
13 import java.text.NumberFormat;\r
14 import java.util.Vector;\r
15 \r
16 import javax.measure.unit.SI;\r
17 import javax.measure.unit.Unit;\r
18 import javax.swing.JFrame;\r
19 import javax.swing.JLabel;\r
20 import javax.swing.JTable;\r
21 import javax.swing.JTextField;\r
22 import javax.swing.WindowConstants;\r
23 import javax.swing.table.TableCellRenderer;\r
24 \r
25 import org.apache.log4j.Logger;\r
26 import org.jscience.physics.amount.Amount;\r
27 \r
28 import com.billkuker.rocketry.motorsim.CylindricalChamber;\r
29 import com.l2fprod.common.propertysheet.PropertySheetPanel;\r
30 \r
31 public class Editor extends PropertySheetPanel {\r
32         private static final long serialVersionUID = 1L;\r
33         private static final NumberFormat nf = new DecimalFormat("##########.###");\r
34         private static final Logger log = Logger.getLogger(Editor.class);\r
35 \r
36         private Object obj;\r
37 \r
38         @SuppressWarnings("deprecation")\r
39         public Editor(Object o) {\r
40                 obj = o;\r
41 \r
42                 PropertyEditorManager.registerEditor(Amount.class,\r
43                                 AmountPropertyEditor.class);\r
44                 \r
45                 setToolBarVisible(false);\r
46                 //setMinimumSize(new Dimension(150,200));\r
47                 \r
48                 getRendererRegistry().registerRenderer(Amount.class, AmountRenderer.class);\r
49 \r
50                 // Build the list of properties we want it to edit\r
51                 //final PropertySheetPanel ps = new PropertySheetPanel();\r
52                 PropertyDescriptor props[];\r
53                 try {\r
54                         props = Introspector.getBeanInfo(obj.getClass())\r
55                                         .getPropertyDescriptors();\r
56                 } catch (IntrospectionException e) {\r
57                         throw new Error(e);\r
58                 }\r
59                 Vector<PropertyDescriptor> v = new Vector<PropertyDescriptor>();\r
60                 for (int i = 0; i < props.length; i++) {\r
61                         if (props[i].getName().equals("class"))\r
62                                 continue;\r
63                         v.add(props[i]);\r
64                 }\r
65                 setProperties(v.toArray(new PropertyDescriptor[v.size()]));\r
66 \r
67                 readFromObject(obj);\r
68                 \r
69                 getTable().setRowHeight(22);\r
70                 \r
71                 setMinimumSize(new Dimension(\r
72                                 getTable().getPreferredSize().width,\r
73                                 getTable().getPreferredSize().height + 10));\r
74 \r
75                 addPropertySheetChangeListener(new PropertyChangeListener() {\r
76 \r
77                         public void propertyChange(PropertyChangeEvent evt) {\r
78                                 // When something changes just update the\r
79                                 // object, I want the changes to be immediate.\r
80                                 try {\r
81                                         log.debug("Writing properties to object.");\r
82                                         writeToObject(obj);\r
83                                 } catch (Exception v) {\r
84                                         // TODO\r
85                                         v.printStackTrace();\r
86                                         java.awt.Toolkit.getDefaultToolkit().beep();\r
87                                 } finally {\r
88                                         readFromObject(obj);\r
89                                 }\r
90                         }\r
91 \r
92                 });\r
93         }\r
94 \r
95         public void showAsWindow() {\r
96                 JFrame f = new JFrame();\r
97                 f.setTitle(obj.getClass().getName());\r
98                 f.setSize(600, 400);\r
99                 f.setContentPane(this);\r
100                 f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);\r
101                 f.setVisible(true);\r
102         }\r
103         \r
104         public static void main(String args[]){\r
105                 CylindricalChamber o = new CylindricalChamber();\r
106                 o.setLength(Amount.valueOf(100.5, SI.MILLIMETER));\r
107                 o.setID(Amount.valueOf(30, SI.MILLIMETER));\r
108                 Editor e = new Editor(o);\r
109                 e.showAsWindow();\r
110         }\r
111         \r
112         public static class AmountRenderer implements TableCellRenderer {\r
113                 @Override\r
114                 public Component getTableCellRendererComponent(JTable table,\r
115                                 Object value, boolean isSelected, boolean hasFocus, int row,\r
116                                 int column) {\r
117                         Amount a = (Amount)value;\r
118                         return new JLabel(nf.format(a.doubleValue(a.getUnit())) + " " + a.getUnit() );\r
119                 }\r
120                 \r
121         }\r
122 \r
123         public static class AmountPropertyEditor extends PropertyEditorSupport {\r
124                 JTextField editor = new JTextField();\r
125                 Unit<?> oldUnit;\r
126 \r
127                 @Override\r
128                 public boolean supportsCustomEditor() {\r
129                         return true;\r
130                 }\r
131 \r
132                 @Override\r
133                 public String getAsText() {\r
134                         return editor.getText();\r
135                 }\r
136 \r
137                 @Override\r
138                 public Object getValue() {\r
139                         String text = editor.getText().trim();\r
140 \r
141                         // Trying to determine if the value is integer or\r
142                         // has a decimal part will prevent the uncertainty\r
143                         // term from appearing when user types an exact value\r
144                         try {\r
145                                 try {\r
146                                         return Amount.valueOf(Integer.parseInt(text), oldUnit);\r
147                                 } catch (NumberFormatException e) {\r
148 \r
149                                 }\r
150                                 Amount<?> a = Amount.valueOf(Double.parseDouble(text), oldUnit);\r
151                                 return a;\r
152                         } catch (NumberFormatException e) {\r
153                                 // Storing the old unit allows you to type 10 into a field\r
154                                 // that says 20 mm and get 10 mm, so you dont have to\r
155                                 // type the unit if they havn't changed.\r
156                                 \r
157                                 //Amount wants a leading 0\r
158                                 if (text.startsWith(".")){\r
159                                         text = "0" + text;\r
160                                 }\r
161                                 \r
162                                 Amount<?> a = Amount.valueOf(text);\r
163                                 oldUnit = a.getUnit();\r
164                                 return a;\r
165                         }\r
166 \r
167                 }\r
168 \r
169                 @SuppressWarnings("unchecked")\r
170                 @Override\r
171                 public void setValue(Object o) {\r
172                         Amount a = (Amount) o;\r
173                         oldUnit = a.getUnit();\r
174 \r
175                         String text;\r
176                         //Leave off the fractional part if it is not relevant\r
177                         if (a.isExact())\r
178                                 text = a.getExactValue() + " " + a.getUnit();\r
179                         else\r
180                                 text = nf.format(a.doubleValue(a.getUnit())) + " " + a.getUnit();\r
181 \r
182                         setAsText(text);\r
183                 }\r
184 \r
185                 @Override\r
186                 public void setAsText(String text) throws IllegalArgumentException {\r
187                         editor.setText(text);\r
188                 };\r
189 \r
190                 @Override\r
191                 public Component getCustomEditor() {\r
192                         return editor;\r
193                 }\r
194         }\r
195 \r
196 }\r