You are on page 1of 72

Applets

Event Handling
Threads
and more in Java
Sami Khuri
Mathematics & Computer Science
Department
Creating the “First” Applet
• Create a Java source file: First.java
• Compile First.java.
The Java compiler creates the Java bytecode
file First.class in the same directory.
• Create an HTML file First.html, for example,
that includes First.class.
• Run the applet in a Java-enabled browser or a
Java applet viewing program.
• java.lang.Object
|
+----java.awt.Component
|

+----java.awt.Container
|
+----java.awt.Panel |
+----
java.applet.Applet
• AWT: Abstract Windowing Toolkit
Applets
• Methods defined in the class Applet:
– init(): Applet is being loaded by browser.
Used for one-time initialization.
– start(): Browser entered page containing applet
– stop(): Browser leaves page containing applet
– destroy(): Applet is discarded by browser.
• paint() is used for drawing on applets.
It is a method in the class Component.
Java-enabled Browser
When a Java-enabled browser encounters an
<APPLET> tag, it:
– reserves a display area of the specified width
and height for the applet
– loads the bytecodes for the specified Applet
subclass
– creates an instance of the subclass
– calls the instance's init() and start() methods.
HyperText Markup Language
• An HTML documents contains tags that
specify formatting instructions.
• An HTML tag is enclosed in angle
brackets: example <BODY> and </BODY>
• The width and height (in pixels) of the area
in which the applet is displayed is included
in the html file.
Inheriting from above classes
• Some methods in Component: add(),
remove() and setLayout(): controls the positions &
sizes of components.
• Applets inherit the drawing and event handling
methods from AWT Component class to produce
user interfaces.
– Drawing: images, control of color and font. UI
components: buttons, etc..
– Event handling: detecting & responding to mouse dragging,
button pushing, key pressing,..
Component, Container, and Panel
• From AWT Container, applets get methods to
hold components & use layout managers.
• Panels and applets can only be displayed on
other graphical surfaces.
• A panel must be added to another container in
order to be displayed.
• A component is added to a container by using
add() from the Container class.
Security Restrictions
Restrictions imposed on applets loaded over
the network. The applet cannot:
– Dynamically load native code libraries.
– Read from or write to the local file system.
– Make network connections to any computer
except to the one from which it obtained the
code.
– Read certain system properties.
– Start a printing job.
More Applet Capabilities
• Applets can make network connections to the
host from which they came.
• Applets that are loaded from the local file
system (from a directory in the user's
CLASSPATH) have none of the restrictions
that applets loaded over the network do.
• Applets can load data files (show images) and
play sounds.
Displaying Images
• The code base, returned by the Applet
getCodeBase() method, is a URL that
specifies the directory from which the
applet's classes were loaded.
• The document base, returned by the Applet
getDocumentBase() method, specifies the
directory of the HTML page that contains
the applet.
Example on Displaying Images
• Images must be in GIF or JPEG format.
• Example: Image
file yawn.gif is in directory “images”. To create
an image object “nekopicture” that contains
“yawn.gif”: Image
nekopicture = new Image nekopicture =
getImage(getCodeBase(),
"images/yawn.gif");
Playing Sounds
• The AudioClip interface in the Applet class
provides basic support for playing sounds.
• Sound format: 8 bit, 8000 Hz, one-channel, Sun
".au" files.
• Methods in AudioClip that need to be
implemented in the applet:
loop(): starts playing the clip repeatedly
play() & stop() to play & stop the clip.
Inheritance tree of applets & frames
Object

Component

Canvas

Label Container

List

Button

Scrollbar Panel Window


TextComponent

Checkbox Applet Frame

Choice
Event Handling
• With event-driven programming, events are
detected by a program and handled
appropriately
• Events: moving the mouse
clicking the button
pressing a key sliding the
scrollbar thumb choosing an
item from a menu
Three Steps of Event Handling
1 Prepare to accept events
import package java.awt.event
2 Start listening for events
include appropriate methods
3 Respond to events
implement appropriate abstract
method
1. Prepare to accept events
• Import package java.awt.event
• Applet manifests its desire to accept events
by promising to “implement” certain methods
• Example:
“ActionListener” for Button events
“AdjustmentListener”
for Scrollbar events
2. Start listening for events
• To make the applet “listen” to a particular
event, include the appropriate
“addxxxListener”.
• Examples:
addActionListener(this)
shows that the applet is interested in
listening to events generated by
the pushing of a certain button.
2. Start listening for events (cont)
• Example
addAdjustmentListener(this)
shows that the applet is
interested in listening to events
generated by the sliding of a
certain scroll bar thumb.
• “this” refers to the applet itself - “me” in
English
3. Respond to events
• The appropriate abstract methods are
implemented.
• Example:
actionPerformed() is automatically
called whenever the user clicks the
button. Thus,
implement actionPerformed() to respond to
the button event.
3. Respond to events (cont)
• Example:
adjustmentValueChanged()
is automatically invoked whenever the
user slides the scroll bar thumb.
So adjustmentValueChanged()
needs to be implemented.
• In actionPerformed(ActionEvent evt),
ActionEvent is a class in java.awt.event.
StatBar pan2

statement
north

center ranger

south
leftMsg centerValue rightMsg

pan1 pan3
Threads
• A lightweight sequential flow of control
that shares an address space and resources
with other threads.
• A thread, unlike processes (heavyweight),
has a low context switching time.
• Threads are indispensable for sockets,
image holding, and animation.
Threads in Java
• Traditionally, threads are implemented at the
system level, separate from the programming
language.
• Java is a language and a runtime system and
threads are integrated in both.
• The keyword synchronize is used to make a
block of code accessible to at most one
thread at a time.
Purpose of Threads
• Making a User Interface more responsive.
• When one method can use the partial output
of another without waiting for the first one to
finish. Example:
image-loading and image-displaying
methods.
• Any type of application that lends itself to
concurrency.
How to create threads
• There are two ways of creating threads in Java:
1) Extend the “Thread” class
We can instantiate the class Thread as many
times as desired to achieve multi-threading.
2) Implement the “Runnable” interface
Since multiple inheritance is not allowed in Java,
this method is used when the program already
extends another class (Ex. Applets)
1) Extend the Thread class
• Create a subclass of java.lang.Thread:
public class MyThread extends Thread {
public void run() { \\put code here
}
}
• Instantiate MyThread:
MyThread myTrd;
myTrd.start(); // calls run() in MyThread
Methods in Class Thread
• Three primary methods to control a thread:
– public native synchronized void start()
prepares a thread to run
– public void run()
actually performs the work of the thread
– public final void stop()
to terminate the thread. The thread also dies
when run() terminates.
start() & run() in Thread
• start() causes the thread to begin execution
and the Java Virtual Machine calls run().
Thus, we never have to call run() explicitly.
• The result is that two threads are running
concurrently: the current thread which
returns from the call to start() and the thread
that executes run().
Other Methods in Thread
• Other important methods in Thread include:
– suspend() and resume()
– sleep(mls) which causes the thread to
temporarily stop execution for mls milliseconds
– yield() which causes the executing thread
object to temporarily pause and allow other
threads to execute
– getName() and getPriority()
Class Thread Priorities
• The class Thread has three fields:
– MAX_PRIORITY
– MIN_PRIORITY
– NORM_PRIORITY: the default priority
assigned to a thread
• A new created thread has its priority
initially set equal to the priority of the
creating thread.
2) Creating a thread by using
Runnable Interface
• Instantiate Thread and pass it “this” (the
applet) as a parameter.
• Use the method start() to start running the
instantiated thread.
• Place all the important code for the
instantiated thread in the run() method.
• Set the instantiated thread to “null” in the
stop() method.
Implement Runnable interface
• Create a class that implements Runnable:
public class MyFoo extends Applet
implements Runnable;
• Runnable is an interface in java.lang that
contains only one method: run().
• Multiple inheritance is not allowed in Java,
thus this method of creating threads is used
when MyFoo already extends another class.
The Life Cycle of a Thread
running

start()
New Thread Runnable Not Runnable

run() terminates

Dead
In and Out of Runnable
Out of Runnable Back to Runnable
• sleep() is invoked. • Specified number of
milliseconds elapsed.
• wait() is invoked (for a • An object notifies the
specified condition to waiting thread that the
be satisfied). condition is satisfied.
• Thread is blocked on • I/O event the thread is
I/O. blocked on, is
completed.
sleep
Done
sleeping
new start
blocked
suspend resume

wait notify
runnable
Block
on I/O
I/O
complete
stop

dead

Thread States from Core Java. Drawn by Ping Wu


Managing Threads
• Launching threads and letting them compete
for computer resources, in an uncontrolled
fashion, may lead to very unpleasant results.
• A typical application involves two or more
threads that share a common resource: file or
block of memory, where one thread tries to
modify the resource while that resource is
still being used by another thread.
Simple Model of a Bank [Horton97]
• A very small bank consists of:
– a bank: a computer that performs operations on
accounts
– clerk1: processes credits (deposits)
– clerk2: processes debits (withdrawals)
• Each clerk can communicate directly with the
bank
• Initially, the bank has only one customer
Credits

clerk1

theBank

theAccount Credit operations

Debit operations

Computer operations
are overlapped

Debits

clerk2
Four Classes of the Bank Model
• public class Account field:
balance getBalance() and
setBalance(balance)
• class Bank where credit & debit operations are
performed and balance is updated.
public void credit(Account theAcc,
int amt) public void debit(Account theAcc, int
amt)
Clerk Class
• public class Clerk implements Runnable
Bank theBank // The employer
// Types of transactions
// Details of the current transaction
public void doCredit(Account theAcc, int amt)
public void doDebit(Account theAcc, int amt)
public void run()
public boolean isBusy() //done with transactions?
Driver Class
• public class BankOperation
public static void main(String[] args) //
initialization (balance, transactionCount) //
create account, bank and clerks //
create clerk1Thread and clerk2Thread and
start them off //
generate transactions of each type and pass
them to the appropriate clerk // wait until
clerks are done & output results
Running the Example
• Original balance : $ 500
Total credits : $1252
Total debits : $ 852
Final balance : $ 100
Should be : $ 900
• The problem: One operation is retrieving the
account balance while another operation is
still in the process of amending it.
Synchronization
The objective of synchronization is to make
sure that when several threads need access to
a shared resource, only one thread can access
it at any given time.
Use synchronized at the
– method level: declare methods to be
synchronized
– block of code level: declare some code to be
synchronized
Synchronizing Methods [Bank_SyncM]
• One solution: declare the operations in class
Bank as being synchronized [see Bank_SyncM]
synchronized public void credit(Account theAcc, int amt) {
int balance = theAcc.getBalance(); …
balance = balance + amt; // update balance
theAcc.setBalance(balance); // put it back in the bank
}
synchronized public void debit(Account theAcc, int amt) //
same as above except for: balance = balance - amt
Synchronizing Methods
• Only one of the synchronized methods in a class
object can be executing at any time.
synchronized public void method1() {
// code for the method }
synchronized public void method2() {
// code for the method }
…… // can also have none synchronized methods which will
operate the usual way (not “protected”)
synchronized public void method3() {
// code for the method } …..
Synchronizing Blocks of Code
• Specify a block of statements in the program as
synchronized:
synchronized(myObject) {
statement; statement; ... } //
synchronized with respect to myObject
• Any other statements in the program that are
synchronized with myObject cannot execute
while the above statements are executing.
Synchronizing Code [Bank_SyncB]
• Other solution: declare the code in the methods
to be synchronized [see Bank_SyncB]
public void credit(Account theAcc, int amt) {
synchronized(the Acc)
{ int balance = theAcc.getBalance(); … }
}
public void debit(Account theAcc, int amt) {
synchronized(the Acc)
{ int balance = theAcc.getBalance(); … }
}
Handling Multiple Accounts
[Bank_SyncB]
• Bank_SyncB handles multiple accounts
• Had we left the synchronization of the
methods (rather than the block of code), no
debit operation of any kind would have
been able to be carried out while a credit
operation is in progress, and vice versa.
• Synchronization of a block of code prevents
overlapping of operations on the same
account, and that is what we want.
Thread Organization [Tan95]
• The possible organization of threads:
– dispatcher/worker model: an idle worker thread
is chosen by the dispatcher thread for the
incoming job
– team model: each thread works on its own
request
– pipeline model: threads cooperate with each
other in a sequential fashion. [see Figure]
Dispatcher thread Worker
thread

Request for Request for Request for


work arrives work arrives work arrives

(a) (c)
(b)

Three organizations of threads in a process. (a) Dispatcher/worker model


(b) Team model (c) Pipeline model. From Tanenbaum’s text. Drawn by Ping Wu.
Flickering
• Flickering invariably occurs with animation.
• The reason behind flickering is the way Java
paints and repaints each single frame of the
applet.
• Calling repaint() results in a call to update()
which in turn results in a call to paint().
• Flickering is caused by update().
update() and Flickering
• update() performs two functions:
– It fills the screen with the current background
color of the applet. This is what is normally
termed as “clearing” the screen.
– It calls paint() which then draws the contents of
the current frame onto the screen.
• Flickering is a result of the quick alternation
between the above two functions.
Quick Alternation of Functions
• The quick alternation of the parts of the
frame that do not change between clearing
the screen and drawing the current contents
of the frame, will cause flickering.
• In essence, what we see in quick
successions are the screen background color
and the current contents of the frame (being
displayed several times per seconds).
Avoiding Flickering
• The major two ways of avoiding (reducing)
flickering in Java applets are:
– Overriding update() so as not to clear the screen
at all or to clear only the parts of the screen that
have been changed since the last alternation.
– Double-buffering which is achieved by
overriding both: update() and paint(). It consists
in drawing the current contents on a graphics
surface that is not on the applet screen and then
copying the surface on the applet screen.
Overriding update()
• update() is a method in the Component class
• Recall that update() clears the screen and
calls paint().
• To avoid clearing the screen, we simply
override update() by adding update() to the
“flickering program”, in which we only have
a call to paint(). Thus the clearing task of the
original update() is eliminated.
Overriding update() (cont.)
Thus instead of the update() method of
Component in which we have:
public void update(Graphics g) {
// code for clearing the screen
paint(g);
} we’ll simply have:
public void update(Graphics g) {
paint(g);
}
Double-Buffering
• Double buffering consists:
– in creating a second surface (an offscreen
buffer) on which we perform all the drawing
(and clearing) and then
– the contents of the offscreen buffer are
transferred (“blitted”: bit block transferred) onto
the applet’s surface.
• It is called double buffering because we are
switching between two drawing buffers.
Five Steps of Double-Buffering
• The five steps of double buffering are:
1) Create an offscreen buffer by declaring an
Image object (offScreenImage) to hold the
image and a Graphics object
(offScreenGraphics) to hold the graphics
context.
2) Create an image and a graphics context for the
offscreen buffer (usually done by overriding
init()).
Five Steps of Double-Buffering

3) Perform all the painting on the offscreen buffer


instead of the applet’s surface (i.e., instead of
the main graphics buffer). It is usually done by
overriding paint().
4) Copy the contents of the offscreen buffer to the
applet’s surface.
Five Steps of Double-Buffering
5) Use dispose() to clean up the graphics context that
was created for the offscreen buffer. It is usually
done by overriding destroy():

public void destroy()


{
offScreenGraphics.dispose();
}
Exceptions
• An exception is an event that occurs during the
execution of a program that prevents the
continuation of the normal flow of instructions.
• The purpose of exception handling is to make it
possible for the program to either attempt to
recover from the problem, or at worst shut down
the program in a graceful manner, whenever an
exception occurs.
Exceptions: An Example
The program contains code which attempts
to divide by zero or tries to access an array
element by using an index that is too small
or too large. These are runtime exceptions.
Common terminology states that when this
happens, the system throws an exception. If
an exception is not caught, a runtime error
may occur.
Advantages of Exception
Handling
• Separating error handling code from
“regular” code. Logical
flow of program gets lost due to the
cluttering of the modified program.
• Propagating errors up the call stack.
Propagate notification up to calling method.
• Grouping error types & error differentiation.
Who throws exceptions?
• Java provides the capability to detect and
handle exceptions.
• The exception can be thrown either by the
system or by code created by the
programmer.
• There is a long list of exceptions, called
“checked” exceptions, which will be thrown
automatically by the Java system.
The Class Throwable
• When an exceptional condition causes an
exception to be thrown, that exception is an object
derived, either directly, or indirectly from the class
Throwable.
• The interpreter and many different methods in
many different classes throw exceptions and
errors.
• Error and Exception are subclasses of Throwable.
public  class  java.lang.Throwable extends  java.lang.Object
{
// Constructors
    public Throwable(); 
    public Throwable(String  message);  

    // Methods
    public Throwable fillInStackTrace();        
    public String getLocalizedMessage();
public String getMessage(); 
    public void printStackTrace();      
    public void printStackTrace(PrintStream  s); 
public void printStackTrace(PrintWriter s);
    public String toString();   
}
Error and Exception Classes
Object

Throwable

Error Exception

... RunTimeException ...

Exceptions we should not catch Exceptions we can catch


Results from catastrophic events Compiler checks to see if the code
or conditions (JVM runs out of handles these exceptions (except for
memory; or class definition not RunTimeException)
found at load time)
Subclasses of Throwable
• An Error indicates that a non-recoverable
error has occurred that should not be
caught. They usually cause the Java
interpreter to display a message and exit. 
• An Exception indicates an abnormal
condition that must be properly handled to
prevent program termination.
Handling Exceptions
Exception handling in Java is done through
try / catch / finally statements.
The catch and finally clauses are responsible
for exception handling and for the clean-up
operations.
1) Design code such that you try to execute a
block of code. Enclose the statements that
might cause an exception in a try block.
Handling Exceptions (cont)
2) Provide code (after the try block) to catch
& process the exception object. Each catch
block handles the type of exception
indicated by its argument - the name of a
class that inherits from the Throwable class.
The first catch clause that has an argument
of the appropriate type in invoked. The
block of code then handles the exception.
Handling Exceptions (cont)
3) Use the finally block to clean up and
release system resources (e.g. closing files).
Java runtime system executes the finally
block regardless of what happens within the
try block.
Remark: A try statement must have at least
one catch block or one finally block.

You might also like