Fixed some warnings
[sw/motorsim] / gui / com / billkuker / rocketry / motorsim / visual / workbench / SRFuelEditor.java
1 package com.billkuker.rocketry.motorsim.visual.workbench;
2
3 import java.awt.Dimension;
4 import java.awt.FlowLayout;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.beans.PropertyChangeEvent;
8 import java.text.DecimalFormat;
9 import java.text.NumberFormat;
10 import java.util.Collections;
11 import java.util.Vector;
12
13 import javax.measure.quantity.Pressure;
14 import javax.measure.quantity.Velocity;
15 import javax.measure.quantity.VolumetricDensity;
16 import javax.measure.unit.SI;
17 import javax.swing.ButtonGroup;
18 import javax.swing.JButton;
19 import javax.swing.JFrame;
20 import javax.swing.JPanel;
21 import javax.swing.JRadioButton;
22 import javax.swing.JScrollPane;
23 import javax.swing.JSplitPane;
24 import javax.swing.JTable;
25 import javax.swing.SwingUtilities;
26 import javax.swing.event.ChangeEvent;
27 import javax.swing.event.ChangeListener;
28 import javax.swing.table.AbstractTableModel;
29
30 import org.jscience.physics.amount.Amount;
31
32 import com.billkuker.rocketry.motorsim.Fuel;
33 import com.billkuker.rocketry.motorsim.RocketScience;
34 import com.billkuker.rocketry.motorsim.fuel.EditableFuel.EditableCombustionProduct;
35 import com.billkuker.rocketry.motorsim.fuel.PiecewiseSaintRobertFuel;
36 import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel;
37 import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel.Type;
38 import com.billkuker.rocketry.motorsim.visual.Chart;
39 import com.billkuker.rocketry.motorsim.visual.Editor;
40
41 public class SRFuelEditor extends JSplitPane {
42         private static final long serialVersionUID = 1L;
43
44         private static final NumberFormat nf = new DecimalFormat("##########.###");
45
46         Chart<Pressure, Velocity> burnRate;
47
48         private class Entry implements Comparable<Entry> {
49                 Amount<Pressure> p = Amount.valueOf(0, RocketScience.UnitPreference.getUnitPreference().getPreferredUnit(RocketScience.PSI));
50                 double a;
51                 double n;
52
53                 @Override
54                 public int compareTo(Entry o) {
55                         return p.compareTo(o.p);
56                 }
57         }
58
59         public static class EditablePSRFuel extends PiecewiseSaintRobertFuel {
60
61                 @SuppressWarnings("unchecked")
62                 private Amount<VolumetricDensity> idealDensity = (Amount<VolumetricDensity>) Amount
63                                 .valueOf("1 g/mm^3");
64                 
65                 private double combustionEfficiency = 1;
66                 private double densityRatio = 1;
67                 private EditableCombustionProduct cp;
68                 private String name = "New Fuel";
69
70                 public EditablePSRFuel(Type t) {
71                         super(t);
72                         cp = new EditableCombustionProduct();
73                 }
74                 
75                 public void clear(){
76                         super.clear();
77                 }
78                 
79                 public void setType(Type t){
80                         super.setType(t);
81                 }
82
83                 public void add(Amount<Pressure> p, final double _a, final double _n) {
84                         super.add(p, _a, _n);
85
86                 }
87
88                 public Amount<VolumetricDensity> getIdealDensity() {
89                         return idealDensity;
90                 }
91
92                 public void setIdealDensity(Amount<VolumetricDensity> idealDensity) {
93                         this.idealDensity = idealDensity;
94                 }
95
96                 public double getCombustionEfficiency() {
97                         return combustionEfficiency;
98                 }
99
100                 public void setCombustionEfficiency(double combustionEfficiency) {
101                         this.combustionEfficiency = combustionEfficiency;
102                 }
103
104                 public double getDensityRatio() {
105                         return densityRatio;
106                 }
107
108                 public void setDensityRatio(double densityRatio) {
109                         this.densityRatio = densityRatio;
110                 }
111
112                 @Override
113                 public CombustionProduct getCombustionProduct() {
114                         return cp;
115                 }
116
117                 public String getName() {
118                         return name;
119                 }
120
121                 public void setName(String name) {
122                         this.name = name;
123                 }
124
125         }
126
127         final EditablePSRFuel f = new EditablePSRFuel(SaintRobertFuel.Type.SI);
128
129         private class TM extends AbstractTableModel {
130                 private static final long serialVersionUID = 1L;
131
132                 @Override
133                 public int getColumnCount() {
134                         return 3;
135                 }
136
137                 @Override
138                 public int getRowCount() {
139                         return entries.size();
140                 }
141
142                 @Override
143                 public String getColumnName(int col) {
144                         switch (col) {
145                         case 0:
146                                 return "Pressure";
147                         case 1:
148                                 return "Coefficient (a)";
149                         case 2:
150                                 return "Exponent (n)";
151                         }
152                         return null;
153                 }
154
155                 @Override
156                 public Object getValueAt(int rowIndex, int columnIndex) {
157                         Entry e = entries.get(rowIndex);
158                         switch (columnIndex) {
159                         case 0:
160                                 //Format like 100 psi or 4.8 Mpa
161                                 return nf.format(e.p.doubleValue(e.p.getUnit())) + " " + e.p.getUnit();
162                         case 1:
163                                 return e.a;
164                         case 2:
165                                 return e.n;
166                         }
167                         return null;
168                 }
169
170                 public boolean isCellEditable(int row, int col) {
171                         return true;
172                 }
173
174                 @SuppressWarnings("unchecked")
175                 public void setValueAt(Object value, int row, int col) {
176                         Entry e = entries.get(row);
177                         try {
178                                 switch (col) {
179                                 case 0:
180                                         try {
181                                                 e.p = (Amount<Pressure>) Amount.valueOf((String) value);
182                                         } catch ( Exception ee ){
183                                                 double d = Double.parseDouble((String)value);
184                                                 e.p = (Amount<Pressure>)Amount.valueOf(d, e.p.getUnit());
185                                         }
186                                         break;
187                                 case 1:
188                                         e.a = Double.valueOf((String) value);
189                                         break;
190                                 case 2:
191                                         e.n = Double.valueOf((String) value);
192                                 }
193                         } catch (Exception ex) {
194                                 ex.printStackTrace();
195                         }
196                         Collections.sort(entries);
197                         fireTableDataChanged();
198                         //f = new EditablePSRFuel(SaintRobertFuel.Type.NONSI);
199                         f.clear();
200                         for (Entry en : entries) {
201                                 f.add(en.p, en.a, en.n);
202                         }
203                         f.firePropertyChange(new PropertyChangeEvent(f,"entries", null, null));
204
205                         update();
206
207                 }
208
209                 @Override
210                 public void fireTableDataChanged() {
211                         super.fireTableDataChanged();
212                 }
213
214         };
215         
216         public Fuel getFuel(){
217                 return f;
218         }
219
220         private void update() {
221                 SwingUtilities.invokeLater(new Runnable() {
222
223                         @Override
224                         public void run() {
225                                 editTop.setTopComponent(new Editor(f));
226                                 editTop.setBottomComponent(new Editor(f.getCombustionProduct()));
227                                 if (burnRate != null)
228                                         SRFuelEditor.this.remove(burnRate);
229                                 try {
230                                         burnRate = new Chart<Pressure, Velocity>(
231                                                         SI.MEGA(SI.PASCAL), SI.MILLIMETER.divide(SI.SECOND)
232                                                                         .asType(Velocity.class), f, "burnRate");
233                                 } catch (NoSuchMethodException e) {
234                                         throw new Error(e);
235                                 }
236                                 burnRate.setDomain(burnRate.new IntervalDomain(Amount.valueOf(
237                                                 0, SI.MEGA(SI.PASCAL)), Amount.valueOf(11, SI
238                                                 .MEGA(SI.PASCAL)), 50));
239                                 SRFuelEditor.this.setRightComponent(burnRate);
240                                 SRFuelEditor.this.revalidate();
241                         }
242                 });
243         }
244
245         private Vector<Entry> entries = new Vector<Entry>();
246
247         JSplitPane editParent;
248         JSplitPane editTop;
249         JSplitPane editBottom;
250         JPanel controls;
251
252         public SRFuelEditor() {
253                 super(HORIZONTAL_SPLIT);
254                 setResizeWeight(0);
255                 setDividerLocation(.3);
256                 
257                 final TM tm = new TM();
258
259                 editParent = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
260                 editTop = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
261                 editBottom = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
262                 
263                 editParent.setTopComponent(editTop);
264                 editParent.setBottomComponent(editBottom);
265                 
266                 editTop.setTopComponent(new Editor(f));
267
268                 JTable table = new JTable(tm);
269                 JScrollPane scrollpane = new JScrollPane(table);
270                 scrollpane.setMinimumSize(new Dimension(200, 200));
271                 editBottom.setTopComponent(scrollpane);
272
273                 setLeftComponent(editParent);
274
275                 JButton add = new JButton("Add Data");
276                 add.addActionListener(new ActionListener() {
277                         @Override
278                         public void actionPerformed(ActionEvent e) {
279                                 entries.add(new Entry());
280                                 tm.fireTableDataChanged();
281                         }
282                 });
283                 controls = new JPanel();
284                 controls.setPreferredSize(new Dimension(200, 50));
285                 controls.setLayout(new FlowLayout());
286                         
287                 controls.add(add);
288
289                 
290                 final JRadioButton si, nonsi;
291                 ButtonGroup type = new ButtonGroup();
292                 JPanel radio = new JPanel();
293                 radio.add(si = new JRadioButton("SI"));
294                 radio.add(nonsi = new JRadioButton("NonSI"));
295                 controls.add(radio);
296                 type.add(si);
297                 type.add(nonsi);
298
299                 si.setSelected(true);
300                 
301                 si.addChangeListener(new ChangeListener(){
302                         @Override
303                         public void stateChanged(ChangeEvent e) {
304                                 if ( si.isSelected() ){
305                                         System.err.println("SI");
306                                         f.setType(Type.SI);
307                                 } else {
308                                         System.err.println("NONSI");
309                                         f.setType(Type.NONSI);
310                                 }
311                                 update();
312                         }});
313                 
314                 editBottom.setBottomComponent(controls);
315                 
316                 
317                 editParent.setDividerLocation(.5);
318                 editTop.setDividerLocation(.5);
319                 editBottom.setDividerLocation(.8);
320                 
321                 editParent.resetToPreferredSizes();
322                 revalidate();
323
324                 update();
325         }
326
327         public static void main(String args[]) {
328                 JFrame f = new JFrame();
329                 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
330                 f.setContentPane(new SRFuelEditor());
331                 f.setSize(800, 600);
332                 f.setVisible(true);
333
334         }
335
336 }