Include grain in overall view
[sw/motorsim] / gui / com / billkuker / rocketry / motorsim / visual / HardwarePanel.java
1 package com.billkuker.rocketry.motorsim.visual;\r
2 \r
3 import java.awt.BasicStroke;\r
4 import java.awt.Color;\r
5 import java.awt.Graphics;\r
6 import java.awt.Graphics2D;\r
7 import java.awt.Rectangle;\r
8 import java.awt.Shape;\r
9 import java.awt.geom.Area;\r
10 import java.beans.PropertyChangeEvent;\r
11 import java.beans.PropertyChangeListener;\r
12 \r
13 import javax.measure.unit.SI;\r
14 import javax.swing.JFrame;\r
15 import javax.swing.JPanel;\r
16 import javax.swing.WindowConstants;\r
17 \r
18 import org.jscience.physics.amount.Amount;\r
19 \r
20 import com.billkuker.rocketry.motorsim.Chamber;\r
21 import com.billkuker.rocketry.motorsim.ChangeListening;\r
22 import com.billkuker.rocketry.motorsim.ConvergentDivergentNozzle;\r
23 import com.billkuker.rocketry.motorsim.CylindricalChamber;\r
24 import com.billkuker.rocketry.motorsim.Motor;\r
25 import com.billkuker.rocketry.motorsim.Nozzle;\r
26 import com.billkuker.rocketry.motorsim.visual.workbench.MotorEditor;\r
27 \r
28 public class HardwarePanel extends JPanel {\r
29         private static final long serialVersionUID = 1L;\r
30         final Motor m;\r
31         \r
32         \r
33         private PropertyChangeListener repainter = new PropertyChangeListener(){\r
34                 public void propertyChange(PropertyChangeEvent evt) {\r
35                         repaint();\r
36                 }\r
37         };\r
38         \r
39         public HardwarePanel(Motor m){\r
40                 this.m = m;\r
41                 Nozzle nozzle = m.getNozzle();\r
42                 Chamber chamber = m.getChamber();\r
43                 if ( nozzle instanceof ChangeListening.Subject ){\r
44                         ((ChangeListening.Subject)nozzle).addPropertyChangeListener(repainter);\r
45                 }\r
46                 if ( chamber instanceof ChangeListening.Subject ){\r
47                         ((ChangeListening.Subject)chamber).addPropertyChangeListener(repainter);\r
48                 }\r
49         }\r
50         \r
51         public void paint(Graphics g){\r
52                 super.paint(g);\r
53                 Graphics2D g2d = (Graphics2D)g;\r
54                 g2d.translate(10, 10);\r
55 \r
56                 g2d.setColor(Color.black);\r
57                 \r
58                 Nozzle nozzle = m.getNozzle();\r
59                 Chamber chamber = m.getChamber();\r
60                 \r
61                 Shape c = chamber.chamberShape();\r
62                 \r
63                 Shape n = nozzle.nozzleShape(Amount.valueOf(c.getBounds().getWidth(), SI.MILLIMETER));\r
64                 \r
65                 \r
66                 Rectangle cb = c.getBounds();\r
67                 Rectangle nb = n.getBounds();\r
68                 double w, h;\r
69                 w = Math.max(cb.getWidth(), nb.getWidth());\r
70                 h = cb.getHeight() + nb.getHeight();\r
71                 \r
72                 double mw, mh;\r
73                 mw = getHeight() - 10;\r
74                 mh = getWidth() - 10;\r
75                 \r
76                 double sw, sh, s;\r
77                 sw = mw / w;\r
78                 sh = mh / h;\r
79                 s = Math.min(sw, sh);\r
80                 \r
81                 g2d.rotate(-Math.PI / 2);\r
82                 \r
83                 g2d.translate(0, -cb.getY() - 5);\r
84                 g2d.scale(s, s);\r
85                 g2d.translate(-(getHeight()/(s*2)), 0);\r
86                 \r
87                 g2d.setStroke(new BasicStroke(1));\r
88                 g2d.draw( c );\r
89                 \r
90                 g2d.translate(0, cb.getHeight());\r
91                 \r
92                 g2d.draw(n);\r
93                 \r
94                 Shape grain = m.getGrain().getSideView(Amount.valueOf(0, SI.MILLIMETER));\r
95                 Shape grain2 = m.getGrain().getSideView(Amount.valueOf(1, SI.MILLIMETER));\r
96                 Area burning = new Area(grain);\r
97                 burning.subtract(new Area(grain2));\r
98                 Rectangle gb = grain.getBounds();\r
99                 double x = -gb.getMaxX() +  gb.getWidth()/2.0;\r
100                 g2d.translate(x, -gb.getMaxY());\r
101                 g2d.draw(grain);\r
102                 g2d.setColor(Color.GRAY);\r
103                 g2d.fill(grain);\r
104                 g2d.setColor(Color.RED);\r
105                 g2d.fill(burning);\r
106         }\r
107         \r
108         public void showAsWindow(){\r
109                 JFrame f = new JFrame();\r
110                 f.setSize(220,250);\r
111                 f.setContentPane(this);\r
112                 f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);\r
113                 f.setVisible(true);\r
114         }\r
115         \r
116         public static void main(String args[]) throws Exception{\r
117                 Motor m = MotorEditor.defaultMotor();\r
118                 new HardwarePanel(m).showAsWindow();\r
119         }\r
120 }\r