LanderApplet07.java
package com.bozoid.cis370.hw07;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*; // for AffineTransform, Shape2D
import java.awt.font.*; // for Font
import java.text.*; // for NumberFormat
import java.util.Date; // for getTime()
/**
CISC370-011 homework #7: Applet
This applet is a transformed version of the application written
for assignment #4. It includes a 'Help' menu, gravity, and
some other goodies.
@author Walt Leipold
*/
public class LanderApplet07 extends JApplet
{
public void init()
{
JMenuBar jmb = new JMenuBar();
setJMenuBar(jmb);
sp = new AppletPanel07((JApplet)this);
Container contentPane = getContentPane();
contentPane.add(sp);
}
public void start() { sp.run(); }
public void stop() { sp.stop(); }
private AppletPanel07 sp;
}
class AppletPanel07 extends JPanel
{
/**
Constructor for the lander panel. Note that the parent frame
is passed explicitly, so the panel can listen for window events.
*/
public AppletPanel07(JApplet parentApplet)
{
// Allow the user to select the amount of gravity.
JRadioButtonMenuItem noGrav,lightGrav,heavyGrav;
AbstractAction noGravAction,lightGravAction,heavyGravAction;
parent = parentApplet;
// First, create a ship to simulate.
ship = new Ship07(200.0,-200.0,Math.PI/2.0);
// Some actions...
noGravAction = new GravAction("None",ship,0.0);
lightGravAction = new GravAction("Some",ship,4.0);
heavyGravAction = new GravAction("Lots",ship,12.0);
// Allow the user to control gravity.
JMenu gravMenu = new JMenu("Gravity");
ButtonGroup gravGroup = new ButtonGroup();
noGrav = new JRadioButtonMenuItem(noGravAction);
lightGrav = new JRadioButtonMenuItem(lightGravAction);
heavyGrav = new JRadioButtonMenuItem(heavyGravAction);
gravGroup.add(noGrav);
gravGroup.add(lightGrav);
gravGroup.add(heavyGrav);
gravMenu.add(noGrav);
gravMenu.add(lightGrav);
gravMenu.add(heavyGrav);
JMenuBar mb = parent.getJMenuBar();
mb.add(gravMenu);
noGrav.setSelected(true);
// Add a 'Help' menu.
JMenu helpMenu = new JMenu("Help");
JMenuItem aboutItem = new JMenuItem("About");
helpMenu.add(aboutItem);
mb.add(helpMenu);
final JPanel thisPane = this; // so action listener can refocus.
aboutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
JOptionPane.showMessageDialog(
(Container)parent,
(Object)aboutMessage,
"About LanderApplet07",
JOptionPane.INFORMATION_MESSAGE
);
}
catch(Exception ex) {
}
thisPane.requestFocus();
}
});
// Hook up listeners with listenees.
addMouseListener(new ShipMouse());
addKeyListener(new ShipKey());
// Make sure we can 'hear' keyboard events.
setFocusable(true);
// Start the simulation timer.
simTimer = new Timer(25,new ShipTimer());
simTimer.start();
// Initialize everything else.
setBackground(space_color);
fuel_font = new Font("Monospaced",Font.PLAIN,10);
}
/**
An action that changes the gravity on the spaceship.
*/
class GravAction extends AbstractAction
{
public GravAction(String name,Ship07 ship,double gravity)
{
super(name);
this.ship = ship;
this.gravity = gravity;
}
public void actionPerformed(ActionEvent e)
{
ship.setGravity(gravity);
}
private Ship07 ship;
private double gravity;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
ship.drawShip(g,cmd_main,cmd_cw,cmd_ccw);
drawFuel(g);
}
/**
Draw the spaceship's fuel consumption in the bottom right
corner of this panel.
@param g a graphics context to draw in
*/
private void drawFuel(Graphics g)
{
String s = nf.format(ship.getFuel());
String s2 = blanks.substring(0,16-s.length()) + s;
g.setColor(text_color);
g.setFont(fuel_font);
g.drawString(s2,5,getHeight()-5);
}
/**
Every tick of the timer, simulate the physics of the ship,
including fuel flow summation, translation and rotation, and
accelerations both linear and rotational.
*/
private class ShipTimer implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
ship.oneTick(cmd_main,cmd_cw,cmd_ccw);
repaint();
}
}
/**
To control the main thruster and reaction control thrusters,
we watch for presses and releases of three control keys, and
store their state in three instance variables.
*/
private class ShipKey extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_J) cmd_cw = true;
else if (e.getKeyCode() == KeyEvent.VK_L) cmd_ccw = true;
else if (e.getKeyCode() == KeyEvent.VK_K) cmd_main = true;
}
public void keyReleased(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_J) cmd_cw = false;
else if (e.getKeyCode() == KeyEvent.VK_L) cmd_ccw = false;
else if (e.getKeyCode() == KeyEvent.VK_K) cmd_main = false;
}
}
/**
Listen for mouse events and move the ship when a click is detected.
*/
private class ShipMouse extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
ship.setX((double)e.getX());
ship.setY((double)e.getY() * -1.0);
}
}
public void run() { simTimer.start(); ship.setActive(true); }
public void stop() { simTimer.stop(); ship.setActive(false); }
private Ship07 ship = null;
private final JApplet parent;
static private String aboutMessage =
"'LanderApplication' by W.S.Leipold\n\n" +
"Use the 'j', 'k', and 'l' keys to control the rocket.\n" +
"The 'j' and 'l' keys spin the rocket clockwise and\n" +
"counterclockwise, respectively. The 'k' key fires\n" +
"the main engine.";
// Which thrusters are thrusting?
private boolean cmd_cw = false;
private boolean cmd_ccw = false;
private boolean cmd_main = false;
// Timer to trigger each frame of the animation.
private Timer simTimer = null;
// Colors of various objects.
private Color space_color = Color.BLACK;
private Color text_color = Color.CYAN;
// Formatter for fuel and (future) coordinate display.
private static NumberFormat nf = null;
static {
nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
}
// Some variables for fuel display.
private Font fuel_font;
private static final String blanks = " ";
}