2 * GravitySimulatorView.java
5 package edu
.mit
.ezyang
.gravity
;
7 import edu
.mit
.ezyang
.gravity
.j3d
.*;
8 import com
.sun
.j3d
.utils
.behaviors
.keyboard
.KeyNavigatorBehavior
;
9 import org
.jdesktop
.application
.Action
;
10 import org
.jdesktop
.application
.SingleFrameApplication
;
11 import org
.jdesktop
.application
.FrameView
;
12 import javax
.swing
.JDialog
;
14 import javax
.swing
.JFrame
;
15 import com
.sun
.j3d
.utils
.geometry
.*;
16 import com
.sun
.j3d
.utils
.universe
.*;
18 import javax
.media
.j3d
.*;
19 import javax
.swing
.JPopupMenu
;
20 import javax
.vecmath
.*;
23 * This is the main and only frame of the GravitySimulator application. It
24 * controls the console and the Canvas3D, both of which respond to user
26 * @author Edward Z. Yang <ezyang@mit.edu>
28 public class GravitySimulatorView
extends FrameView
{
31 * BranchGroup that objects in the universe should be inserted in. This
32 * itself is inside a rotatable TransformGroup, which allows all objects
33 * in the universe to be rotated.
35 protected BranchGroup universeRoot
;
38 * TransformGroup corresponding to the rotation universeRoot; this
39 * needs to be registered to all SmartPickTranslateBehavior objects
40 * in order to compensate properly.
42 protected TransformGroup globalRotateGroup
;
45 * TransformGroup corresponding to the location of the viewpoint; this
46 * can be modified in order to change the viewer's location.
48 protected TransformGroup viewTransformGroup
;
51 * Canvas being rendered in the UI. Use this to access global properties
52 * including the SimpleUniverse.
54 protected Canvas3D canvas
;
56 public GravitySimulatorView(SingleFrameApplication app
) {
59 // make menus heavy, see <http://java3d.j3d.org/faq/swing.html>
60 JPopupMenu
.setDefaultLightWeightPopupEnabled(false);
63 BoundingSphere bounds
= new BoundingSphere(new Point3d(0f
,0f
,0f
), 1000f
);
65 canvas
= new Canvas3D(SimpleUniverse
.getPreferredConfiguration());
66 SimpleUniverse universe
= new SimpleUniverse(canvas
);
68 BranchGroup root
= new BranchGroup();
71 TransformGroup vpTrans
= universe
.getViewingPlatform().getViewPlatformTransform();
72 KeyNavigatorBehavior keyNavBeh
= new KeyNavigatorBehavior(vpTrans
);
73 keyNavBeh
.setSchedulingBounds(bounds
);
74 root
.addChild(keyNavBeh
);
76 universeRoot
= new BranchGroup();
77 universeRoot
.setCapability(BranchGroup
.ALLOW_CHILDREN_WRITE
);
78 universeRoot
.setCapability(BranchGroup
.ALLOW_CHILDREN_EXTEND
);
80 globalRotateGroup
= new RotateGroup();
82 globalRotateGroup
.addChild(universeRoot
);
83 root
.addChild(globalRotateGroup
);
84 universe
.addBranchGraph(root
);
86 ViewingPlatform platform
= universe
.getViewingPlatform();
87 platform
.setNominalViewingTransform();
88 //platform.getViewers()[0].getView().setFieldOfView(10f);
90 viewTransformGroup
= platform
.getMultiTransformGroup().getTransformGroup(0);
91 Transform3D viewTransform
= new Transform3D();
92 viewTransform
.setTranslation(new Vector3f(0.0f
,0.0f
,10.0f
));
93 viewTransformGroup
.setTransform(viewTransform
);
95 canvasPanel
.add(canvas
);
97 // Initialize environment with some objects
98 processCommand("add sphere");
99 processCommand("add cube at 0,2,0");
100 processCommand("add cube at 0,-2,0");
101 processCommand("add cube at 2,0,0");
102 processCommand("add cube at -2,0,0");
106 /** Processes a command from the command line box, modifying Universe.
107 * @param command Command line to execute.
109 public void processCommand(String command
) {
111 String
[] parts
= command
.split(" ");
112 if (parts
.length
== 0 || parts
[0].equals("") || parts
[0].equals("help")) {
113 send("Commands: add, view, clear");
116 if (parts
[0].equals("add")) {
117 if (parts
.length
== 1) {
118 send("Need object to add: sphere, cone, cube or cylinder");
122 // initialize default "first class" parameters
124 Vector3f location
= new Vector3f(0f
, 0f
, 0f
);
126 // initialize generic params HashMap; this can be used for
127 // any sort of thing you want
128 HashMap
<String
, String
> params
= new HashMap
<String
, String
>();
130 // parse the arguments
131 if (parts
.length
> 2) {
133 for (int i
= 2; i
< parts
.length
; i
++) {
137 if (state
.equals("scale")) {
138 scale
= new Float(parts
[i
]);
139 } else if (state
.equals("at")) {
140 location
= vectorize(parts
[i
]);
142 params
.put(state
, parts
[i
]);
148 // generate the actual primitive
150 if (parts
[1].equals("sphere")) {
151 Sphere sphere
= new Sphere(scale
);
152 sphere
.getAppearance().getMaterial().setAmbientColor(.8f
,.2f
,.2f
);
154 } else if (parts
[1].equals("cube")) {
155 object
= new ColorCube(scale
);
156 } else if (parts
[1].equals("cone")) {
157 object
= new Cone(scale
* 1f
, scale
* 2f
);
158 } else if (parts
[1].equals("cylinder")) {
159 object
= new Cylinder(scale
* 1f
, scale
* 2f
);
161 send("Unknown primitive: " + parts
[1]);
164 object
.setCapability(Node
.ENABLE_PICK_REPORTING
);
165 object
.setCapability(Node
.ALLOW_BOUNDS_READ
);
166 object
.setCapability(Node
.ALLOW_BOUNDS_WRITE
);
168 EditableGroup group
= new EditableGroup(canvas
, globalRotateGroup
, location
);
169 group
.addTransformChild(object
);
171 universeRoot
.addChild(group
);
172 } else if (parts
[0].equals("view")) {
173 if (parts
.length
== 1) {
174 send("Need location parameter x,y,z");
177 Transform3D viewTransform
= new Transform3D();
178 viewTransform
.setTranslation(vectorize(parts
[1]));
179 viewTransformGroup
.setTransform(viewTransform
);
180 } else if (parts
[0].equals("zoom")) {
181 if (parts
.length
== 1) {
182 send("Need zoom value z (view 0,0,z)");
185 Transform3D viewTransform
= new Transform3D();
186 viewTransform
.setTranslation(vectorize("0,0," + parts
[1]));
187 viewTransformGroup
.setTransform(viewTransform
);
188 } else if (parts
[0].equals("clear")) {
189 universeRoot
.removeAllChildren();
191 send("Unknown command: " + parts
[0] + ", type help for options");
196 /** Converts string in form x,y,z to Vector3f
197 * @param input vector in form x,y,z
198 * @return Appropriate vector
200 protected Vector3f
vectorize(String input
) {
201 String
[] vectorFields
= input
.split(",");
202 return new Vector3f(new Float(vectorFields
[0]), new Float(vectorFields
[1]), new Float(vectorFields
[2]));
205 /** Sends a message to display in the terminal.
206 * @param message Message to send
208 protected void send(String message
) {
209 terminal
.append(message
+ "\n");
212 /** Displays the about box.
215 public void showAboutBox() {
216 if (aboutBox
== null) {
217 JFrame mainFrame
= GravitySimulatorApp
.getApplication().getMainFrame();
218 aboutBox
= new GravitySimulatorAboutBox(mainFrame
);
219 aboutBox
.setLocationRelativeTo(mainFrame
);
221 GravitySimulatorApp
.getApplication().show(aboutBox
);
224 /** This method is called from within the constructor to
225 * initialize the form.
226 * WARNING: Do NOT modify this code. The content of this method is
227 * always regenerated by the Form Editor.
229 @SuppressWarnings("unchecked")
230 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
231 private void initComponents() {
233 mainPanel
= new javax
.swing
.JPanel();
234 canvasPanel
= new javax
.swing
.JPanel();
235 console
= new javax
.swing
.JPanel();
236 commandLine
= new javax
.swing
.JTextField();
237 terminalPane
= new javax
.swing
.JScrollPane();
238 terminal
= new javax
.swing
.JTextArea();
239 menuBar
= new javax
.swing
.JMenuBar();
240 javax
.swing
.JMenu fileMenu
= new javax
.swing
.JMenu();
241 javax
.swing
.JMenuItem exitMenuItem
= new javax
.swing
.JMenuItem();
242 javax
.swing
.JMenu helpMenu
= new javax
.swing
.JMenu();
243 javax
.swing
.JMenuItem aboutMenuItem
= new javax
.swing
.JMenuItem();
245 mainPanel
.setName("mainPanel"); // NOI18N
246 mainPanel
.setLayout(new java
.awt
.BorderLayout());
248 org
.jdesktop
.application
.ResourceMap resourceMap
= org
.jdesktop
.application
.Application
.getInstance(edu
.mit
.ezyang
.gravity
.GravitySimulatorApp
.class).getContext().getResourceMap(GravitySimulatorView
.class);
249 canvasPanel
.setBackground(resourceMap
.getColor("canvasPanel.background")); // NOI18N
250 canvasPanel
.setName("canvasPanel"); // NOI18N
251 canvasPanel
.setLayout(new java
.awt
.BorderLayout());
252 mainPanel
.add(canvasPanel
, java
.awt
.BorderLayout
.CENTER
);
254 console
.setName("console"); // NOI18N
255 console
.setLayout(new java
.awt
.BorderLayout());
257 commandLine
.setText(resourceMap
.getString("commandLine.text")); // NOI18N
258 commandLine
.setName("commandLine"); // NOI18N
259 commandLine
.addActionListener(new java
.awt
.event
.ActionListener() {
260 public void actionPerformed(java
.awt
.event
.ActionEvent evt
) {
261 commandLineActionPerformed(evt
);
264 console
.add(commandLine
, java
.awt
.BorderLayout
.CENTER
);
266 terminalPane
.setName("terminalPane"); // NOI18N
268 terminal
.setColumns(20);
269 terminal
.setEditable(false);
270 terminal
.setFont(resourceMap
.getFont("terminal.font")); // NOI18N
272 terminal
.setName("terminal"); // NOI18N
273 terminalPane
.setViewportView(terminal
);
275 console
.add(terminalPane
, java
.awt
.BorderLayout
.PAGE_START
);
277 mainPanel
.add(console
, java
.awt
.BorderLayout
.PAGE_END
);
279 menuBar
.setName("menuBar"); // NOI18N
281 fileMenu
.setText(resourceMap
.getString("fileMenu.text")); // NOI18N
282 fileMenu
.setName("fileMenu"); // NOI18N
284 javax
.swing
.ActionMap actionMap
= org
.jdesktop
.application
.Application
.getInstance(edu
.mit
.ezyang
.gravity
.GravitySimulatorApp
.class).getContext().getActionMap(GravitySimulatorView
.class, this);
285 exitMenuItem
.setAction(actionMap
.get("quit")); // NOI18N
286 exitMenuItem
.setName("exitMenuItem"); // NOI18N
287 fileMenu
.add(exitMenuItem
);
289 menuBar
.add(fileMenu
);
291 helpMenu
.setText(resourceMap
.getString("helpMenu.text")); // NOI18N
292 helpMenu
.setName("helpMenu"); // NOI18N
294 aboutMenuItem
.setAction(actionMap
.get("showAboutBox")); // NOI18N
295 aboutMenuItem
.setName("aboutMenuItem"); // NOI18N
296 helpMenu
.add(aboutMenuItem
);
298 menuBar
.add(helpMenu
);
300 setComponent(mainPanel
);
302 }// </editor-fold>//GEN-END:initComponents
304 private void commandLineActionPerformed(java
.awt
.event
.ActionEvent evt
) {//GEN-FIRST:event_commandLineActionPerformed
305 processCommand(commandLine
.getText());
306 commandLine
.setText("");
307 }//GEN-LAST:event_commandLineActionPerformed
309 // Variables declaration - do not modify//GEN-BEGIN:variables
310 private javax
.swing
.JPanel canvasPanel
;
311 private javax
.swing
.JTextField commandLine
;
312 private javax
.swing
.JPanel console
;
313 private javax
.swing
.JPanel mainPanel
;
314 private javax
.swing
.JMenuBar menuBar
;
315 private javax
.swing
.JTextArea terminal
;
316 private javax
.swing
.JScrollPane terminalPane
;
317 // End of variables declaration//GEN-END:variables
319 private JDialog aboutBox
;