2d297f12fd461e5424b3ed4736e57e4c4bdb30da
[sw/motorsim] / gui / com / billkuker / rocketry / motorsim / visual / BurnPanel.java
1 package com.billkuker.rocketry.motorsim.visual;\r
2 \r
3 import java.awt.BorderLayout;\r
4 import java.awt.Dimension;\r
5 import java.awt.GridLayout;\r
6 import java.text.NumberFormat;\r
7 \r
8 import javax.measure.quantity.Duration;\r
9 import javax.measure.quantity.Force;\r
10 import javax.measure.quantity.Pressure;\r
11 import javax.measure.quantity.Velocity;\r
12 import javax.measure.unit.SI;\r
13 import javax.swing.JFrame;\r
14 import javax.swing.JLabel;\r
15 import javax.swing.JPanel;\r
16 import javax.swing.JSlider;\r
17 import javax.swing.JSplitPane;\r
18 import javax.swing.WindowConstants;\r
19 import javax.swing.event.ChangeEvent;\r
20 import javax.swing.event.ChangeListener;\r
21 \r
22 import org.jscience.physics.amount.Amount;\r
23 \r
24 import com.billkuker.rocketry.motorsim.Burn;\r
25 import com.billkuker.rocketry.motorsim.BurnSummary;\r
26 import com.billkuker.rocketry.motorsim.RocketScience;\r
27 \r
28 public class BurnPanel extends JPanel {\r
29         private static final long serialVersionUID = 1L;\r
30         private Burn burn;\r
31         Chart<Duration, Pressure> pressure;\r
32         Chart<Duration, Force> thrust;\r
33         Chart<Pressure, Velocity> burnRate;\r
34         GrainPanel grain;\r
35         Amount<Duration> displayedTime = Amount.valueOf(0, SI.SECOND);\r
36         \r
37         public BurnPanel(Burn b){\r
38                 super( new BorderLayout() );\r
39                 burn = b;\r
40                 \r
41                 try {\r
42                         pressure = new Chart<Duration, Pressure>(\r
43                                         SI.SECOND,\r
44                                         SI.MEGA(SI.PASCAL),\r
45                                         b,\r
46                                         "pressure");\r
47                         pressure.showAverage();\r
48                         pressure.showMax();\r
49                         pressure.setDomain(burn.getData().keySet());\r
50                         \r
51                         thrust = new Chart<Duration, Force>(\r
52                                         SI.SECOND,\r
53                                         SI.NEWTON,\r
54                                         b,\r
55                                         "thrust");\r
56                         thrust.showAverage();\r
57                         thrust.showMax();\r
58                         thrust.setDomain(burn.getData().keySet());\r
59                         \r
60                         burnRate = new Chart<Pressure, Velocity>(\r
61                                         SI.MEGA(SI.PASCAL),\r
62                                         SI.METERS_PER_SECOND,\r
63                                         burn.getMotor().getFuel(),\r
64                                         "burnRate");\r
65                         burnRate.setDomain(\r
66                                         burnRate.new IntervalDomain(\r
67                                                         Amount.valueOf(0, SI.MEGA(SI.PASCAL)),\r
68                                                         Amount.valueOf(11, SI.MEGA(SI.PASCAL)),\r
69                                                         20\r
70                                                         ));\r
71                         \r
72                         \r
73                         JSplitPane tp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, thrust, pressure);\r
74                         tp.setDividerLocation(.5);\r
75                         tp.setResizeWeight(.5);\r
76                         \r
77                         grain = new GrainPanel(burn.getMotor().getGrain()){\r
78                                 private static final long serialVersionUID = 1L;\r
79                                 @Override protected void addComponents(java.awt.Component crossSection, java.awt.Component slider, java.awt.Component label, java.awt.Component area, java.awt.Component volume) {\r
80                                         JSplitPane h = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, crossSection, area); \r
81                                         add(h, BorderLayout.CENTER);\r
82                                         h.resetToPreferredSizes();\r
83                                 };\r
84                         };\r
85                         \r
86                         JSplitPane grains = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, grain, burnRate);\r
87                         grains.setDividerLocation(.5);\r
88                         grains.setResizeWeight(.5);\r
89                         \r
90                         JSplitPane main = new JSplitPane(JSplitPane.VERTICAL_SPLIT, grains, tp);\r
91                         Dimension minimumSize = new Dimension(800, 200);\r
92                         grains.setMinimumSize(minimumSize);\r
93                         tp.setMinimumSize(minimumSize);\r
94                         main.setDividerLocation(.5);\r
95                         main.setResizeWeight(.5);\r
96                         \r
97                         add( main, BorderLayout.CENTER );\r
98                         \r
99                         add( new SL(), BorderLayout.SOUTH);\r
100                         \r
101                         \r
102                         \r
103                         {\r
104                                 BurnSummary bi = new BurnSummary(burn);\r
105                                 JPanel text = new JPanel(new GridLayout(2, 5));\r
106 \r
107                                 text.add(new JLabel("Rating"));\r
108                                 text.add(new JLabel("Total Impulse"));\r
109                                 text.add(new JLabel("ISP"));\r
110                                 text.add(new JLabel("Max Thrust"));\r
111                                 text.add(new JLabel("Average Thust"));\r
112                                 text.add(new JLabel("Max Pressure"));\r
113 \r
114                                 text.add(new JLabel(bi.getRating()));\r
115                                 text.add(new JLabel(RocketScience.ammountToRoundedString(bi.totalImpulse())));\r
116                                 text.add(new JLabel(RocketScience.ammountToRoundedString(bi.specificImpulse())));\r
117                                 text.add(new JLabel(RocketScience\r
118                                                 .ammountToRoundedString(bi.maxThrust())));\r
119                                 text.add(new JLabel(RocketScience\r
120                                                 .ammountToRoundedString(bi.averageThrust())));\r
121                                 text.add(new JLabel(RocketScience\r
122                                                 .ammountToRoundedString(bi.maxPressure())));\r
123 \r
124                                 add(text, BorderLayout.NORTH);\r
125                         }\r
126                         \r
127                         \r
128                 } catch (NoSuchMethodException e){\r
129                         throw new Error(e);\r
130                 }\r
131                 \r
132 \r
133         }\r
134         \r
135         private class SL extends JSlider implements ChangeListener{\r
136                 private static final long serialVersionUID = 1L;\r
137                 private static final int STEPS = 80;\r
138                 public SL(){\r
139                         addChangeListener(this);\r
140                         setMinimum(0);\r
141                         setMaximum(STEPS);\r
142                         setValue(0);\r
143                 }\r
144                 \r
145                 public void stateChanged(ChangeEvent e) {\r
146                         double t = ((SL)e.getSource()).getValue();\r
147                         displayedTime = burn.burnTime().divide(STEPS).times(t);\r
148                         \r
149                         //Find the nearest key in the data set\r
150                         displayedTime =burn.getData().tailMap(displayedTime).firstKey();\r
151                         \r
152                         NumberFormat nf = NumberFormat.getInstance();\r
153                         nf.setMaximumFractionDigits(2);\r
154                         \r
155                         pressure.mark(displayedTime);\r
156                         thrust.mark(displayedTime);\r
157                         \r
158                         grain.setDisplayedRegression(burn.getData().get(displayedTime).regression);\r
159                         \r
160                         burnRate.mark(burn.getData().get(displayedTime).chamberPressure);\r
161                         \r
162                         \r
163                         /*\r
164                         double r = ((SL)e.getSource()).getValue();\r
165                         displayedRegression = grain.webThickness().divide(STEPS).times(r);\r
166                         NumberFormat nf = NumberFormat.getInstance();\r
167                         nf.setMaximumFractionDigits(2);\r
168                         l.setText("Regression: " + nf.format(displayedRegression.doubleValue(SI.MILLIMETER)) + "mm");\r
169                         area.mark(displayedRegression);\r
170                         volume.mark(displayedRegression);\r
171                         if ( xc != null )\r
172                                 xc.repaint();\r
173                         */\r
174                 }\r
175         }\r
176         \r
177         public void showAsWindow(){\r
178                 JFrame f = new JFrame();\r
179                 f.setTitle(burn.getMotor().getName());\r
180                 f.setSize(1280,720);\r
181                 f.setLocation(0, 0);\r
182                 f.setContentPane(this);\r
183                 f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);\r
184                 f.setVisible(true);\r
185         }\r
186 }\r