CS 4773 Object Oriented Systems
Applets


Previous Topic: The Java Language

Introduction
Testing Applets
The Applet Tag
Passing Parameters to Applets
Applet Initialization
Repainting
The Graphics Context
Some Graphics Methods
Writing Text
A Simple Applet: T1
Java 1.1 Event Model Start of class: Thursday, January 22
Buffering
The Applet T2
The Applet T3
The Applet T4
The Applet T5
Class Modifiers
Method and Field Modifiers

Next Topic: Layouts


Introduction

Applets are programs meant to be run by a browser.

Applets and applications have a different structure.

An application has a public method called main which is started by the interpreter when the program is loaded. An applet is a public class which extends the Applet class. It usually has a method called paint which displays something on the screen. Here is an example of an applet:

import java.awt.*;
import java.applet.*;
public class HelloWorldApplet extends Applet {
   public void paint(Graphics g) {
      g.drawString("Hello World!", 20, 20);
   }
}
This writes the string ``Hello World!'' on the screen starting at position with (x,y) coordinates (20,20).

(0,0) is in the upper left corner.


Testing Applets

The appletviewer is used to run applets.

You pass to the appletviewer the name of an HTML file which has the tag applet and the name of a file containing the compiled class.

< applet code="HelloWorldApplet" width=200 height = 40 >
< /applet >
This displays the applet in a box 200 pixels wide and 40 pixels high.

In fact, for testing, it is convenient to put both the source of the applet and the HTML in the same file.

The HTML code is put inside a comment so that it is ignored by the Java compiler.

The appletviewer ignores anything not in the scope of the applet tag.

Put the following in a file called HelloWorldApplet.java

/*
 * < applet code="HelloWorldApplet" width=200 height = 40 >
 * < /applet >
*/
import java.awt.*;
import java.applet.*;
public class HelloWorldApplet extends Applet {
   public void paint(Graphics g) {
      g.drawString("Hello World!", 20, 20);
   }
}


To compile:
javac HelloWorldApplet.java

To run:
appletviewer HelloWorldApplet.java

This produces the following:

Click Here to run this applet.


The Applet Tag

< APPLET
   [CODEBASE = codebaseURL]
    CODE = appletClassFile 
   [ALT = alternateText] 
   [NAME = appletInstanceName]
    WIDTH = pixels
    HEIGHT = pixels
   [ALIGN = alignment]
   [VSPACE = pixels]
   [HSPACE = pixels]
>
[< PARAM NAME = AttributeName VALUE = AttributeValue > ] 
[< PARAM NAME = AttributeName VALUE = AttributeValue > ] 
...
[HTML displayed in the absence of Java]
< /APPLET >
The required fields are: Some of the optional fields are:

Passing Parameters to Applets

The following is HTML code which starts an applet and passes 2 parameters.
/*
 * < applet code="T1" width=200 height = 100 >
 * < PARAM NAME = fontsize VALUE = 30 >
 * < PARAM NAME = message VALUE = hello >
 * < /applet >
*/
The values are passed to the Java code as strings and so they may have to be converted.

The following Java code might be used for this example:

Serif_Fontsize = 
   Integer.parseInt(getParameter("fontsize"));
Serif_String = getParameter("message");
The above examples leave out the error checking.

Applet Initialization

void init() is called first.
Use this to initialize your variables.

void start() is called after init.
It is called each time the applet's HTML document is displayed on the screen, for example if a browser revisits a page.

void paint(Graphics g) is called by the AWT when it thinks it is necessary, say when an applet is uncovered.

void update(Graphics g) is called by the AWT when you call repaint()
You should probably override is since if first fills the applet with the default background color causing the screen to flash.

void stop() is called when the browser leaves the page containing the applet's HTML.
Use this to suspend your threads and restart them with start().

void destroy() is called when your applet needs to be removed from memory. This should free up your resources.


Repainting

The paint(Graphics g) method is used by the AWT to repaint the applet when it thinks it is necessary.

This should redraw the entire applet.

The update(Graphics g) is (eventually) called in response to a call to repaint().

Several calls to repaint may result in a single call to update.

A call to repaint(long time) is a request to call update within time milliseconds.

It may not be honored if the system is busy.

Why not call paint yourself?

You do not have the g to pass to it.


The Graphics Context

The Graphics class is part of java.awt.

A Graphics object cannot be created with new.

It can only be created from another graphics object.

Graphics newGC;
Graphics currentGC;
Image current_image;

/* Crate an image of size 100 by 100 */
current_image = createImage(100,100);

/* Create a graphics context */
currentGC = current_image.getGraphics();
/* Set this one to draw in green */
currentGC.setColor(Color.green);

/* Create another one from the first */
newGC = currentGC.create();
/* Set this one to draw in light red */
newGC.setColor(new Color(255,200,200));

Some Graphics Methods

void drawRect(int left_x, int top_y, int width, int height)

void fillRect(int left_x, int top_y, int width, int height)

void drawOval(int x, int y, int width, int height)

void fillOval(int x, int y, int width, int height)

void drawArc(int x, int y, int width, int height,
            int startAngle, int arcAngle)

void fillArc(int x, int y, int width, int height,
            int startAngle, int arcAngle)

void drawLine(int x1, int y1, int x2, int y2)

void drawPolygon(int xPoints[], int yPoints[], int nPoints)

void fillPolygon(int xPoints[], int yPoints[], int nPoints)

Writing Text

Choosing a font:

Starting with Java 1.1, the names of the default standard fonts have been changed. The three standard names are:

/* 12 point MonoSpaced bold font */
myGC1.setFont(new Font("MonoSpaced",Font.BOLD,12));

/* 20 point Serif font */
myGC2.setFont(new Font("Serif",Font.PLAIN,20));
To write text use

void drawString(String str, int x, int y)

myGC1.drawString("Hi there",10,20);
myGC2.drawString("Hi there",10,60);
Information about the size of a string in a font can be obtained using FontMetrics
FontMetrics fm;

fm = getFontMetrics(myGC1.getFont());
ascent = fm.getMaxAscent();
descent = fm.getDescent();
width = fm.stringWidth("How are you");

A Simple Applet

/* < applet code="T1" width=200 height = 100 >
 * < PARAM NAME = fontsize VALUE = 30 >
 * < PARAM NAME = message VALUE = hello >
 * < /applet > */
import java.awt.*;
import java.applet.*;

public class T1 extends Applet {

   Image myimage;
   Graphics myGC1;
   Graphics myGC2;
   int sizex = 150;
   int sizey = 80;
   int Serif_Fontsize;
   String Serif_String;

   public void paint(Graphics g) {
      g.drawImage(myimage,0,0,this);
   }

   public void init() {
      Serif_Fontsize = Integer.parseInt(getParameter("fontsize"));
      Serif_String = getParameter("message");
      myimage = createImage(sizex,sizey);
      myGC1 = myimage.getGraphics();
      myGC2 = myimage.getGraphics();
                          /* 12 point MonoSpaced bold font */
      myGC1.setFont(new Font("MonoSpaced",Font.BOLD,12));
                     /* Serif_Fontsize point Serif font */
      myGC2.setFont(new Font("Serif",Font.PLAIN,Serif_Fontsize));
      myGC1.setColor(Color.blue);
      myGC2.setColor(Color.red);

      myGC1.drawString("Hi there",10,20);
      myGC2.drawString(Serif_String,10,60);
      myGC1.drawRect(100,20,30,10);
      myGC2.fillRect(100,60,30,10);

      repaint();
   }
}
This produces the following:

Click Here to run this applet.




Lecture on January 20 ended here.

The Java 1.1 Event Model

The event model has changed from Java 1.0 to Java 1.1.

Any object that can generate an event, can send that event to another object, or to a collection of objects. An object that generates an event uses an addXListener method to register an object to receive its events.

An object receives an event with a corresponding method by implementing the XListener interface. This must contain the appropriate method for handling the event.

For example, buttons generate Action events. A button, PushMe sets the current applet to receive its events be executing PushMe.addActionListener(this).

The applet must implement the ActionListener interface and the events are received by the actionPerformed method.

We have seen examples of this in the first two homework assignments.

There are 11 Listener interfaces. A class that implements one of these interfaces must implement a collection of methods. The Listener interfaces and the corresponding methods are:

Listener interfaces may have as many as 7 methods, and all have to be implemented if the interface is implemented. However, any of these methods may have empty bodies.

For those interfaces with more than one method, the toolkit also provides an Adapter class which implements all of these with an empty body.


Buffering

The idea: draw into an image that is not being displayed.

When done, display the entire image.

Some useful methods:

In class Component

Image createImage(int width, int height)
creates a new image of a given size.

In class Image

Graphics getGraphics()
creates a graphics context for this image.

In class Graphics

Graphics create()
returns a new graphics context which is a copy of this one.

boolean drawImage(Image img, int x, int y, ImageObserver)
draws the image with its top corner at (x,y)
Typical usage: drawImage(im, 0, 0, this)


The Applet T2.java

This example draws a rectangle each time a mouse button is pushed.

/*
 * < applet code="T2" width=200 height = 100 %gt
 * < /applet >
*/
import java.awt.*;
import java.applet.*;
import java.awt.event.*;

// This simple applet draws some text and a circle and
// then waits for mouse events.  It draws a red rectangle
// at the position of a mouse up.
public class T2 extends Applet implements MouseListener {

   Image background;
   Image foreground;
   Graphics foreGC;
   int sizex;
   int sizey;
   int rectangle_count = 0;
   int last_rect_x;
   int last_rect_y;
   int rect_width = 30;
   int rect_height = 10;

   public void paint(Graphics g) {
      g.drawImage(foreground,0,0,this);
   }

   public void init() {
      Graphics myGC1;
      Graphics myGC2;
      sizex = getBounds().width;
      sizey = getBounds().height;
      background = createImage(sizex,sizey);
      foreground = createImage(sizex,sizey);
      myGC1 = background.getGraphics();
      myGC2 = background.getGraphics();
      foreGC = foreground.getGraphics();
                          /* 12 point MonoSpaced bold font */
      myGC1.setFont(new Font("MonoSpaced",Font.BOLD,12));
                                 /* 20 point Serif font */
      myGC2.setFont(new Font("Serif",Font.PLAIN,20));
      myGC1.setColor(new Color(200,200,200));
      myGC1.fillRect(0,0,sizex,sizey);
      myGC1.setColor(Color.blue);
      myGC2.setColor(Color.green);
      foreGC.setColor(Color.red);

      myGC1.drawString("Hi there",10,20);
      myGC2.drawString("Hi there",10,60);
      myGC1.fillOval(100,30,20,20);
      foreGC.drawImage(background,0,0,this);

      repaint();
      addMouseListener(this);
      System.out.println("init done");
   }

   public void mouseClicked(MouseEvent e) {
   }

   public void mousePressed(MouseEvent e) {
      showStatus("Down at ("+e.getX()+","+e.getY()+")");
      repaint(1);
   }
 
   public void mouseReleased(MouseEvent e) {
      int x;
      int y;
      x = e.getX();
      y = e.getY();
      foreGC.fillRect(x,y,rect_width,rect_height);
      last_rect_x = x;
      last_rect_y = y;
      rectangle_count++;
      show_rectangle_count();
      repaint(1);
   }
 
   public void mouseEntered(MouseEvent e) {
   }
 
   public void mouseExited(MouseEvent e) {
   }
 
 
   void show_rectangle_count() {
      if (rectangle_count == 0)
         showStatus("No rectangles drawn yet");
      else
         showStatus("Rectangles: "+rectangle_count+
            ", Last at ("+last_rect_x+","+last_rect_y+")");
   }
}

Click Here to run this applet.


T3.java

This is similar to T2.java but it erases the old rectangle before drawing the new one.

   public void mouseReleased(MouseEvent e) {
      int x;
      int y;
      x = e.getX();
      y = e.getY();
      foreGC.drawImage(background,0,0,this);   // This line is the only change
      foreGC.fillRect(x,y,rect_width,rect_height);
      last_rect_x = x;
      last_rect_y = y;
      rectangle_count++;
      show_rectangle_count();
      repaint(1);
   }
Click Here to run this applet.

T4.java

If you watch at T3.java running, you will see a flashing of the screen when the new rectangle is drawn.

If we run T3 with a larger window it becomes more obvious. T4 is identical to T3, except that the region is bigger and the flashing is more apparent.

Click Here to run the T3a applet with a window size of 800 by 500 instead of 200 by 100.

T4 is identical to T3 but overrides update to prevent the flashing

   public void update(Graphics g) {
      paint(g);
   }
Click Here to run the T4 applet.


T5.java

T5.java is similar to T4 but it drags the rectangle around when the mouse button is held down.

In order to capture mouse mootion events, you need to implement the MouseMotionListener interface, add the applet as a listener with addMouseMotionListener, and have the appropriate methods.

   public void mouseMoved(MouseEvent e) {
   }
 
   public void mouseDragged(MouseEvent e) { 
      mouseReleased(e); 
   }
Click Here to run the T5 applet.


Class Modifiers

abstract final public private < empty >

Method and Field Modifiers

public protected private < empty > final static synchronized native

Next topic: Layouts