week4 - Andrew.cmu.edu - Carnegie Mellon University

Download Report

Transcript week4 - Andrew.cmu.edu - Carnegie Mellon University

Week Four
• Event Handling
• Inner classes
• Event Handling and Inner
Classes
• GUI Programming
• Threads and Web Servers
Carnegie Mellon University,
Graduate School of Industrial
1
Event Handling
• Used by the Abstract Window Toolkit (AWT) – for basic GUI
programming Java 1.0
• Used by Swing -Better components than AWT Java 2
• Used by JavaBeans -- reusable software components, like
Visual Basic, that can be manipulated
in a builder tool
Carnegie Mellon University,
Graduate School of Industrial
2
Babysitting
A baby in the home needs attention.
Many events surrounding the baby are not easily ignored.
Events can be of different types.
Carnegie Mellon University,
Graduate School of Industrial
3
One possible source of events
Carnegie Mellon University,
Graduate School of Industrial
4
Babysitting
Before responding to an event, a babysitter typically takes note
of the source and the type of event.
Carnegie Mellon University,
Graduate School of Industrial
5
Babysitting
Handler
Event type
Event source
The sitter needs to know both the
event type and the event source.
Carnegie Mellon University,
Graduate School of Industrial
6
Event Handling
The window manager software may generate hundreds of different
events.
Examples include mouse clicks, mouse movements, key strokes,
and timer ticks.
A programmer is typically interested in a small subset of all of the
possible events that may occur.
Carnegie Mellon University,
Graduate School of Industrial
7
Events and Event Objects
• Since events may be of different types but still exhibit some
shared traits (inheritance) Java represents the event classes
in a hierarchy.
• The root class is called java.util.EventObject. The only common
feature shared by all events is a source object. So we find the
following method in the EventObject class :
public Object getSource();
Carnegie Mellon University,
Graduate School of Industrial
8
Some classes and
methods in the event
hierarchy.
Object
EventObject
AWTEvent
ActionEvent
ComponentEvent
String getActionCommand()
InputEvent
boolean isAltDown()
MouseEvent
WindowEvent
Window getWindow()
KeyEvent
int getX()
Carnegie Mellon University,
Graduate School of Industrial
char getKeyChar()
9
Event handling usually involves
three types of objects
• Objects are used to hold and report on information about the event.
• Objects are typically the source of events.
• Objects, called listeners, are used to handle events.
Carnegie Mellon University,
Graduate School of Industrial
10
A mouse
object
Event Source
Example
An event object
that describes,
say, the x and y
coordinate of
where the mouse
was clicked
Event data and methods
Listener
The listener object
has methods that
are called for
particular events
Carnegie Mellon University,
Graduate School of Industrial
11
Example
A mouse
object
A mouse object must
be told who its listener
is.
An event object
that describes,
say, the x and y
coordinate of
where the mouse
was clicked
The event object is sent
to a listener method
Carnegie Mellon University,
Graduate School of Industrial
Implements
MouseListener
The listener object
has methods that
are called for
particular events
12
The Listener
There are different types of Listeners.
MouseListeners
WindowListeners
ScrollBarListeners
Etc..
These Listeners are interfaces. Remember what an interface
provides? If class X implements an interface then class X promises
to provide (at least) the methods declared in the interface.
Carnegie Mellon University,
Graduate School of Industrial
13
Some of the Listener Hierarchy
EventListener
ActionListener
abstract void actionPerformed(ActionEvent e);
MouseListener
KeyListener
abstract void mouseClicked(MouseEvent e)
Carnegie Mellon University,
Graduate School of Industrial
14
A Listener Interface
public interface MouseListener {
void mouseClicked(MouseEvent e);
void mouseEntered(MouseEvent e);
void mouseExited(MouseEvent e);
void mouseReleased(MouseEvent e);
}
//What does it mean if I claim that I implement this interface?
Carnegie Mellon University,
Graduate School of Industrial
15
An Example
// MouseSpyApplet.java
import java.applet.Applet;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
Carnegie Mellon University,
Graduate School of Industrial
16
class MouseSpy implements MouseListener
{ public void mouseClicked(MouseEvent event)
{ System.out.println("Mouse clicked. x = "
+ event.getX() + " y = " + event.getY());
}
public void mouseEntered(MouseEvent event)
{ System.out.println("Mouse entered. x = "
+ event.getX() + " y = " + event.getY());
}
public void mouseExited(MouseEvent event)
{ System.out.println("Mouse exited. x = "
+ event.getX() + " y = " + event.getY());
}
public void mousePressed(MouseEvent event)
{ System.out.println("Mouse pressed. x = "
+ event.getX() + " y = " + event.getY());
}
public void mouseReleased(MouseEvent event)
{ System.out.println("Mouse released. x = "
+ event.getX() + " y = " + event.getY());
}
Carnegie Mellon University,
}
Graduate School of Industrial
I have to provide
ALL of these methods!!
17
public class MouseSpyApplet extends Applet
{ public MouseSpyApplet()
{ MouseSpy listener = new MouseSpy();
addMouseListener(listener);
}
}
Carnegie Mellon University,
Graduate School of Industrial
18
Java Applets need an HTML file.
<html>
<head>
</body>
</head>
<B>Spying on the mouse</b><p>
<applet code="MouseSpyApplet.class" width=400 height=200>
</applet>
</html>
Carnegie Mellon University,
Graduate School of Industrial
19
Another approach
Suppose a friendly sole created this class:
public class MouseAdapter implements MouseListener {
void mouseClicked(MouseEvent e){}
void mouseEntered(MouseEvent e){}
void mouseExited(MouseEvent e){}
void mouseReleased(MouseEvent e){}
}
Now, suppose I extend this class. What must I provide?
Carnegie Mellon University,
Graduate School of Industrial
20
Only those methods that I am interested in.
The other methods, when called, do
nothing. We’ll visit this issue again later.
Carnegie Mellon University,
Graduate School of Industrial
21
Inner Classes
•
•
•
•
Nested Top Level Classes (not inner)
Member Classes
Local Classes
Anonymous Classes
Carnegie Mellon University,
Graduate School of Industrial
22
Nested Top Level Class
• Nested top-level classes are not inner classes.
• Use as a convenient way to group related classes
• Since the class must be static and has no 'this' pointer, it
has no access to the instance data of objects for its
enclosing class.
• It behaves just like a 'normal' class or interface.
Carnegie Mellon University,
Graduate School of Industrial
23
//NestedTopLevelExample.java
class Top {
int i,j;
static class SomeClass { // static makes it top-level nested
int k;
SomeClass() {
System.out.println("Constructing SomeClass");
}
void foo() { System.out.println("Hello"); }
}
Top() {
System.out.println("Constructing a Top object");
}
}
Carnegie Mellon University,
Graduate School of Industrial
24
public class NestedTopLevelExample {
public static void main(String args[]) {
Top myTop = new Top();
Top.SomeClass myObject = new Top.SomeClass();
myObject.foo();
}
}
Output
Constructing a Top object
Constructing SomeClass
Hello
Carnegie Mellon University,
Graduate School of Industrial
25
Member Classes
• Member classes (there is no such thing as a 'member‘
interface)
• This inner class (it's not a top-level class) has no static
keyword and can access the members of each object of
its outer class.
• The class 'appears in every instance'.
•
Carnegie Mellon University,
Graduate School of Industrial
26
•The parent class must declare an instance of an inner
class, before it can invoke the inner class methods, assign
to data fields (including private ones), and so on.
•Unlike nested top-level classes, inner classes are not
directly part of a package and are not visible outside the
class in which they are nested.
• Inner classes are often used for GUI event handlers.
Carnegie Mellon University,
Graduate School of Industrial
27
// MemberClassExample.java
class Top {
int i = 33;
public class SomeClass {
// access the outer object's state.
private int k = i;
SomeClass() {
System.out.println("Constructing SomeClass");
}
void foo() { System.out.println("Hello"); }
}
Top() {
System.out.println("Constructing a Top object");
SomeClass sc = new SomeClass();
System.out.println(sc.k);
}
Carnegie Mellon University,
28
Graduate School of Industrial
}
public class MemberClassExample {
public static void main(String args[]) {
Top myObject = new Top();
}
}
// OUTPUT
Constructing a Top object
Constructing SomeClass
33
Carnegie Mellon University,
Graduate School of Industrial
29
Local Classes
•A Local class is an inner class. Typically, a local class
is declared within a method. It is not a member of an
enclosing class. It is visible only within the block.
•These classes are used primarily as "adapter classes".
• For example, a block of code that creates a Button object
could use a local class to define a simple implementation
of the ActionListener Interface. Then it could instantiate
this simple implementation and pass the resulting object
to the button's ActionListener method, thereby connecting
the button to the "callback" code that is executed when
the button is pressed.
Carnegie Mellon University,
Graduate School of Industrial
30
// Local Class example
class Top {
int i = 33;
Top() {
System.out.println("Constructing a Top object");
// define a class within a method
class Wow {
int t;
Wow() { System.out.println("Building a Wow");
i = 8;
t = 9;
}
}
Wow h = new Wow();
System.out.println(" h.t == " + h.t);
System.out.println(" i == " + i);
}
Carnegie Mellon University,
31
Graduate School of Industrial
}
public class LocalExample {
public static void main(String args[]) {
Top myObject = new Top();
}
}
// OUTPUT
Constructing a Top object
Building a Wow
h.t == 9
i == 8
Carnegie Mellon University,
Graduate School of Industrial
32
Anonymous Classes
• An anonymous class is refinement of inner classes.
• It allows you to combine the definition of the class
with the instance allocation.
• Since it is instantiated in the same expression that defines
it, it can only be instantiated once. This is very similar to
local classes.
• When writing a simple adapter class, the choice between
a named local class and an unnamed anonymous class
typically comes down to a matter of style and code clarity,
rather than any difference in functionality.
•The new class can't have a constructor.
Carnegie Mellon University,
Graduate School of Industrial
33
// Anonymous.java
interface SmallClass {
public void foo();
}
class Top {
int i = 33;
void someMethod(SmallClass s) {
s.foo();
}
void anotherMethod() {
someMethod(new SmallClass() {
public void foo() {
System.out.println("Really fun");
}
}); Carnegie Mellon University,
Graduate School of Industrial
}
34
Top() {
System.out.println("Constructing a Top object");
someMethod(new SmallClass() {
public void foo() {
System.out.println("Strange but fun");
}
});
}
}
Carnegie Mellon University,
Graduate School of Industrial
35
public class Anonymous {
public static void main(String args[]) {
// We can't create interface objects
// error: SmallClass s = new SmallClass();
Top myObject = new Top();
myObject.anotherMethod();
}
}
// OUTPUT
Constructing a Top object
Strange but fun
Really fun
Carnegie Mellon University,
Graduate School of Industrial
36
Event Handling and Inner Classes
register
Source Object
Listener Object
Event object
fire events
After the listener object registers itself with the source
object, the source object calls a method found in the
listener object and passes an object that describes the event.
Carnegie Mellon University,
Graduate School of Industrial
37
Event Handling
Suppose we have a Button object Button b = new Button();
We must determine what events a particular component generates.
A Button component may generate an ActionEvent object.
Button b
ActionEvent
Object
Carnegie Mellon University,
Graduate School of Industrial
38
Implementing a Listener
•We need an object that will listen for the ActionEvent.
•We implement the ActionListener class (this class listens
for ActionEvents from buttons, menus, etc.) and override
its actionPerformed method.
class BabySitter implements ActionListener {
public void actionPerformed(ActionEvent e) {
// handle the event object e in some way
}
}
Carnegie Mellon University,
Graduate School of Industrial
39
Create a BabySitter object
BabySitter sitter = new BabySitter();
sitter
Carnegie Mellon University,
Graduate School of Industrial
40
Registering The Listener
• We want to listen for the ActionEvent
object coming from the button.
• So, we tell the button what object will
listen for the ActionEvent object:
• b.addActionListener(sitter)
Carnegie Mellon University,
Graduate School of Industrial
41
The button and its listener
addActionListener
Button Object
Sitter Object
The button calls the actionPerformed()
method of the sitter object
and passes an ActionEvent object
as a parameter
Carnegie Mellon University,
Graduate School of Industrial
42
Once again but with a window
Hit the X and the program exits
Carnegie Mellon University,
Graduate School of Industrial
43
Create a WindowCloseSitter Class
import javax.swing.*;
import java.awt.event.*;
public class CloseDemo {
public static void main(String[] args) {
JFrame f = new JFrame("Example");
f.setSize(400,100);
f.setVisible(true);
WindowCloseSitter h = new WindowCloseSitter();
f.addWindowListener(h);
}
}
Carnegie Mellon University,
44
Graduate School of Industrial
But we have to implement ALL of the functions !!
class WindowCloseSitter implements WindowListener {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
public void windowClosed(WindowEvent e) { }
public void windowOpened(WindowEvent e) { }
public void windowIconified(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowActivated(WindowEvent e) { }
public void windowDeactivated(WindowEvent e) { }
}
Carnegie Mellon University,
Graduate School of Industrial
45
Java Provides Adapter Classes
•
•
•
•
•
•
•
ComponentAdapter
MouseMotionAdapter
WidowAdapter
ContainerAdapter
MouseAdapter
FocusAdapter
KeyAdapter
Carnegie Mellon University,
Graduate School of Industrial
46
The WindowAdapter class
public abstract class WindowAdapter implements WindowListener {
public void windowClosing(WindowEvent e) {}
public void windowClosed(WindowEvent e) { }
public void windowOpened(WindowEvent e) { }
public void windowIconified(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowActivated(WindowEvent e) { }
public void windowDeactivated(WindowEvent e) { }
}
A built in class -- we already have the empty bodies!!
Carnegie Mellon University,
Graduate School of Industrial
47
The Window again
import javax.swing.*;
import java.awt.event.*;
public class CloseDemo2 extends WindowAdapter {
public static void main(String[] args) {
JFrame f = new JFrame("Example");
f.setSize(400,100);
f.setVisible(true);
f.addWindowListener(new CloseDemo2());
}
public void windowClosing(WindowEvent e) {
System.exit(0);
}
Carnegie Mellon University,
Graduate School of Industrial
}
48
Again with anonymous classes
import javax.swing.*;
import java.awt.event.*;
public class CloseDemo3 {
public static void main(String[] args) {
JFrame f = new JFrame("Example");
f.setSize(400,100);
f.setVisible(true);
f.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
); }
Carnegie Mellon University,
49
Graduate School of Industrial
}
GUI Programming with threads
Java GUI programming and Java Threads
GUI example taken from “Computing Concepts with Java 2” by
Cay Horstmann
Thread examples taken from “The Java Programming Language”
By Arnold and Gosling and from Cay Horstmann’s “Core Java 2
Advanced”
Carnegie Mellon University,
Graduate School of Industrial
50
Frame Windows
A Frame window has a border and a title bar
A Frame window has an addWindowListener method. We can
use this method to add listeners to our frame window.
Carnegie Mellon University,
Graduate School of Industrial
51
An example
javax means Java standard
extension
import javax.swing.*;
import java.awt.event.*;
public class InternetFrameExample {
public static void main(String[] args) {
JFrame f = new InternetFrame("Example");
f.setTitle("Internet browser");
f.show();
}
}
Tell the window manager to
display the frame.
Carnegie Mellon University,
Graduate School of Industrial
52
class InternetFrame extends JFrame {
Add the handler
public InternetFrame(String s){
setSize(300,300);
windowOpened()
widowClosed()
}
windowClosing()
:
private class WindowCloser extends WindowAdapter {
:
WindowCloser listener = new WindowCloser();
addWindowListener(listener);
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}
Carnegie Mellon University,
Graduate School of Industrial
53
Carnegie Mellon University,
Graduate School of Industrial
54
Adding User Interface
Components to a Frame
•Do not draw directly on the surface of a frame.
•Frames have been designed to arrange user interface components.
•User interface components are such things as buttons, menus,
scroll bars, and so on.
•If you want to draw on a frame, draw on a separate component and
then add that component to the frame. The Swing UI toolkit
provides the Jpanel class for this purpose.
Carnegie Mellon University,
Graduate School of Industrial
55
Drawing on a JPanel
To draw on a Jpanel you override the paintComponent method.
Make sure that from within your paintComponent method you
call super.paintComponent(…) so that the superclass method
paintComponent has a chance to erase the existing contents,
redraw the borders and decorations, etc.
Carnegie Mellon University,
Graduate School of Industrial
56
Adding the Panel to the JFrame
• The surface of a Swing frame is covered with four
panes.
• Each of these four has a purpose.
• We are interested in getting access to the
JFrame’s content pane.
• So, call the getContentPane on the JFrame.
• This call returns a Container object.
• Add your Panel object to the content pane
Container.
Carnegie Mellon University,
Graduate School of Industrial
57
Adding a Panel to a JFrame
JFrame
getContentPane()
x = getContentPane (a
contentPane holds
components for display).
x refers to a Container (may
contain other components)
c = a Panel or some other
component.
Add c to x using x’s layout
manager (a content pane uses
Carnegie Mellon University,
58
border
layout)
Graduate School of Industrial
Adding a JTextfield to the
JFrame
JFrame
getContentPane()
cp
class MyFrame extends JFRAME {
private JTextField textField;
public MyFrame() {
Container cp = getContentPane();
textField = new JTextField();
cp.add(textField, “South”);
Carnegie Mellon University,
Graduate School of Industrial
59
We may want to add a listener to
the TextField
JFrame
getContentPane()
cp
Class MyFrame extends JFRAME {
private JTextField textField;
public myFrame() {
Container cp = getContentPane();
textField = new JTextField();
cp.add(textField, “South”);
textField.addActionListener(
new TextFieldListener());
Carnegie Mellon University,
Graduate School of Industrial
60
Output first! -- user enters number of eggs and we draw them
Carnegie Mellon University,
Graduate School of Industrial
61
Strategy
Think about
• What do we want on the screen?
• What events should we listen for?
• What should we do when those events occur?
• What processing will we do when user input arrives?
• What object has responsibilities for what activities?
Think about
• The ‘has-a’ relationship,e.g., the Jframe’s ContentPane “has-a”
Panel and a TextField.
• The ‘is-a’ relationship,e.g., The TextFieldListener ‘is-an’
Carnegie Mellon University,
62
actionListener.
Graduate School of Industrial
// Example
// Eggs.java
We need classes from
the awt, util, and swing
packages.
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
Carnegie Mellon University,
Graduate School of Industrial
63
public class Eggs
{ public static void main(String[] args)
{ EggFrame frame = new EggFrame();
frame.setTitle("Enter number of eggs");
frame.show();
}
}
This thread is done
after creating a frame and
starting up the frame thread.
A frame now exists and is running.
Carnegie Mellon University,
Graduate School of Industrial
64
The EggFrame Constructor
• Set the size of the frame
• Add a listener to listen for the stop event
• Create a JPanel object to draw on and a
JTextField object to interact with the user
via the keyboard
• Add a listener for the JTextField
• Add the Jpanel and the JTextField to the
contentPane container.
Carnegie Mellon University,
Graduate School of Industrial
65
class EggFrame extends JFrame
{
private JTextField textField;
private EggPanel panel;
A listener for the jframe
window
public EggFrame()
{
final int DEFAULT_FRAME_WIDTH = 300;
final int DEFAULT_FRAME_HEIGHT = 300;
setSize(DEFAULT_FRAME_WIDTH,
DEFAULT_FRAME_HEIGHT);
A textField listener
addWindowListener(new WindowCloser());
panel = new EggPanel();
textField = new JTextField();
textField.addActionListener(new TextFieldListener());
Container contentPane = getContentPane();
contentPane.add(panel, "Center");
As before
contentPane.add(textField,
"South");
Carnegie Mellon University,
}
Graduate School of Industrial
66
Event driven programming
The constructor will be called from our main thread.
The other thread operates asynchronously.
What do we mean by asynchronous execution?
Who is running the show?
Don’t programs run sequentially?
We have to think differently.
Carnegie Mellon University,
Graduate School of Industrial
67
The TextField
The TextField object will call us when it detects
an event.
We don’t ‘read the input’. We set up a babysitter to
respond.
The TextField object sends us an event object.
Carnegie Mellon University,
Graduate School of Industrial
68
// Use an inner class to listen on the text field
private class TextFieldListener implements ActionListener {
public void actionPerformed(ActionEvent event)
{
String input = textField.getText();
panel.setEggCount(Integer.parseInt(input));
textField.setText("");
}
}
We do two things when we
have a textfield event.
1) Get the data
2) Tell the panel the number
of eggs to display
Carnegie Mellon University,
Graduate School of Industrial
69
// Use an inner class to listen on the text field
private class TextFieldListener implements ActionListener {
public void actionPerformed(ActionEvent event)
{
String input = textField.getText();
panel.setEggCount(Integer.parseInt(input));
textField.setText("");
}
}
Note how handy the inner class is. Both panel and
textField are available. What if the listener were not
an object of an inner class. how would it get access
to these variables? We can’t just pass the variables on
the call because
we don’t make the call.
Carnegie Mellon University,
70
Graduate School of Industrial
private class WindowCloser extends WindowAdapter
{ public void windowClosing(WindowEvent event)
{ System.exit(0);
}
}
}
This is how we respond when the
close signal is received.
system.exit(0) stops the java
virtual machine. 0 means
normal termination.
Carnegie Mellon University,
Graduate School of Industrial
71
How about the panel object
What are the panel object’s responsibilities?
get input? _____
repaint itself? _____
keep track of the egg count? _____
hold the data it needs to repaint itself? _____
Do we want our panel to inherit properties and methods from any
existing classes? _____
Carnegie Mellon University,
Graduate School of Industrial
72
How about the panel object
What are the panel object’s responsibilities?
get input? No, that’s the TextField’s job.
repaint itself? Sure, that’s its main job.
keep track of the egg count? Yes, better here where it’s
needed
hold the data it needs to repaint itself? Yes
Do we want our panel to inherit properties from any existing
classes? Sure, we want to re-use existing code whenever possible.
Carnegie Mellon University,
Graduate School of Industrial
73
How about the panel object
When should the panel object repaint itself?
What will the panel need to repaint itself?
Who actually calls the paintComponent method?
Carnegie Mellon University,
Graduate School of Industrial
74
How about the panel object
When should the panel object repaint itself?
When a new input arrives from the user.
When the egg count changes.
What will the panel need to repaint itself?
A graphics object to draw on.
Who actually calls the paintComponent method?
While we have to provide a paintComponent method
we don’t call it directly.
It’s called by the Java run-time environment after
we make a call onCarnegie
repaint.
Mellon University,
Graduate School of Industrial
75
class EggPanel extends JPanel
{
public void paintComponent(Graphics g)
{ super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
// draw eggCount ellipses with random centers
Random generator = new Random();
for (int i = 0; i < eggCount; i++)
{ double x = getWidth() * generator.nextDouble();
double y = getHeight() * generator.nextDouble();
Ellipse2D.Double egg = new Ellipse2D.Double(x, y,
EGG_WIDTH, EGG_HEIGHT);
g2.draw(egg);
}
Carnegie Mellon University,
}
Graduate School of Industrial
76
public void setEggCount(int count)
{ eggCount = count;
repaint();
}
private int eggCount;
private static final double EGG_WIDTH = 30;
private static final double EGG_HEIGHT = 50;
}
Carnegie Mellon University,
Graduate School of Industrial
77
Java Threads
• Four kinds of thread programming
• Applications
– A GUI application
– A server application
Carnegie Mellon University,
Graduate School of Industrial
78
Four kinds of thread programming
1) Unrelated threads
2) Related but unsynchronized threads
3) Mutually-exclusive threads
4) Communicating mutually-exclusive
threads
We will look at only the first two kinds.
Carnegie Mellon University,
Graduate School of Industrial
79
Unrelated threads
class Coffee extends Thread {
Coffee(String name) {
super(name);
}
public void run() {
for(int n = 1; n <= 3; n++) {
System.out.println("I like coffee");
yield();
System.out.println(this.getName());
yield();
}
}
}
Carnegie Mellon University,
Graduate School of Industrial
80
class Tea extends Thread {
Tea(String name) {
super(name);
}
public void run() {
for(int n = 1; n <= 3; n++) {
System.out.println("I like tea");
yield();
System.out.println(this.getName());
yield();
}
}
}
Carnegie Mellon University,
Graduate School of Industrial
81
public class Drinks {
public static void main(String args[]) {
System.out.println("I am main");
Coffee t1 = new Coffee("Wawa Coffee");
Tea t2 = new Tea(“Sleepy Time Tea");
t1.start();
t2.start();
System.out.println("Main is done");
}
}
Carnegie Mellon University,
Graduate School of Industrial
82
Output
I am main
Main is done
I like coffee
I like tea
Wawa Coffee
Sleepy Time Tea
I like coffee
I like tea
Wawa Coffee
Sleepy Time Tea
I like coffee
I like tea
Wawa Coffee
Sleepy Time Tea
Main finishes right away
Threads are sharing time
This program has three threads.
Carnegie Mellon University,
Graduate School of Industrial
83
Unrelated Threads Part II
• Using sleep() in unrelated threads
• The call sleep(millis) puts the currently executing thread to
sleep for at least the specified number of milliseconds. "At
least“ means there is no guarantee the thread will wake up
in exactly the specified time. Other thread scheduling can
interfere.
Carnegie Mellon University,
Graduate School of Industrial
84
class Coffee extends Thread {
Coffee(String name) {
super(name);
}
public void run() {
for(int n = 1; n <= 3; n++) {
System.out.println("I like coffee");
try {
sleep(1000); // 1 second
}
catch(InterruptedException e) {}
System.out.println(this.getName());
}
}
}
Carnegie Mellon University,
Graduate School of Industrial
85
class Tea extends Thread {
Tea(String name) {
super(name);
}
public void run() {
for(int n = 1; n <= 5; n++) {
System.out.println("I like tea");
System.out.println(getName());
}
}
}
Carnegie Mellon University,
Graduate School of Industrial
86
public class Drinks2 {
public static void main(String args[]) {
System.out.println("I am main");
Coffee t1 = new Coffee("Wawa Coffee");
Tea t2 = new Tea("China Tea");
t1.start();
t2.start();
System.out.println("Main is done");
}
}
Carnegie Mellon University,
Graduate School of Industrial
87
I am main
Main is done
I like coffee
I like tea
China Tea
I like tea
China Tea
I like tea
China Tea
I like tea
China Tea
I like tea
China Tea
Wawa Coffee
I like coffee
Wawa Coffee
I like coffee
Wawa Coffee
After “I like coffee”,
the coffee thread
goes to sleep and the
tea thread gets to
finish and die.
1 second pausing
after each “I like
coffee”
Carnegie Mellon University,
Graduate School of Industrial
88
Yield() and Sleep()
• Yield() may have no effect on some
implementations.
• The thread scheduler might make no
effort toward fairness.
• The yielding thread may be picked again
even though other threads want a turn.
• It is a good idea to call sleep() instead.
Carnegie Mellon University,
Graduate School of Industrial
89
An Example Without Threads
Black ball bounces for awhile and then stops. If you then click start,
a new ball bounces for awhile and then stops. Close only works
between balls. If the ball is moving and you click close, the close
Carnegie Mellon University,
90
message is queued.
Graduate School of Industrial
// From Cay Horstmann Core Java 2 Advanced
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Bounce
{ public static void main(String[] args)
{ JFrame frame = new BounceFrame();
frame.show();
}
}
Carnegie Mellon University,
Graduate School of Industrial
91
class BounceFrame extends JFrame
{ public BounceFrame()
{ setSize(300, 200);
setTitle("Bounce");
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);
}
} );
Carnegie Mellon University,
Graduate School of Industrial
92
Container contentPane = getContentPane();
canvas = new JPanel();
contentPane.add(canvas, "Center");
JPanel p = new JPanel();
addButton(p, "Start",
new ActionListener()
{ public void actionPerformed(ActionEvent evt)
{ Ball b = new Ball(canvas);
b.bounce();
}
});
Carnegie Mellon University,
Graduate School of Industrial
93
addButton(p, "Close",
new ActionListener()
{ public void actionPerformed(ActionEvent evt)
{ System.exit(0);
}
});
contentPane.add(p, "South");
}
public void addButton(Container c, String title,
ActionListener a)
{
JButton b = new JButton(title);
c.add(b);
b.addActionListener(a);
}
private JPanel canvas;
}
Carnegie Mellon University,
Graduate School of Industrial
94
class Ball
{ public Ball(JPanel b) { box = b; }
public void draw()
{ Graphics g = box.getGraphics();
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
Carnegie Mellon University,
Graduate School of Industrial
95
public void move()
{ Graphics g = box.getGraphics();
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
x += dx;
y += dy;
Dimension d = box.getSize();
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; }
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
Carnegie Mellon University,
Graduate School of Industrial
96
public void bounce()
{ draw();
for (int i = 1; i <= 1000; i++)
{ move();
try { Thread.sleep(5); }
catch(InterruptedException e) {}
}
}
private JPanel box;
private static final int XSIZE = 10;
private static final int YSIZE = 10;
private int x = 0;
private int y = 0;
private int dx = 2;
private int dy = 2;
}
Carnegie Mellon University,
Graduate School of Industrial
97
Bouncing With Threads
The close button works in an instant. Each time the start button
is clicked a new ball appears. The screen above shows four fast
moving bouncing balls.
Carnegie Mellon University,
Graduate School of Industrial
98
We use start() rather than bounce() on the
ball object…
addButton(p, "Start",
new ActionListener()
{ public void actionPerformed(ActionEvent evt)
{ Ball b = new Ball(canvas);
b.start();
}
});
Carnegie Mellon University,
Graduate School of Industrial
99
…and have the Ball class extend Thread
and implement run() rather than bounce().
class Ball extends Thread
:
public void run()
{ try
{ draw();
for (int i = 1; i <= 1000; i++)
{ move();
sleep(5);
}
}
catch(InterruptedException e) {}
}
Carnegie Mellon University,
Graduate School of Industrial
100
Ping Pong
•Adapted from "The Java Programming Language", Arnold
and Gosling
•After a thread is created, you can configure it – set its name,
its initial priority, and so on.
•The start() method spawns a new thread of control based on
the data in the thread object and then returns. Now, the
•Java virtual machine invokes the new thread's run method,
making the thread active.
•When a thread's run method returns, the thread has exited.
•The thread may be manipulated with a number of methods,
including the interrupt() method as shown in this example.
Carnegie Mellon University,
Graduate School of Industrial
101
public class PingPong extends Thread {
private String word;
private int delay;
public PingPong(String whatToSay, int delayTime) {
word = whatToSay;
delay = delayTime;
}
Carnegie Mellon University,
Graduate School of Industrial
102
public void run() {
try {
for(;;) {
System.out.println(word+" ");
sleep(delay);
}
}
catch (InterruptedException e) {
System.out.println("Interrupted!!!!!");
return;
}
}
Carnegie Mellon University,
Graduate School of Industrial
103
public static void main(String args[]) {
PingPong t1 = new PingPong("\tping",33);
t1.start();
PingPong t2 = new PingPong("Pong",100);
t2.start();
try {
Thread.sleep(5000);
}
catch(InterruptedException e) {
// will not be printed
System.out.println("Good morning");
return;
}
Carnegie Mellon University,
Graduate School of Industrial
104
Thread myThread = Thread.currentThread();
for (int t = 1 ; t <= 10; t++)
System.out.println("In Main..." + myThread.getName());
t1.interrupt();
}
}
Carnegie Mellon University,
Graduate School of Industrial
105
C:\McCarthy\threads\PingPong>java PingPong
ping
Main is asleep.
Pong
ping
ping
ping
Pong
ping
ping
ping
For 5 seconds
Pong
ping and pong
ping
take turns sleeping
ping
and running
ping
:
:
Carnegie Mellon University,
106
Graduate School of Industrial
Pong
ping
ping
ping
Pong
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
Interrupted!!!!!
Pong
Pong
Pong
Pong
Pong
:
Main wakes up
Main interrupts
Ping and ping dies.
“Pongs” forever
or until until ctrl-c
Carnegie Mellon University,
Graduate School of Industrial
107
A Thread Application --A Simple Web
Server
• Responds by sending the same file on
each hit
• Creates a new thread on each hit
Carnegie Mellon University,
Graduate School of Industrial
108
// A simple web server
// Responds with the same file on each hit
import java.net.*;
import java.io.*;
import java.util.*;
public class OneFile extends Thread {
static String theData = "";
static String contentType;
static int contentLength;
Socket theConnection;
Carnegie Mellon University,
Graduate School of Industrial
109
// construct each OneFile object with an existing socket
public OneFile(Socket s) {
theConnection = s;
}
// run the following code on each object
public void run() {
try {
// get a PrintStream attached to this socket
PrintStream os = new PrintStream(
theConnection.getOutputStream());
// get a DataInputStream attached to this socket
DataInputStream is = new DataInputStream(
theConnection.getInputStream());
// read a line from the socket
String request = is.readLine();
Carnegie Mellon University,
Graduate School of Industrial
110
// HTTP/1.0 and later send a MIME header
if(request.indexOf("HTTP/") != -1) {
// we need to read the rest of the MIME header
while(true) {
String thisLine = is.readLine();
if(thisLine.trim().equals("")) break;
}
// respond to the client
os.print("HTTP/1.0 200 OK\r\n");
// send the date
Date now = new Date();
os.print("Date: " + now + "\r\n");
// send our name
os.print("Server: OneFile 1.0\r\n");
Carnegie Mellon University,
Graduate School of Industrial
111
// send the contentLength
os.print("Content-length: " + contentLength + "\r\n");
// send the content type
os.print("Content-type: " + contentType + "\r\n\r\n");
}
// send the file in the string
os.println(theData);
theConnection.close();
}
catch(IOException e) {
}
}
Carnegie Mellon University,
Graduate School of Industrial
112
// main loads the file and creates the object on every hit
public static void main(String args[] ) {
int thePort;
ServerSocket ss;
Socket theConnection;
FileInputStream theFile;
// cache the file
try {
// open file and create a DataInputStream
theFile = new FileInputStream(args[0]);
DataInputStream dis = new DataInputStream(theFile);
Carnegie Mellon University,
Graduate School of Industrial
113
// determine the content type of this file
if(args[0].endsWith(".html") || args[0].endsWith(".htm") ) {
contentType = "text/html";
}
else {
contentType = "text/plain";
}
// read the file into the string theData
try {
String thisLine;
while((thisLine = dis.readLine()) != null) {
theData += thisLine + "\n";
}
}
catch(Exception e) {
System.err.println("Error " + e);
}
Carnegie Mellon University,
114
}
Graduate School of Industrial
catch(Exception e) {
System.err.println(e);
System.err.println("usage: java onefile filename port");
System.exit(1);
}
// set the port to listen on
try {
thePort = Integer.parseInt(args[1]);
if(thePort < 0 || thePort > 65535) thePort = 80;
}
catch(Exception e) {
thePort = 80;
}
Carnegie Mellon University,
Graduate School of Industrial
115
// create a server socket
try {
ss = new ServerSocket(thePort);
System.out.println("Accepting connections on port " +
ss.getLocalPort());
System.out.println("Data to be sent:");
System.out.println(theData);
while(true) {
// stop and wait for a connection
Socket socketTemp = ss.accept();
// we have a socket so create a handler
OneFile fs = new OneFile(socketTemp);
// start the handler running
fs.start();
}
}
catch(IOException e) {System.out.println("Socket error"); }
}
}
Carnegie Mellon University,
Graduate School of Industrial
116