|
Second Summer 2002
|
Lab Notes Ten: Overview of applets.
Here's an overview of applets from the Java
tutorial.
Here's the basic framework for an applet:
import java.applet.*;
import java.awt.*;
public class Simple extends Applet {
public void paint(Graphics g) {
for (int i = 0; i < 20; i++) {
g.drawString("This is a test.", 20 + 10 * i, 20 + 10 * i);
}
}
}
Here's what you do to install it:
frilled.cs.indiana.edu%emacs Simple.java
frilled.cs.indiana.edu%javac Simple.java
frilled.cs.indiana.edu%emacs simple.html
frilled.cs.indiana.edu%cat simple.html
<html><head><title>Testing a simple applet</title></head><body bgcolor=white>
<applet code=Simple width=200 height=200>
</applet>
</body></html>
frilled.cs.indiana.edu%appletviewer simple.html
And here it is in action.
Let's now clarify how this works.
| A class gives us a description, a list of features that an object of that class should have.
| By features we mean what kind of data members and method members it should have. |
|
By extending a class we extend our original description, and specify additional features.
|
An object of the extended class has all the features
listed in the original class and the class that extends it.
|
|
An object of the original class has the features listed in the original class.
|
That's what we started from, anyway.
|
This is the reason for which we say that if class B extends
class A every object of type B is also an object
of type A.
|
Just put on a pair of blinkers.
|
But an object of type A is not of type
B (objects of type B have additional features,
listed in the description of class B).
|
Objects of type B are more specialized.
|
|
Another way to remember this is in this way:
|
... if Goalkeeper extends Player we can
use an object of type Goalkeeper everywhere we need
to use a Player
|
... any Player
|
... but not the other way around.
|
|
This is one kind of polymorphism.
|
In our discussion in class we have distinguished between:
- object references
- actual objects
|
| Both have a type. |
Objects are anonymous, and we refer to them by names
(or object references). |
|
Extending classes is a very simple concept.
|
Creating composite objects from composite descriptions is as easy as
putting the two descriptions together,
|
|
... unless we use the same names for different features
(class members of the same kind: data, or methods) in the two descriptions.
|
When the name of two methods collide overriding happens.
|
|
Which method gets invoked is determined through dynamic
method lookup.
|
When variables are involved it's called shadowing, and
we haven't studied it much.
|
|
A few examples will help clarify these concepts.
|
|
class Player {
void fun() {
System.out.println("Having fun as a Player.");
}
}
class Goalkeeper extends Player {
void fun() {
System.out.println("Having fun as a Goalkeeper.");
}
}
public class One {
public static void main(String[] args) {
System.out.println("Welcome to Program One.");
Player meola = new Goalkeeper();
meola.fun();
Goalkeeper higuita = new Goalkeeper();
higuita.fun();
((Player)higuita).fun();
}
}
|
Here's what you get when you run the program:
|
You see then,
|
frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
Welcome to Program One.
Having fun as a Goalkeeper.
Having fun as a Goalkeeper.
Having fun as a Goalkeeper.
frilled.cs.indiana.edu%
|
... that it's the type of the object
(and not that of its reference) that really matters.
|
If either A or B do not define
fun() then there's no overriding involved,
and no dynamic method lookup is involved.
|
|
But it is instructive to cover the three alternatives to the situation described above.
|
In total: four cases.
|
Case 2. Player does not define fun().
|
Only objects of type Goalkeeper referenced through object references of type Goalkeeper will be able
to invoke fun().
|
Casting an object of type Goalkeeper to type Player and asking for fun()
|
... will get you into trouble early (as early as compile time).
|
Case 3. Goalkeeper does not define fun().
|
Objects of type Goalkeeper inherit fun() from being Players (but
they don't have own fun).
|
Case 4: Neither Player nor Goalkeeper define fun().
|
In that case there's really nothing to talk about.
|
|
To summarize, looking up a method for invocation involves taking into account the
class of the object and the class of its reference (casting included here).
|
The object reference's class determine the method unless the object's class also
defines a method with the same name, in which case that's the one that will be invoked.
|
class Player {
void fun() {
System.out.println("Having fun as a Player.");
}
}
class Defender extends Player {
}
class Fullback extends Defender {
void fun() {
System.out.println("Having fun as a Fullback.");
}
}
public class Two {
public static void main(String[] args) {
System.out.println("Welcome to Program Two");
Defender dooley = new Defender();
dooley.fun(); // fun inherited (Player)
Fullback baresi = new Fullback();
baresi.fun(); // Fullback has its own fun
Defender tresor = new Fullback();
tresor.fun(); // type Fullback overrides the fun that
// Defender inherited from Player
Player rijkaard = new Fullback();
rijkaard.fun(); // the fun defined in Fullback is used
// over the one defined in Player, since
// the type of the object rijkaard points
// to (that class) has own fun
}
}
frilled.cs.indiana.edu%java Two
Welcome to Program Two
Having fun as a Player.
Having fun as a Fullback.
Having fun as a Fullback.
Having fun as a Fullback.
frilled.cs.indiana.edu%
Once you override a function the only way you can get to it is through a super reference.
|
You can't get to it from outside the class (through casting).
|
|
Overriding is a stronger notion than shadowing.
|
If you shadow a variable you can still get to it from outside by casting.
|
|
But we don't want to talk about shadowing here.
|
We never used it this semester.
|
|
We have used overriding.
|
We redefined paint.
|
Let's simulate how paint works.
|
Indeed, let's analyze that.
|
|
Before we do that, let's make two final points.
|
One refers to super.
|
super is a kind of casting.
|
It allows us to put one pair of blinkers right away.
|
this is a reference to the current object.
|
... of the same type as the object's class.
|
|
And now the program.
|
Can you annotate it and explain what happens?
|
class Frame {
protected String myGC = "The Graphics Context from class Frame";
protected int width, height;
protected boolean visible;
protected void resize(int w, int h) {
setSize(w, h);
refresh();
}
protected void refresh() {
paint(myGC);
}
protected void setVisible(boolean tF) {
visible = tF;
paint(myGC);
}
protected void setSize(int w, int h) {
width = w;
height = h;
}
public void paint(String gc) {
System.out.println("Frame: I use\n " + gc + " \nto draw my images.");
}
}
public class Picture extends Frame {
public void paint(String gc) {
System.out.println("Picture: I use\n " + gc + " \nto draw my images.");
}
public static void main(String[] args) {
Frame f = new Picture(); // you
f.setSize(100, 200); // see this
f.setVisible(true); // in many places...
user(f); // you never ever see this
// but you know it happens
}
private static void user(Frame f) {
f.resize(200, 400);
// minimal interaction by the user simulated here
}
}
- no packages are used
- we are simulating a
Frame
- we simulate the
user too
|
If you understand how the code above works then
|
|
|
|
- you understand overriding of methods
- you understand why we need to override
paint when doing graphics
- you understand how
paint gives you access to a graphics context
|
Also note: protected is like private,
but allowing inheritance of the variable or method.
|
I believe you, but that doesn't tell me much right now.
Still, I will keep it in the back of my mind.
|
Now we have the following examples, for you to practice with them:
1. A Simple Applet
Create a file One.html with the following contents.
<HTML>
<HEAD>
<TITLE>Applet One</TITLE>
</HEAD>
<BODY>
<P>Here is my <U>first applet</U>.</P>
<APPLET CODE="One.class" WIDTH=300 HEIGHT=300>
</APPLET>
<P> Its title is <I>"Picasso in disbelief"</I>.</P>
</BODY>
</HTML>
Create a file One.java with the following contents.
import java.applet.Applet;
import java.awt.*;
public class One extends Applet {
public void paint (Graphics g) {
Graphics2D g2 = (Graphics2D)g;
Rectangle a = new Rectangle(5, 10, 20, 30);
g2.draw(a);
a.translate(15, 25);
g2.draw(a);
}
}
Compile One.java and look at One.html with
either Netscape or an appletviewer.
2. Graphical Shapes
Create a file Two.html with the following contents.
<HTML>
<HEAD>
<TITLE>Applet Two</TITLE>
</HEAD>
<BODY>
<P>Here is my <U>second applet</U>.</P>
<APPLET CODE="Two.class" WIDTH=300 HEIGHT=300>
</APPLET>
<P> Its title is <I>"Graphical Shapes"</I>.</P>
</BODY>
</HTML>
Create a file Two.java with the following contents.
import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
public class Two extends Applet {
public void paint (Graphics g) {
Graphics2D g2 = (Graphics2D)g;
Ellipse2D.Double m = new Ellipse2D.Double(5, 10, 150, 80);
g2.draw(m); // an ellipse
int x = 90;
int y = 90;
int diam = 70;
Ellipse2D.Double q = new Ellipse2D.Double(x, y, diam, diam);
g2.draw(q); // a circle
Line2D.Double segment = new Line2D.Double(15, 150, 55, 90);
g2.draw(segment); // a line
Point2D.Double start = new Point2D.Double(20, 155);
Point2D.Double stop = new Point2D.Double(60, 95);
segment = new Line2D.Double(start, stop);
g2.draw(segment); // another line
}
}
Compile Two.java and look at Two.html with
either Netscape or an appletviewer.
3. Color and Shapes
Create a file Three.html with the following contents.
<HTML>
<HEAD>
<TITLE>Applet Three</TITLE>
</HEAD>
<BODY>
<P>Here is my <U>third applet</U>.</P>
<APPLET CODE="Three.class" WIDTH=300 HEIGHT=300>
</APPLET>
<P> Its title is <I>"Colored Graphical Shapes"</I>.</P>
</BODY>
</HTML>
Create a file Three.java with the following contents.
import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
public class Three extends Applet {
public void paint (Graphics g) {
Graphics2D g2 = (Graphics2D)g;
Color magenta = new Color(1.0F, 0.0F, 1.0F);
g2.setColor(magenta);
Ellipse2D.Double m = new Ellipse2D.Double(5, 10, 150, 80);
g2.draw(m); // an ellipse
g2.fill(m); // fill it with the current color
// magenta is still current color here
int x = 90;
int y = 90;
int diam = 70;
g2.setColor(Color.red); // predefined color
Ellipse2D.Double q = new Ellipse2D.Double(x, y, diam, diam);
g2.draw(q); // a circle
g2.fill(q); // fill it with the current color
g2.setColor(Color.blue); // another predefined color
Line2D.Double segment = new Line2D.Double(15, 150, 55, 90);
g2.draw(segment); // a line
Point2D.Double start = new Point2D.Double(20, 155);
Point2D.Double stop = new Point2D.Double(60, 95);
segment = new Line2D.Double(start, stop);
g2.draw(segment); // another line
// current color is blue here
}
}
Compile Three.java and look at Three.html with
either Netscape or an appletviewer.
4. Text in Applets
Create a file Four.html with the following contents.
<HTML>
<HEAD>
<TITLE>Applet Four</TITLE>
</HEAD>
<BODY>
<P>Here is my <U>fourth applet</U>.</P>
<APPLET CODE="Four.class" WIDTH=300 HEIGHT=300>
</APPLET>
<P> Its title is <I>"Applet Applet"</I>.</P>
</BODY>
</HTML>
Create a file Four.java with the following contents.
import java.applet.Applet;
import java.awt.*;
public class Four extends Applet {
public void paint (Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.drawString("Applet", 50, 160);
final int HUGE_SIZE = 36; // fotn point size
String message = "Applet"; // actual text
// create Font object then call setFont on it
Font hugeFont = new Font("Serif", // font face name
Font.BOLD, // style
HUGE_SIZE); // point size
g2.setFont(hugeFont); // now g2 will write that way
g2.setColor(Color.green); // set color to predefined green
g2.drawString(message, 50, 100); // then write string
}
}
Compile Four.java and look at Four.html with
either Netscape or an appletviewer.
5. Simple Drawing
Create a file Five.html with the following contents.
<HTML>
<HEAD>
<TITLE>Applet Five</TITLE>
</HEAD>
<BODY>
<P>Here is my <U>fourth applet</U>.</P>
<APPLET CODE="Five.class" WIDTH=300 HEIGHT=300>
</APPLET>
<P> Its title is <I>"Happy Hour"</I>.</P>
</BODY>
</HTML>
Create a file Five.java with the following contents.
import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
public class Five extends Applet {
public void paint (Graphics g) {
Graphics2D g2 = (Graphics2D)g;
Ellipse2D.Double e1 = new Ellipse2D.Double( 75, 40, 30, 70);
Ellipse2D.Double e2 = new Ellipse2D.Double(115, 40, 30, 70);
Ellipse2D.Double c1 = new Ellipse2D.Double( 85, 85, 15, 15);
Ellipse2D.Double c2 = new Ellipse2D.Double(125, 85, 15, 15);
Ellipse2D.Double n = new Ellipse2D.Double(55, 120, 110, 25);
Arc2D.Double m =
new Arc2D.Double(-40, -120, 300, 300, 230, 80, Arc2D.OPEN);
g2.draw(e1);
g2.draw(e2);
g2.fill(c1);
g2.fill(c2);
g2.draw(n);
g2.draw(m);
}
}
Compile Five.java and look at Five.html with
either Netscape or an appletviewer.
What comes next is your:
A201/A597
LAB ASSIGNMENT TEN
Take a look at the pictures below. Choose
one that you like. Write an applet that draws that picture.
More notes from the past:
one,
two.
Last updated: Jul 25, 2002 by Adrian German for A201