Lecture Notes Twenty-Two:
Overview of Applets.
Here's an overview of applets from the Java tutorial.
Here's the basic framework of 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.
- when variables are involved it's called shadowing.
|
|
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.
|
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.
Lab assignment 12: Take a look at the pictures below. Choose
one that you like. Write an applet that draws that picture. The lab
notes on Thursday this week will contain this lab assignment.
Last updated: Jun 18, 2001 by Adrian German for A201