|
First Summer 2004 |
Today in class I would like to discuss this code:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Game extends Applet {
int i = 0;
public void paint(Graphics g) {
this.i = this.i + 1;
System.out.println("Paint called: " + i);
}
public void init() {
Umpire ump = new Umpire();
this.addMouseMotionListener(ump);
}
}
class Umpire implements MouseMotionListener { // wearing the uniform...
public void mouseDragged(MouseEvent e) {
System.out.println("Ha! You're dragging the mouse.");
}
public void mouseMoved(MouseEvent e) {
System.out.print ( "Mouse seen being moved at: (");
System.out.println( e.getX() + ", " + e.getY() + ")");
}
}
This goes with the following HTML file:
<html>
<head>
<title>Game Applet One</title>
</head>
<body bgcolor=white>
<applet code="Game.class" width=300 height=300>
</applet>
</body>
</html>
We'd like to understand this code very well. When this is done we will continue with the notes for tomorrow.
I include, however, some more information on applets, that we may be
going over in class.
We start with the life cycle of an applet: there are four methods in the Applet class that give you
the framework on which you build any serious applet:
init()
start()
stop()
destroy()
init()PARAM values and adding GUI
components.
Note: applets can have a default constructor, but it is customary to perform
all initialization in the init method, instead of the default
constructor.
start()init method. It is also called whenever the user returns to
the page containing the applet after having gone off to other pages. This
means that the start method can be called repeatedly, unlike
the init method. For this reason, put the code that you want
executed only once in the init method, rather than in the
start method. For example the start method is
where you usually restart a thread for your applet, for example, to resume
an animation.
If your applet does nothing that needs to be suspended when the user leaves
the current Web page, you do not need to implement this method (or the
stop method discussed next).
stop()
destroy()finalize method for objects, Java is guaranteed
to call this method when the browser shuts down normally. Since applets are
meant to live on an HTML page, you do not need to worry about destroying the
panel. This will happen automatically when the browser shuts down. What you
do need to put in the destroy method is the code for
reclaiming any non-memory dependent resources such as window handles that you
may have consumed. (Of course Java calls stop method before
calling the destroy method if the applet is still active).
paint().
Here's an investigation into how paint() works:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class One extends Applet {
int i = 0;
public void paint(Graphics g) {
i += 1;
System.out.println("paint has been called: " + i + " times.");
}
}
And use a basic HTML file to dispatch the applet.
<html>
<head>
<title>All eyes on the mouse!</title>
</head>
<body>
<applet code=One.class height=300 width=300>
</applet>
</body>
</html>
Now let's make paint work harder.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class One extends Applet {
int i = 0;
public void paint(Graphics g) {
i += 1;
System.out.println("paint has been called: " + i + " times.");
int width = getWidth(), height = getHeight();
for (int line = 0; line < height; line += 3) {
g.drawLine(0, line, width, line); // horizontal line
}
}
}
Now let's introduce some colors, and let's show them.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class One extends Applet {
int i = 0;
Color[] c = { Color.red , Color.yellow, Color.blue , Color.pink,
Color.magenta, Color.green , Color.black, Color.white };
public void paint(Graphics g) {
i += 1;
System.out.println("paint has been called: " + i + " times.");
int width = getWidth(), height = getHeight();
int j = 0;
for (int line = 0; line < height; line += 3) {
g.setColor(c[j % c.length]);
g.drawLine(0, line, width, line);
j += 1;
}
}
}
Now let's paint in one color, but each time another one.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class One extends Applet {
int i = 0;
Color[] c = { Color.red , Color.yellow, Color.blue , Color.pink,
Color.magenta, Color.green , Color.black, Color.white };
public void paint(Graphics g) {
i += 1;
System.out.println("paint has been called: " + i + " times.");
int width = getWidth(), height = getHeight();
for (int line = 0; line < height; line += 3) {
g.setColor(c[i % c.length]);
g.drawLine(0, line, width, line);
}
}
}
Now it is easy to prove that paint is actually optimized. It only refreshes that part of the screen that has just become visible.
Now we add circles.
import java.awt.*; public class Circle {
int x, y, radius;
public Circle(int x, int y, int radius) {
this.x = x; this.y = y; this.radius = radius;
}
public void moveTo(int x, int y) { // x, y coordinates of center
this.x = x - radius;
this.y = y - radius;
}
public void draw(Graphics g) {
g.drawOval(x, y, 2 * radius, 2 * radius);
}
}
And we draw them.
import java.applet.*;
import java.awt.*;
public class One extends Applet {
Circle c = new Circle(20, 20, 10);
public void paint(Graphics g) {
c.draw(g);
}
}
Now let's pay attention to mouse movement.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class One extends Applet implements MouseMotionListener {
Circle c = new Circle(20, 20, 10);
public void init() {
addMouseMotionListener(this);
}
public void paint(Graphics g) {
c.draw(g);
}
public void mouseMoved(MouseEvent e) {
int x = e.getX(), y = e.getY();
c.moveTo(x, y);
repaint();
}
public void mouseDragged(MouseEvent e) {
}
}
And notice that you can leave the circle behind while dragging.
And
here's one last example (which is still instructive, I believe).
This is a simple applet whose purpose is to draw:
import java.applet.*;
import java.awt.*;
import java.util.*;
public class ManyShapes extends Applet
{
// this method overrides the paint method from the Applet class
public void paint(
Graphics g // the Graphics context to draw with
)
{
// create a new number generator
Random r = new Random();
// draw 10000 shapes
for(int i = 0; i < 10000; i++)
{
// generate random values for our shape
int x = r.nextInt()%300;
int y = r.nextInt()%300;
int width = r.nextInt()%300;
int height = r.nextInt()%300;
// set a random color
g.setColor(new Color(r.nextInt()));
// generate a positive number between 0 and 4
int n = Math.abs(r.nextInt()%5);
// draw a shape based on the value of n
switch(n)
{
case(0):
g.draw3DRect(x, y, width, height, true);
break;
case(1):
g.drawRect(x, y, width, height);
break;
case(2):
g.drawOval(x, y, width, height);
break;
case(3):
g.fillRect(x, y, width, height);
break;
case(4):
g.fillOval(x, y, width, height);
break;
// this shouldn't happen; but if it does,
// print a message
default:
System.out.println("Invalid case: " + n);
break;
} // switch
} // for
} // paint
} // ManyShapes
Here's the HTML file:
<html>
<head>
<title>ManyShapes</title>
</head>
<body>
<hr>
<applet code=ManyShapes.class
width=300
height=300>
</applet>
<hr>
</body>
</html>
EXERCISES