Spring Semester 2003


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.
Consider this:
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.

Here's another example:
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  
  } 
}

Let's run it.
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%
Predictable. I think so.

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
  } 

}
Notice: I am impressed.

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: Apr 3, 2003 by Adrian German for A201