New panels.
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / grain / GrainPanel.java
1 package com.billkuker.rocketry.motorsim.grain;\r
2 \r
3 import java.awt.BorderLayout;\r
4 import java.awt.Color;\r
5 import java.awt.Dimension;\r
6 import java.awt.Graphics;\r
7 import java.awt.Graphics2D;\r
8 import java.awt.Rectangle;\r
9 import java.awt.geom.AffineTransform;\r
10 import java.text.NumberFormat;\r
11 \r
12 import javax.measure.quantity.Area;\r
13 import javax.measure.quantity.Length;\r
14 import javax.measure.quantity.Volume;\r
15 import javax.measure.unit.SI;\r
16 import javax.swing.JFrame;\r
17 import javax.swing.JLabel;\r
18 import javax.swing.JPanel;\r
19 import javax.swing.JSlider;\r
20 import javax.swing.JSplitPane;\r
21 import javax.swing.event.ChangeEvent;\r
22 import javax.swing.event.ChangeListener;\r
23 \r
24 import org.jscience.physics.amount.Amount;\r
25 \r
26 import com.billkuker.rocketry.motorsim.Grain;\r
27 import com.billkuker.rocketry.motorsim.visual.Chart;\r
28 \r
29 public class GrainPanel extends JPanel {\r
30         private static final long serialVersionUID = 1L;\r
31         private Amount<Length> displayedRegression = Amount.valueOf(0, SI.MILLIMETER);\r
32         private JLabel l = new JLabel();\r
33         private Chart<Length,Area> area;\r
34         Chart<Length, Volume> volume;\r
35         private XC xc;\r
36         private SL sl;\r
37         private Grain grain;\r
38         \r
39         public GrainPanel(Grain g){\r
40                 super(new BorderLayout());\r
41 \r
42                 grain = g;\r
43 \r
44                 try {\r
45 \r
46                         area = new Chart<Length, Area>(\r
47                                         SI.MILLIMETER,\r
48                                         SI.MILLIMETER.pow(2).asType(Area.class),\r
49                                         grain,\r
50                                         "surfaceArea");\r
51                         area.setDomain(area.new IntervalDomain(Amount.valueOf(0, SI.MILLIMETER), grain.webThickness()));\r
52                         \r
53                         volume = new Chart<Length, Volume>(\r
54                                         SI.MILLIMETER,\r
55                                         SI.MILLIMETER.pow(3).asType(Volume.class),\r
56                                         grain,\r
57                                         "volume");\r
58                         volume.setDomain(volume.new IntervalDomain(Amount.valueOf(0, SI.MILLIMETER), grain.webThickness()));\r
59 \r
60                         area.setMaximumSize(new Dimension(200,100));\r
61                         volume.setMaximumSize(new Dimension(200,100));\r
62                         \r
63 \r
64                 } catch (ClassCastException e) {\r
65                         // TODO Auto-generated catch block\r
66                         e.printStackTrace();\r
67                 } catch (NoSuchMethodException e) {\r
68                         // TODO Auto-generated catch block\r
69                         e.printStackTrace();\r
70                 }\r
71                 \r
72                 \r
73                 JSplitPane charts = new JSplitPane(JSplitPane.VERTICAL_SPLIT, area, volume);\r
74                 charts.setDividerLocation(.5);\r
75                 charts.setResizeWeight(.5);\r
76                 \r
77                 JPanel left = new JPanel(new BorderLayout());\r
78                 \r
79                 if ( grain instanceof Grain.Graphical){\r
80                         add(xc = new XC((Grain.Graphical)grain), BorderLayout.CENTER);\r
81                         left.add(xc);\r
82                 }\r
83                 left.add(l, BorderLayout.NORTH);\r
84                 left.add( sl = new SL(), BorderLayout.SOUTH);\r
85         \r
86                 add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, charts));\r
87 \r
88         }\r
89         \r
90         public void setDisplayedRegression( Amount<Length> r ){\r
91                 displayedRegression = r;\r
92                 \r
93                 NumberFormat nf = NumberFormat.getInstance();\r
94                 nf.setMaximumFractionDigits(2);\r
95                 l.setText("Regression: " + nf.format(displayedRegression.doubleValue(SI.MILLIMETER)) + "mm");\r
96                 \r
97                 area.mark(displayedRegression);\r
98                 volume.mark(displayedRegression);\r
99                 if ( xc != null )\r
100                         xc.repaint();\r
101         }\r
102         \r
103         private class XC extends JPanel{\r
104                 private static final long serialVersionUID = 1L;\r
105                 Grain.Graphical grain;\r
106                 public XC(Grain.Graphical g){\r
107                         setMinimumSize(new Dimension(440,250));\r
108                         grain = g;\r
109                 }\r
110                 public void paint(Graphics g){\r
111                         super.paint(g);\r
112                         Graphics2D g2d = (Graphics2D)g;\r
113                         g2d.translate(10, 30);\r
114                         /*\r
115                         grain.draw(g2d, displayedRegression );\r
116                         */\r
117                         \r
118                         {\r
119                                 AffineTransform t = g2d.getTransform();\r
120                                 java.awt.geom.Area unburnt = grain.getCrossSection(Amount.valueOf(0, SI.MILLIMETER));\r
121                                 \r
122                                 Rectangle bounds = unburnt.getBounds();\r
123                                 g2d.scale(200 / bounds.getWidth(), 200 / bounds.getHeight());\r
124                                 g2d.translate(-bounds.getX(), -bounds.getY());\r
125         \r
126                                 //Draw the fuel that is left\r
127                                 java.awt.geom.Area burning = grain.getCrossSection(displayedRegression);\r
128                                 g2d.setColor(Color.RED);\r
129                                 g2d.fill(burning);\r
130                                 //Draw the fuel that is left\r
131                                 java.awt.geom.Area left = grain.getCrossSection(displayedRegression.plus(grain.webThickness().divide(30)));\r
132                                 g2d.setColor(Color.GRAY);\r
133                                 g2d.fill(left);\r
134                                 //Draw the outline of the unburnt grain\r
135                                 g2d.setColor(Color.BLACK);\r
136                                 g2d.draw(unburnt);\r
137                                 //untranslate\r
138                                 g2d.setTransform(t);\r
139                         }\r
140                         {\r
141                                 AffineTransform t = g2d.getTransform();\r
142                                 java.awt.geom.Area unburnt = grain.getSideView(Amount.valueOf(0, SI.MILLIMETER));\r
143                                 \r
144                                 Rectangle bounds = unburnt.getBounds();\r
145                                 g2d.translate(220, 0);\r
146                                 \r
147                                 double max = bounds.getWidth();\r
148                                 if ( bounds.getHeight() > max )\r
149                                         max = bounds.getHeight();\r
150                                 \r
151                                 g2d.scale(200 / max, 200 / max);\r
152                                 g2d.translate(-bounds.getX(), -bounds.getY());\r
153         \r
154                                 //Draw the fuel that is left\r
155                                 java.awt.geom.Area burning = grain.getSideView(displayedRegression);\r
156                                 g2d.setColor(Color.RED);\r
157                                 g2d.fill(burning);\r
158                                 //Draw the fuel that is left\r
159                                 java.awt.geom.Area left = grain.getSideView(displayedRegression.plus(grain.webThickness().divide(30)));\r
160                                 g2d.setColor(Color.GRAY);\r
161                                 g2d.fill(left);\r
162                                 //Draw the outline of the unburnt grain\r
163                                 g2d.setColor(Color.BLACK);\r
164                                 g2d.draw(unburnt);\r
165                                 //untranslate\r
166                                 g2d.setTransform(t);\r
167                         }\r
168                         \r
169                 }\r
170         }\r
171         \r
172         private class SL extends JSlider implements ChangeListener{\r
173                 private static final long serialVersionUID = 1L;\r
174                 private static final int STEPS = 60;\r
175                 public SL(){\r
176                         addChangeListener(this);\r
177                         setMinimum(0);\r
178                         setMaximum(STEPS);\r
179                         setValue(0);\r
180                 }\r
181                 \r
182                 @Override\r
183                 public void stateChanged(ChangeEvent e) {\r
184                         double r = ((SL)e.getSource()).getValue();\r
185 \r
186                         setDisplayedRegression(grain.webThickness().divide(STEPS).times(r));\r
187                 }\r
188         }\r
189         \r
190         public void show(){\r
191                 JFrame f = new JFrame();\r
192                 f.setSize(1024,600);\r
193                 f.setContentPane(this);\r
194                 f.setDefaultCloseOperation(f.DISPOSE_ON_CLOSE);\r
195                 f.setVisible(true);\r
196         }\r
197 \r
198 }\r