N341/N342 Java Applets
|
Modified:
|
Overview
A Java applet is a Java program that can be executed on the browser client.
Java is a modern language with C++ style syntax, supporting object-oriented
programming, dynamic memory management, light-weight threads, GUI design, and is
designed for networked applications. Java programs are compiled into machine
code for the Java Virtual Machine rather than Intel or Apple or other machine
code, browsers implement an interpreter that simulates the JVM. A Java applet is
then a Java program running on the JVM implemented by the browser. Since the JVM
can be implemented on any browser (NetScape and IE do), this offers the
potential for a write once/run anywhere programming language. In reality the JVM
implementation differs slightly from one browser to another (my own experience
with a serious applet is that it runs differently on every operating system just
using Netscape, IE explodes on some machines and works fine on others), or as
some wag said, applets create a write once/debug everywhere programming
language.
The reality is that for implementing highly interactive Web GUIs on clients
that are comparable to Windows, Linux, Apple, etc. the choices are limited to
plug-ins, ActiveX on IE only that are not secure, or Java applets that can in
theory run anywhere safely. Java applets offer a choice of portability
(runs on most browsers), security (restricted from accessing local hardware),
and ease of delivery (does not require registration as does ActiveX or
installation as do plug-ins such as Flash!).
Applets tend to be useful where:
- a high degree of user interactivity is required, such as a game.
Server-side applications are too slow in responding to inputs.
- a rich GUI is required since new objects other than buttons, text box,
radios buttons, lists, etc. can be created.
- application must run on a variety of platforms (it is possible to run
applets outside browsers as regular programs).
Applet Installation
The code of an applet is stored in a file on the server and is automatically
loaded by the browser whenever it encounters an <Applet> tag in the HTML. For
example the following applet was loaded because this HTML contains <applet
code=Box.class width=150 height=150></applet>. The Box.class file
contains the code for the applet, other class files used by the Box
applet would automatically be loaded by the browser also.
Below are several demonstration applets.
- HelloWorld - The obligatory Hello World program as an applet.
- Box - Demonstrates a simple applet that can draw and erase a box.
- Sketch - Demonstrates interaction with user via the mouse.
- Calculator - A familiar application to demonstrate a more complex
user interface and event handling.
- Bounce - Demonstrates a dynamic graphic not possible with
server side programming.
- BounceThread - Demonstrates thread support.
- xyPlot - An applet to produce simple X-Y data plots. It is
of interest because JavaScript is used to call Java methods, allowing data to
be passed between the two programming languages. In the example, the data to
be plotted can be entered from the browser or generated by a the server.
HelloWorld
The simplest applet. Draws the string "Hello World" in the applet window
area. Points of note are:
- Cross-browser incompatibilities - the JavaScript is determines the
browser used and how to define the applet.
- import - Defines a library of classes used by the applet.
- public class HelloWorldApp extends Applet - Defines a new class
HelloWorldApp that inherits from the class Applet.
- paint - Called whenever the applet window is given focus (i.e.
opened).
- drawString("Hello World", 50, 50); - Draws the string in the applet
area at x=50 and y=50.
| HelloWorld.HTM
<script language="Javascript">
var _app = navigator.appName;
if (_app == 'Netscape')
document.write('<embed code="HelloWorldApp.class"',
'width="200"', 'height="200"',
'type="application/x-java-applet;version=1.5.0">');
else if (_app == 'Microsoft Internet Explorer')
document.write('<OBJECT ', 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"',
'width="200"', 'height="200">',
'<PARAM name="code" value="HelloWorldApp.class">',
'</OBJECT>');
else
document.write('<p>Sorry, unsupported browser.</p>');
</script>
HelloWorldApp.java
import java.awt.*;
import java.applet.*;
public class HelloWorldApp extends Applet {
public void
paint(Graphics g) {
g.drawString("Hello World", 50, 50);
}
} |
Exercise 0 - Hello World
Applet
- Copy and paste the HelloWorld.Htm and HelloWorldApp.java to
a virtual drive.
- At the command prompt, compile by: javac HelloWorldApp.java
- From a browser, load the HelloWorld.Htm file.
- Modify the HTML so that a bigger window is used by the applet.
- Modify the Java applet so that the text Hello World is displayed at
a different location.
- Compile the Java by:
Box
A simple applet that can draw a fixed size box or erase it. Demonstrates user
interface design using buttons and line graphics. Java has a built in set of
buttons, list, etc. for implementing a user interface. Points of note are:
- import - Defines a library of classes used by the applet.
- public class Box extends Applet - Defines a new class Box
that inherits from the class Applet.
- public void init() - Always called first to initialize anything in
program such as the user interface.
- add(new Button("Draw Box")); - Place a button on the applet area.
- public boolean action(Event e, Object o) - The event handler where
all events are handled. The e event is for object o.
- o.equals("Draw Box") - Returns true if the object o
is Draw Box.
- drawLine(0, 0, 0, 100); - Draws
a line from (x, y) point (0,0) to (0, 100) in the applet area.
| HTML
<script language="Javascript">
var _app = navigator.appName;
if (_app == 'Netscape')
document.write('<embed code="Box.class"',
'width="200"', 'height="200"',
'type="application/x-java-applet;version=1.5.0">');
else if (_app == 'Microsoft Internet Explorer')
document.write('<OBJECT ', 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"',
'width="200"', 'height="200">',
'<PARAM name="code" value="Box.class">',
'</OBJECT>');
else
document.write('<p>Sorry, unsupported browser.</p>');
</script>
Box.java
import java.awt.*;
import java.applet.*;
public class Box extends Applet
{
public void init()
// Always called first (like main())
{
add(new Button("Draw Box"));
// Place buttons
add(new Button("Erase Box"));
setBackground(Color.white);
}
public boolean action(Event e, Object o) // Executed on any event
{
if (o.equals("Draw Box")) {
Graphics pen = getGraphics();
// Get current graphics (the applet)
pen.setColor(Color.black);
pen.drawLine(0,
0, 0, 100);
pen.drawLine(0,
100, 100, 100);
pen.drawLine(100, 100, 100,
0);
pen.drawLine(100,
0, 0, 0);
}
if (o.equals("Erase Box")) {
Graphics pen = getGraphics();
// Get current graphics (the applet)
pen.setColor(Color.white);
pen.drawLine(0,
0, 0, 100);
pen.drawLine(0,
100, 100, 100);
pen.drawLine(100, 100, 100,
0);
pen.drawLine(100,
0, 0, 0);
}
return true;
}
} |
Exercise 1 - Buttons and
Events
Buttons generate events when clicked. All user interface object events
execute the action method. To demultiplex which object generated the
event, the button caption can be examined as in:
if (o.equals("Draw Box")
To use graphics with drawLine or drawString methods requires a
Graphics object. One way to get the Graphics object representing the
applet is using method getGraphics. For example, to write Hello World:
Graphics g = getGraphics( );
g.drawString("Hello World", 50, 50);
- Copy and paste the Box applet and HTML to a virtual drive.
- Add two buttons:
- One button to print your name.
- The second button to erase your name.
- Compile the Java by:
Sketch
Demonstrates interaction with user via the mouse.
Sketch
Drag to draw
| HTML
<h2>Sketch</h2><br>
<script language="Javascript">
var _app = navigator.appName;
if (_app == 'Netscape')
document.write('<embed code="SketchApp.class"',
'width="200"', 'height="200"',
'type="application/x-java-applet;version=1.5.0">');
else if (_app == 'Microsoft Internet Explorer')
document.write('<OBJECT ', 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"',
'width="200"', 'height="200">',
'<PARAM name="code" value="SketchApp.class">',
'</OBJECT>');
else
document.write('<p>Sorry, unsupported browser.</p>');
</script>
<br>
<i>Drag</i> to draw
SketchApp.java
import java.awt.*;
import java.applet.*;
public class SketchApp extends Applet {
private int startx, starty, endx, endy;
public void init() {
setBackground(Color.yellow);
}
public boolean mouseDown(Event evt, int x, int y) {
startx = x;
starty = y;
return true;
}
public boolean mouseUp(Event evt, int x, int y) {
startx = x;
starty = y;
return true;
}
public boolean mouseDrag(Event evt, int x, int y) {
endx = x;
endy = y;
repaint();
return true;
}
public void update(Graphics g) {
paint(g);
startx = endx;
starty = endy;
}
public void paint(Graphics g) {
g.drawLine(startx, starty, endx, endy);
}
}
|
Exercise 2 - Sketch
- Sketch a line from top to bottom.
- Move down the page till only part of the sketch scrolls off the screen.
- Move up the page to see the complete sketch.
- What's wrong with this implementation?
Calculator
Demonstrates nothing special other than user interaction.
| HTML
<script language="Javascript">
var _app = navigator.appName;
if (_app == 'Netscape')
document.write('<embed code="Calculator.class"',
'width="200"', 'height="200"',
'type="application/x-java-applet;version=1.5.0">');
else if (_app == 'Microsoft Internet Explorer')
document.write('<OBJECT ', 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"',
'width="200"', 'height="200">',
'<PARAM name="code" value="Calculator.class">',
'</OBJECT>');
else
document.write('<p>Sorry, unsupported browser.</p>');
</script>
Calculator.java
import java.awt.*;
import java.applet.*;
public class Calculator extends Applet
{
double accumulator=0.0, operand;
char operation;
TextField display;
Panel p;
public void init()
{ setLayout(new BorderLayout());
display = new TextField("0");
add("North", display);
p = new Panel();
p.setLayout(new GridLayout(4,5));
for(int i=0; i<=9; i++)
p.add(new Button(""
+(char)('0'+i)));
p.add(new Button("+"));
p.add(new Button("-"));
p.add(new Button("*"));
p.add(new Button("/"));
p.add(new Button("="));
p.add(new Button("C"));
add("Center", p);
}
public boolean action(Event e, Object o)
{
if(e.target instanceof Button &&
((String)o).length()==1)
{ char c = ((String) o).charAt(0);
switch (c){
case '0' : case '1' :
case '2' : case '3' : case '4' :
case '5' : case '6' :
case '7' : case '8' : case '9' :
accumulator=accumulator*10+(c-'0');
break;
case '=' : equal();
break;
case 'C' : accumulator
= 0.0; break;
default :
operation = c;
operand = accumulator;
accumulator = 0.0;
}
display.setText("" + accumulator);
}
return true;
}
public void equal()
{ switch (operation)
{ case '+' : accumulator=accumulator+operand; break;
case '-' :
accumulator=operand-accumulator; break;
case '*' :
accumulator=accumulator*operand; break;
case '/' :
accumulator=operand/accumulator; break;
}
}
} |
Exercise 3 - Calculator
- Copy and paste the HTML and the Java named as Calculator.java.
- Make a memory calculator, one that has a button for Memory Store
and another for Memory Recall.
Threads Overview
One useful and interesting model supported by Java is that of light-weight
threads that run within the environment of the main application thread. This
allows multi-threaded applications to operate with relatively low overhead and
corresponding good performance, since threads are part of the language design
rather than being implemented by the operating system, threaded applications are
portable at the code level. Java threads can execute within the same environment
scope so that data can be shared between threads. Synchronization of threads is
achieved using the monitor model (versus tasks in Ada or semaphores in languages
such as C and C++ that rely on operating system calls).
A key use of threads is to handle blocking method invocations. When a
method is invoked it normally does not return until completed (unless an event
such as a mouse clieck occurs) implying that any other program execution is
temporarily stopped. By using individual threads to handle methods that may
block for an unknown (possibly long) period of time, other program functions can
continue.
A working definition of a thread is an execution. All programs have at
least one thread of execution control, Java supports multiple, light-weight
threads of execution. An example of a heavy-weight thread is a single program in
execution where the internal environments of other heavy-weight threads are
isolated from one another. A heavy-weight program can have multiple light-weight
threads, each being switched to execute for a time but then temporarily
suspended while another thread executes. The prime distinction between heavy and
light weight threads are that light weight threads can share a common program
environment, when thread switching occurs between light weight threads there is
less individual thread information to switch since much is common to all. The
key advantages of Java thread support are: 1) thread communication is relatively
easy to program since part of the language, 2) inexpensive in execution since
light weight, and 3) allows a program to handle multiple, concurrent operations
in a relatively platform independent fashion.
A Single Heavy Weight
Thread Example
We'll use a bouncing ball to illustrate differences in multi-threaded
execution. Our first thread example uses a single heavy weight thread to
bounce a single ball off the sides of the display window. The Ball
class implements the ball bouncing, since a single thread is used, only one ball
can be bounced at a time. The most important part of the program is:
public void bounce()
{
for (int i = 1; i <= 1000; i++)
{ move();
try { Thread.sleep(5); } catch(InterruptedException e) {}
}
}
which is invoked once as a normal function call from action() function
by clicking the Toss button. The button click:
- causes an event in the main thread, executing the action()
function,
- the Toss invokes the bounce function,
- the ball is moved ( move is inherited from the basicBall
class),
- the iteration in bounce() moves the ball and includes
Thread.sleep(5); which puts the main, heavy weight thread to sleep for 5
milliseconds, 5/1000 of second so it moves once about every 5/1000 of a
second. Because of the 1000 iterations, the ball bounces for at least 5
seconds.
| HTML
<script language="Javascript">
var _app = navigator.appName;
if (_app == 'Netscape')
document.write('<embed code="Bounce.class"',
'width="640"', 'height="100"',
'type="application/x-java-applet;version=1.5.0">');
else if (_app == 'Microsoft Internet Explorer')
document.write('<OBJECT ', 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"',
'width="640"', 'height="100">',
'<PARAM name="code" value="Bounce.class">',
'</OBJECT>');
else
document.write('<p>Sorry, unsupported browser.</p>');
</script>
Bounce.java
- import java.awt.*;
- import java.applet.*;
- public class Bounce extends Applet
- {
- public void init()
- { add(new Button("Toss"));
- setBackground(Color.white);
- }
-
- public boolean action(Event e, Object o)
- { if (o.equals("Toss"))
- { Ball ball = new Ball(this);
// Create
- ball.bounce();
- }
- return true;
- }
- }
- class Ball extends basicBall
- {
- public Ball(Applet a)
- { super(a);
- }
-
- public void bounce()
// Execute
- { for (int i = 1; i <= 1000; i++)
- { move();
- try { Thread.sleep(5); }
catch(InterruptedException e) {}
- }
- }
- }
|
basicBall.java
import java.awt.*;
import java.applet.*;
public class basicBall
{ Graphics graphics;
Applet applet;
static final int XSIZE = 10;
static final int YSIZE = 10;
int x = 0;
int y = 0;
int dx = 2;
int dy = 2;
public basicBall(Applet a)
{ applet = a;
graphics = applet.getGraphics();
}
public int x() { return x; }
public int y() { return y; }
public void draw()
{ graphics.fillOval(x,y,XSIZE,YSIZE);
}
public void move() {
graphics.setColor(Color.white);
draw();
x += dx;
y += dy;
Dimension d = applet.size();
if (x < 0) { x = 0; dx = -dx; }
if (x + XSIZE >= d.width)
{ x = d.width - XSIZE; dx
= -dx; }
if (y < 0) { y = 0; dy = -dy; }
if (y + YSIZE >= d.height)
{ y = d.height - YSIZE;
dy = -dy; }
graphics.setColor(Color.red);
draw();
}
} |
Exercise 4 - Single Thread
- List the sequence of line(s) executed when Toss button is clicked.
- Which line(s) bounce the ball?
Multiple Threads
With only minor changes to the previous example, multiple light-weight
threads can control many simultaneously bouncing balls. The key changes are:
- Implement the Runnable class by Ball class which inherits
threads in the Ball class, the result is a runnable thread extended to
include bouncing ball behavior. The Ball class has been renamed BallThread.
- In the previous example, the bounce() function bounced the ball
directly by:
public void bounce()
{ for (int i = 1; i <= 1000; i++)
{ move();
try { Thread.sleep(5); } catch(InterruptedException e) {}
}
}
Now the bounce() constructs a new thread then calls the
start() function which in turn invokes the thread's run() function,
which controls the thread execution. The thread usually executes until the
run() function completes executing.
public void bounce()
{ new Thread(this).start();
}
- Where before the function bounce was invoked to bounce a single
ball, the function run is invoked whenever another BallTread is
started. The run is a special name that must be in a Thread
subclass, and must be invoked to start the thread. The run() is
to a thread what main() is to a C program.
public void run()
{ for (int i = 1; i <= 1000; i++)
{ move();
try { Thread.sleep(5); } catch(InterruptedException e) {}
}
}
Click the Toss button rapidly and notice that all the balls appear to
move at the same rate. This is due to the Thread.sleep(5); which suspends
the running thread giving the others a chance to run. The threads are in effect
taking turns running so that each thread makes progress, so that one ball moves
then the next, etc.
BounceThread.java
- import java.awt.*;
- import java.applet.*;
- public class BounceThread extends Applet
- {
- public void init()
- { add(new Button("Toss"));
- setBackground(Color.white);
- }
-
- public boolean action(Event e, Object o)
- { if (o.equals("Toss"))
- { BallThread ballThread = new
BallThread(this);
// Create a thread
-
ballThread.bounce();
- }
- return true;
- }
- }
- class BallThread extends basicBall implements
Runnable
- {
- public BallThread(Applet a)
- { super(a);
- }
- public void bounce()
// Start the thread
- { new
Thread(this).start();
- }
-
- public void run()
// Thread execution
- { for (int i = 1; i <= 1000; i++)
- { move();
- try { Thread.sleep(5); }
catch(InterruptedException e) {}
- }
- }
- }
|
Exercise 5 - Multiple Threads
- List the sequence of lines executed when Toss is clicked the first
time.
- Is this same sequence executed everytime?
- What happens to a thread at the end of the run() method?
- What must occur after new Thread(this).start() is executed, since
you can press Toss repeatedly and another ball starts bouncing?
Controlling Java
Applets from JavaScript
Java applet methods that take 0 or more String parameters can be
called by JavaScript. This is useful for extending the capability of JavaScript
to the level of Java, within the usual security restrictions enforced on
applets. In some ways, this provides much of the same potential as ActiveX for
extending the scripting language within the limitations and safety of applet
security. In addition to applets generally accepted as safe, JavaScript and Java
applets are supported by most browsers making applications more portable.
Simple example - The first example is the HelloWorld applet
that can have a different greeting based upon user form input. The applet has a
public method setGreeting that takes a String parameter, the HTML
supplies the parameter through a method call. The parameter is the value of a
form variable supplied in the HTML. The applet method is invoked through an
onClick event in the user form.
NewHelloWorld.htm
<script language="Javascript">
var _app = navigator.appName;
if (_app == 'Netscape')
document.write('<embed name="Greeter"', 'code="NewHelloWorldApp.class"', 'width="640"', 'height="100"',
'type="application/x-java-applet;version=1.5.0">');
else if (_app == 'Microsoft Internet Explorer')
document.write('<OBJECT ', 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"',
'name="Greeter"', 'width="640"', 'height="100">',
'<PARAM name="code" value="NewHelloWorldApp.class">',
'</OBJECT>');
else
document.write('<p>Sorry, unsupported browser.</p>');
</script>
<form name=formGreeter>
Enter new greeting <input type=text size=40 name="theGreeting">
<input type=button value="Change"
onClick="document.Greeter.setGreeting(theGreeting.value)"><br>
</form>
// NewHelloWorldApp.java
import java.awt.*;
import java.applet.*;
public class NewHelloWorldApp extends Applet {
String greeting = "Hello World";
public void paint(Graphics g) {
g.drawString(greeting, 50, 50);
}
public void setGreeting(String greeting) {
this.greeting = greeting;
repaint();
}
}
|
Exercise 6 - Controlling
Applets
- Copy and paste the HTML into a file on a virtual drive.
- Copy and paste the Java into a file on a virtual drive named
NewHelloWorld.java
- Compile the Java by:
- javac NewHelloWorldApp.java
- Load the HTML file to verify that it works.
- Add a method to the Java applet to draw a line from (0,0) to (150,150).
See the Sketch applet for line
drawing.
- Add a button to the HTML to invoke the new Java method.
Complex example - The following is an example of JavaScript calling a
Java applet method that plots X-Y data. Click Plot to plot the data in
the text boxes. To plot new data, change the text boxes and click Plot.
Java Applet Data Plotter
Separate data with spaces.
| xyPlot.htm
<Title>xyPlot</Title>
<center><h1>Java Applet Data Plotter</h1></center>
<center>
<Body onload='document.DataPlot.xyPlot("1 2 3 4 5", "1 4 9 16 25", "X",
"Y") '>
<script language="Javascript">
var _app = navigator.appName;
if (_app == 'Netscape')
document.write('<embed name="DataPlot"', 'code="DataPlot.class"',
'width="300"', 'height="300"',
'type="application/x-java-applet;version=1.5.0">');
else if (_app == 'Microsoft Internet Explorer')
document.write('<OBJECT ', 'classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"',
'name="DataPlot"', 'width="300"', 'height="300">',
'<PARAM name="code" value="DataPlot.class">',
'</OBJECT>');
else
document.write('<p>Sorry, unsupported browser.</p>');
</script> <b>Seperate data with spaces.</b>
<form name="test">
X Data <input type=text size=40 name="x"
value='1998
1999 2000 2001 2002 2003 2004 2005 2006'>
X Axis <input type=text size=8 name="xAxis" value='Year'><br>
Y Data <input type=text size=40 name="y"
value='100 250 450 700 550 200 -100 -250 -300'>
Y Axis <input type=text size=8 name="yAxis" value='Profits'><br>
<input type=button value="Plot"
onclick="document.DataPlot.xyPlot(x.value,
y.value,xAxis.value, yAxis.value )"><br>
</form>
</center>
</body> |
Java - The xyPlot Java method must be public, and as far as I can
determine, the parameters must be of class String. Due to the program
length it is not given but is available for downloading.
The prototype is:
| public void xyPlot(String x, String y, String xAxis, String yAxis) |
JavaScript/HTML
- supplies the user input interface as four text boxes and a submit button,
- calls the xyPlot Java method with four String parameters
when the page is loaded or the Plot button clicked,
- in this example, sample data is supplied in the text boxes.
- <Body onload='document.DataPlot.xyPlot("1 2 3 4 5", "1 4 9 16 25", "X",
"Y") '> - When the page body is finished loading, the method xyPlot
in Java applet DataPlot is called with the parameters. Note that with a
little imagination, the complete page along with the data to plot, could be
generated by a server rather than being static HTML.
- <Applet code="Plot/DataPlot.class" name='DataPlot' WIDTH=300
HEIGHT=300> - The DataPlot.class is in a subdirectory Plot, the
name of the applet will be DataPlot.
- onclick="document.DataPlot.xyPlot(x.value, y.value,xAxis.value,
yAxis.value )" - When the Plot button is clicked, the xyPlot
Java method is called with the parameters from the four text boxes; x, y,
xAxis, yAxis. This draws the plot.
- To call the xyplot Java applet function when the JavaScript is
loaded:
<Body onload='document.DataPlot.xyPlot("1 2 3 4 5", "1 4 9 16 25",
"X", "Y") '>
<Applet code="Plot/DataPlot.class" name='DataPlot' WIDTH=300
HEIGHT=300>
</Applet> |
Document last modified: