home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java 1.2 How-To
/
JavaHowTo.iso
/
code
/
ch04.txt
< prev
next >
Wrap
Text File
|
1998-12-14
|
35KB
|
1,723 lines
Clock.java:
import java.awt.*;
import java.applet.*;
import java.util.*;
import java.text.*;
/*
* class for applet/application
*/
public class Clock extends Applet implements Runnable {
/*
* the instance of Thread for checking the time periodically
*/
Thread thread = null;
SimpleDateFormat formatter;
Date currentDate;
/*
* saved values used to draw only when things have changed
*/
int lastxs=0;
int lastys=0;
int lastxm=0;
int lastym=0;
int lastxh=0;
int lastyh=0;
/**
* sets the background color to light gray
*/
public void init(){
this.setBackground(Color.lightGray);
}
/**
* draws the clock face
* @param g - destination graphics object
*/
public void paint (Graphics g) {
int xh, yh, xm, ym, xs, ys, s=0,m=10, h=10, xcenter, ycenter;
String Today;
currentDate = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("s",Locale.getDefault());
try{
s=Integer.parseInt(formatter.format(currentDate));
}catch(NumberFormatException n){
s=0;
}
formatter.applyPattern("m");
try{
m=Integer.parseInt(formatter.format(currentDate));
}catch(NumberFormatException n){
m=10;
}
formatter.applyPattern("h");
try{
h=Integer.parseInt(formatter.format(currentDate));
}catch(NumberFormatException n){
h=10;
}
xcenter=100;
ycenter=100;
xs = (int)(Math.cos(s * 3.14f/30 - 3.14f/2) * 45 + xcenter);
ys = (int)(Math.sin(s * 3.14f/30 - 3.14f/2) * 45 + ycenter);
xm = (int)(Math.cos(m * 3.14f/30 - 3.14f/2) * 40 + xcenter);
ym = (int)(Math.sin(m * 3.14f/30 - 3.14f/2) * 40 + ycenter);
xh = (int)(Math.cos((h*30 + m/2) * 3.14f/180 - 3.14f/2) * 30
+ xcenter);
yh = (int)(Math.sin((h*30 + m/2) * 3.14f/180 - 3.14f/2) * 30
+ ycenter);
// Draw the circle and numbers
g.setFont(new Font("TimesRoman", Font.PLAIN, 14));
g.setColor(Color.blue);
g.drawOval (xcenter-50, ycenter-50, 100, 100);
g.setColor(Color.darkGray);
g.drawString("9",xcenter-45,ycenter+3);
g.drawString("3",xcenter+40,ycenter+3);
g.drawString("12",xcenter-5,ycenter-37);
g.drawString("6",xcenter-3,ycenter+45);
// Erase if necessary, and redraw
g.setColor(Color.lightGray);
if (xs != lastxs || ys != lastys) {
g.drawLine(xcenter, ycenter, lastxs, lastys);
}
if (xm != lastxm || ym != lastym) {
g.drawLine(xcenter, ycenter-1, lastxm, lastym);
g.drawLine(xcenter-1, ycenter, lastxm, lastym);
}
if (xh != lastxh || yh != lastyh) {
g.drawLine(xcenter, ycenter-1, lastxh, lastyh);
g.drawLine(xcenter-1, ycenter, lastxh, lastyh);
}
g.setColor(Color.darkGray);
g.drawLine(xcenter, ycenter, xs, ys);
g.setColor(Color.red);
g.drawLine(xcenter, ycenter-1, xm, ym);
g.drawLine(xcenter-1, ycenter, xm, ym);
g.drawLine(xcenter, ycenter-1, xh, yh);
g.drawLine(xcenter-1, ycenter, xh, yh);
lastxs=xs; lastys=ys;
lastxm=xm; lastym=ym;
lastxh=xh; lastyh=yh;
}
/*
* called when the applet is started
* create a new instance of Thread and start it
*/
public void start() {
if(thread == null) {
thread = new Thread(this);
thread.start();
}
}
/*
* called when the applet is stopped
* stops the thread
*/
public void stop() {
thread = null;
}
/*
* the thread itself
* sleeps for 100ms and forces a repaint
*/
public void run() {
while (thread != null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
repaint();
}
thread = null;
}
/**
* override the default update method to avoid flickering
* caused by unnecessary erasing of the applet panel
* @param g - destination graphics object
*/
public void update(Graphics g) {
paint(g);
}
/**
* application entry point
* not used when run as an applet
* create a new window frame and add the applet inside
* @param args[] - command-line arguments
*/
public static void main (String args[]) {
Frame f = new Frame ("Clock");
Clock clock = new Clock ();
f.setSize (210, 230);
f.add ("Center", clock);
f.show ();
clock.init ();
clock.start ();
}
}
MultiThread.java:
import java.applet.Applet;
import java.awt.*;
/**
* class LineColors holds 24 color values
*/
class LineColors {
/**
* color[] array holds the colors to be used
*/
Color color[];
/**
* class constructor
* initializes the color array using an arbitrary algorithm
*/
public LineColors () {
color = new Color[24];
int i, rgb;
rgb = 0xff;
for (i=0; i<24; i+=1) {
color[i] = new Color (rgb);
rgb <<= 1;
if ((rgb & 0x1000000) != 0) {
rgb |= 1;
rgb &= 0xffffff;
}
}
}
}
/**
* class describing one line segment
*/
class Segment {
/*
* x1, y1 - starting coordinates for this segment
* x2, y2 - ending coordinates for this segment
* dx1,...dy2 - velocities for the endpoints
* whichcolor - the current index into color array
* width, height - width and height of bounding panel
* LC - instance of LineColors class
*/
double x1, y1, x2, y2;
double dx1, dy1, dx2, dy2;
int whichcolor, width, height;
LineColors LC;
/**
* class constructor
* initialize endpoints and velocities to random values
* @param w - width of bounding panel
* @param h - height of bounding panel
* @param c - starting color index
* @param lc - instance of LineColors class
*/
public Segment (int w, int h, int c, LineColors lc) {
whichcolor = c;
width = w;
height = h;
LC = lc;
x1 = (double) w * Math.random ();
y1 = (double) h * Math.random ();
x2 = (double) w * Math.random ();
y2 = (double) h * Math.random ();
dx1 = 5 - 10 * Math.random ();
dy1 = 5 - 10 * Math.random ();
dx2 = 5 - 10 * Math.random ();
dy2 = 5 - 10 * Math.random ();
}
/*
* increment color index
* calculate the next endpoint position for this segment
*/
void compute () {
whichcolor += 1;
whichcolor %= 24;
x1 += dx1;
y1 += dy1;
x2 += dx2;
y2 += dy2;
if (x1 < 0 || x1 > width) dx1 = -dx1;
if (y1 < 0 || y1 > height) dy1 = -dy1;
if (x2 < 0 || x2 > width) dx2 = -dx2;
if (y2 < 0 || y2 > height) dy2 = -dy2;
}
/**
* draw the line segment using the current color
* @param g - destination graphics object
*/
void paint (Graphics g) {
g.setColor (LC.color [whichcolor]);
g.drawLine ((int) x1, (int) y1, (int) x2, (int) y2);
}
}
/**
* The applet/application proper
*/
class Lines extends Panel implements Runnable {
/*
* width, height - width and height of bounding panel
* Nlines - number of line segments to be displayed
* lines - array of instances of Segment class
* LC - instance of LineColors class
*/
int width, height;
final int NLines = 4;
Segment lines[] = new Segment[NLines];
LineColors LC = new LineColors ();
/*
* instance of thread for this line
*/
Thread thread;
/**
* init is called when the applet is loaded
* save the width and height
* create instances of Segment class
*/
public void init () {
width = 200;
height = 200;
thread = new Thread (this);
thread.start ();
int i;
for (i=0; i<NLines; i+=1)
lines[i] = new Segment (width, height, (2*i) % 24, LC);
}
/**
* recompute the next endpoint coordinates for each line
* invoke paint() method for each line
* @param g - destination graphics object
*/
public void paint (Graphics g)
{
int i;
g.setColor (Color.black);
g.drawRect (0, 0, width-1, height-1);
for (i=0; i<NLines; i+=1) {
lines[i].compute ();
lines[i].paint (g);
}
}
/*
* the thread proper
* calls paint() every 50ms
*/
public void run()
{
Graphics g = getGraphics();
while (true) {
paint (g);
try {
Thread.sleep (50);
} catch(InterruptedException e) { }
}
}
}
/*
* the applet/application proper
* creates two instances of Lines and starts them
* as separate threads
*/
public class MultiThread extends Applet {
/*
* the instances of Lines
*/
Lines lines1;
Lines lines2;
/*
* called when the applet is loaded
*/
public void init () {
setLayout (new GridLayout (2, 1, 0, 0));
lines1 = new Lines ();
lines2 = new Lines ();
add (lines1);
add (lines2);
lines1.setSize (200, 100);
lines2.setSize (200, 100);
lines1.init ();
lines2.init ();
}
/**
* application entry point, unused when run as an applet
* create window frame and add applet inside
* @param args[] - command-line arguments
*/
public static void main (String args[]) {
Frame f = new Frame ("Colored lines");
f.setLayout (new GridLayout (2, 1, 0, 0));
f.setSize (200, 200);
Lines lines1 = new Lines ();
Lines lines2 = new Lines ();
f.add (lines1);
f.add (lines2);
f.show ();
lines1.init ();
lines2.init ();
}
}
MultiThread.java:
import java.applet.Applet;
import java.awt.*;
/**
* class LineColors holds 24 color values
*/
class LineColors {
/**
* color[] array holds the colors to be used
*/
Color color[];
/**
* class constructor
* initializes the color array by using an arbitrary algorithm
*/
public LineColors () {
color = new Color[24];
int i, rgb;
rgb = 0xff;
for (i=0; i<24; i+=1) {
color[i] = new Color (rgb);
rgb <<= 1;
if ((rgb & 0x1000000) != 0) {
rgb |= 1;
rgb &= 0xffffff;
}
}
}
}
/**
* class describing one line segment
*/
class Segment {
/*
* x1, y1 - starting coordinates for this segment
* x2, y2 - ending coordinates for this segment
* dx1,...dy2 - velocities for the endpoints
* whichcolor - the current index into color array
* width, height - width and height of bounding panel
* LC - instance of LineColors class
*/
double x1, y1, x2, y2;
double dx1, dy1, dx2, dy2;
int whichcolor, width, height;
LineColors LC;
/**
* class constructor
* initialize endpoints and velocities to random values
* @param w - width of bounding panel
* @param h - height of bounding panel
* @param c - starting color index
* @param lc - instance of LineColors class
*/
public Segment (int w, int h, int c, LineColors lc) {
whichcolor = c;
width = w;
height = h;
LC = lc;
x1 = (double) w * Math.random ();
y1 = (double) h * Math.random ();
x2 = (double) w * Math.random ();
y2 = (double) h * Math.random ();
dx1 = 5 - 10 * Math.random ();
dy1 = 5 - 10 * Math.random ();
dx2 = 5 - 10 * Math.random ();
dy2 = 5 - 10 * Math.random ();
}
/*
* increment color index
* calculate the next endpoint position for this segment
*/
void compute () {
whichcolor += 1;
whichcolor %= 24;
x1 += dx1;
y1 += dy1;
x2 += dx2;
y2 += dy2;
if (x1 < 0 || x1 > width) dx1 = -dx1;
if (y1 < 0 || y1 > height) dy1 = -dy1;
if (x2 < 0 || x2 > width) dx2 = -dx2;
if (y2 < 0 || y2 > height) dy2 = -dy2;
}
/**
* draw the line segment using the current color
* @param g - destination graphics object
*/
void paint (Graphics g) {
g.setColor (LC.color [whichcolor]);
g.drawLine ((int) x1, (int) y1, (int) x2, (int) y2);
}
}
/**
* The applet/application proper
*/
class Lines extends Panel implements Runnable {
/*
* width, height - width and height of bounding panel
* Nlines - number of line segments to be displayed
* lines - array of instances of Segment class
* LC - instance of LineColors class
*/
int width, height;
final int NLines = 4;
Segment lines[] = new Segment[NLines];
LineColors LC = new LineColors ();
/*
* instance of thread for this line
*/
Thread thread;
/**
* init is called when the applet is loaded
* save the width and height
* create instances of Segment class
*/
public void init (int inPriority) {
width = 200;
height = 200;
thread = new Thread (this);
thread.start ();
thread.setPriority(inPriority);
int i;
for (i=0; i<NLines; i+=1)
lines[i] = new Segment (width, height, (2*i) % 24, LC);
}
/**
* recompute the next endpoint coordinates for each line
* invoke paint() method for each line
* @param g - destination graphics object
*/
public void paint (Graphics g)
{
int i;
g.setColor (Color.black);
g.drawRect (0, 0, width-1, height-1);
for (i=0; i<NLines; i+=1) {
lines[i].compute ();
lines[i].paint (g);
}
}
/*
* the thread proper
* calls paint() every 50ms
*/
public void run()
{
Graphics g = getGraphics();
int iterCount = 0;
while (true) {
paint(g);
try {
iterCount += 1;
if (iterCount == 5) {
Thread.sleep(10);
iterCount = 0;
}
}
catch (InterruptedException e) {
System.out.println("Caught exception...");
}
}
}
}
/*
* the applet/application proper
* creates two instances of Lines and starts them
* as separate threads
*/
public class MultiThread extends Applet {
/*
* the instances of Lines
*/
Lines lines[];
/*
* the number of threads to be run
*/
public final static int NumThreads = 5;
/*
* the priority of the first thread
*/
public final static int StartingPriority = Thread.NORM_PRIORITY;
/*
* called when the applet is loaded
* creates several instances of Lines and adds them to the
* applet panel
* sets the priority of each thread to 1 less than the previous
* one
*/
public void init () {
setLayout (new GridLayout (MultiThread.NumThreads, 1, 0, σ0));
lines = new Lines[MultiThread.NumThreads];
for (int i = 0; i< MultiThread.NumThreads; i++) {
lines[i] = new Lines ();
add (lines[i]);
lines[i].setSize (200, 200/MultiThread.NumThreads);
lines[i].init (StartingPriority-i);
}
}
/**
* application entry point, unused when run as an applet
* create window frame and add applet inside
* @param args[] - command-line arguments
*/
public static void main (String args[]) {
Frame f = new Frame ("Colored lines");
f.setLayout (new GridLayout (MultiThread.NumThreads, 1, 0, 0));
f.setSize (200, 200);
Lines lines[] = new Lines[MultiThread.NumThreads];
for (int i = 0; i< MultiThread.NumThreads; i++) {
lines[i] = new Lines ();
f.add (lines[i]);
}
f.show ();
for (int i = 0; i< MultiThread.NumThreads; i++) {
lines[i].init (StartingPriority-i);
}
}
}
SyncMethod.java:
import java.awt.*;
import java.applet.Applet;
/*
* a class for handling first in, first out data structure
*/
class FIFO {
/*
* the maximum depth of the FIFO
*/
final int MaxDepth = 200;
/*
* the real depth of this FIFO
*/
int depth;
/*
* write and read indexes into the data array
*/
int writeIndex;
int readIndex;
/*
* the number of data items currently in the FIFO
*/
int nItems;
/*
* the data proper
*/
int data[] = new int[MaxDepth];
/*
* width and height of the FIFO graphical display
*/
int width;
int height;
/*
* x and y position of the upper-left corner of the FIFO
* graphical display
*/
int xpos;
int ypos;
/**
* the constructor
* @param d - depth of the FIFO
*/
public FIFO (int d) {
depth = d;
writeIndex = 0;
readIndex = 0;
nItems = 0;
width = depth + 4;
height = 50;
xpos = 50;
ypos = 75;
}
/**
* write one integer value into the FIFO
* @param value - the value to write
*/
synchronized void write (int value) {
if (nItems >= depth) return;
data[writeIndex] = value;
writeIndex += 1;
writeIndex %= depth;
nItems += 1;
}
/**
* read 1 integer value from the FIFO
*/
synchronized int read () {
if (nItems < 1) return 0;
int value = data[readIndex];
readIndex += 1;
readIndex %= depth;
nItems -= 1;
return value;
}
/**
* returns true if the FIFO is empty
*/
synchronized boolean empty () {
return nItems > 0 ? false : true;
}
/**
* returns true if the FIFO is half full
*/
synchronized boolean halfFull () {
return nItems > (depth >> 1) ? true : false;
}
/**
* returns true if the FIFO is full
*/
synchronized boolean full () {
return nItems >= (depth) ? true : false;
}
/**
* draws the FIFO graphical display
* @param g - destination graphics context
*/
synchronized void paint (Graphics g) {
int x, y, w, h;
g.setColor (Color.white);
g.fillRect (xpos, ypos, width, height);
g.setColor (Color.black);
g.drawRect (xpos, ypos, width, height);
x = writeIndex + xpos + 2;
y = ypos - 22;
g.drawLine (x, y, x, y + 20);
g.drawString ("Write index "+writeIndex, x+2, y+10);
x = readIndex + xpos + 2;
y = ypos + height + 22;
g.drawLine (x, y-20, x, y);
g.drawString ("Read index "+readIndex, x+2, y);
if (nItems < 1) return;
if (nItems > (depth>>1)) g.setColor (Color.red);
else g.setColor (Color.green);
x = xpos + 2 + readIndex;
y = ypos + 2;
if (writeIndex > readIndex) w = nItems;
else w = width - readIndex - 4;
h = height - 4;
g.fillRect (x, y, w, h);
if (writeIndex > readIndex) return;
x = xpos + 2;
w = writeIndex;
g.fillRect (x, y, w, h);
}
}
/*
* a class that generates data continuously
*/
class Source extends Thread {
/*
* the FIFO to write into
*/
FIFO fifo;
int value;
/**
* constructor
* saves the FIFO instance and starts the thread
* @param f - an instance of FIFO
*/
public Source (FIFO f) {
fifo = f;
value = 0;
start ();
}
/*
* the thread that writes one word every 100ms
*/
public void run () {
while (true) {
if (fifo.full() == false)
fifo.write (value++);
try {
Thread.sleep (100);
} catch (InterruptedException e) {
}
}
}
}
/*
* a class that reads data from the FIFO
*/
class Sink extends Thread {
/*
* the FIFO to read from
*/
FIFO fifo;
int value;
/**
* constructor
* saves the FIFO instance and starts the thread
* @param f - an instance of FIFO
*/
public Sink (FIFO f) {
fifo = f;
start ();
}
/*
* the thread that reads all data out after the FIFO is half
* full
*/
public void run () {
while (true) {
if (fifo.halfFull()) {
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
}
while (fifo.empty() == false) {
value = fifo.read ();
try {
Thread.sleep (50);
} catch (InterruptedException e) {
}
}
}
try {
Thread.sleep (100);
} catch (InterruptedException e) {
}
}
}
}
/*
* the applet/application class
*/
public class SyncMethod extends Applet implements Runnable {
Source source;
Sink sink;
FIFO fifo;
Thread thread;
/*
* called when the applet is loaded
* create instances of FIFO, Source, Sink, and Thread
*/
public void init () {
fifo = new FIFO (200);
source = new Source (fifo);
sink = new Sink (fifo);
thread = new Thread (this);
}
/*
* start the graphics update thread
*/
public void start () {
thread.start ();
}
/*
* the graphics update thread
* call repaint every 100ms
*/
public void run () {
while (true) {
repaint ();
try {
Thread.sleep (100);
} catch (InterruptedException e) {
}
}
}
/**
* called from update() in response to repaint()
* @param g - destination graphics context
*/
public void paint (Graphics g) {
fifo.paint (g);
}
/**
* main() is the application entry point
* main() is unused when run as an applet
* create a window frame and add the applet inside
* @param args[] - command-line arguments
*/
public static void main (String args[]) {
Frame f = new Frame ("Synchronized methods example");
SyncMethod syncMethod = new SyncMethod ();
f.add ("Center", syncMethod);
f.setSize (400, 200);
f.show ();
syncMethod.init ();
syncMethod.start ();
}
}
SyncCode.java:
import java.awt.*;
import java.applet.Applet;
/*
* a class for handling first in, first out data structure
*/
class FIFO {
/*
* the maximum depth of the FIFO
*/
final int MaxDepth = 200;
/*
* the real depth of this FIFO
*/
int depth;
/*
* write and read indexes into the data array
*/
int writeIndex;
int readIndex;
/*
* the number of data items currently in the FIFO
*/
int nItems;
/*
* the data proper
*/
int data[] = new int[MaxDepth];
/*
* width and height of the FIFO graphical display
*/
int width;
int height;
/*
* x and y position of the upper-left corner of the FIFO
* graphical display
*/
int xpos;
int ypos;
/**
* the constructor
* @param d - depth of the FIFO
*/
public FIFO (int d) {
depth = d;
writeIndex = 0;
readIndex = 0;
nItems = 0;
width = depth + 4;
height = 50;
xpos = 50;
ypos = 75;
}
/**
* write one integer value into the FIFO
* @param value - the value to write
*/
void write (int value) {
if (nItems >= depth) return;
data[writeIndex] = value;
writeIndex += 1;
writeIndex %= depth;
nItems += 1;
}
/**
* read one integer value from the FIFO
*/
int read () {
if (nItems < 1) return 0;
int value = data[readIndex];
readIndex += 1;
readIndex %= depth;
nItems -= 1;
return value;
}
/**
* returns true if the FIFO is empty
*/
boolean empty () {
return nItems > 0 ? false : true;
}
/**
* returns true if the FIFO is half full
*/
boolean halfFull () {
return nItems > (depth >> 1) ? true : false;
}
/**
* returns true if the FIFO is full
*/
boolean full () {
return nItems >= (depth) ? true : false;
}
/**
* draws the FIFO graphical display
* @param g - destination graphics context
*/
void paint (Graphics g) {
int x, y, w, h;
g.setColor (Color.white);
g.fillRect (xpos, ypos, width, height);
g.setColor (Color.black);
g.drawRect (xpos, ypos, width, height);
x = writeIndex + xpos + 2;
y = ypos - 22;
g.drawLine (x, y, x, y + 20);
g.drawString ("Write index "+writeIndex, x+2, y+10);
x = readIndex + xpos + 2;
y = ypos + height + 22;
g.drawLine (x, y-20, x, y);
g.drawString ("Read index "+readIndex, x+2, y);
if (nItems < 1) return;
if (nItems > (depth>>1)) g.setColor (Color.red);
else g.setColor (Color.green);
x = xpos + 2 + readIndex;
y = ypos + 2;
if (writeIndex > readIndex) w = nItems;
else w = width - readIndex - 4;
h = height - 4;
g.fillRect (x, y, w, h);
if (writeIndex > readIndex) return;
x = xpos + 2;
w = writeIndex;
g.fillRect (x, y, w, h);
}
}
/*
* a class that generates data continuously
*/
class Source extends Thread {
/*
* the FIFO to write into
*/
FIFO fifo;
int value;
/**
* constructor
* saves the FIFO instance and starts the thread
* @param f - an instance of FIFO
*/
public Source (FIFO f) {
fifo = f;
value = 0;
start ();
}
/*
* the thread that writes one word every 100ms
*/
public void run () {
while (true) {
synchronized (fifo) {
if (fifo.full() == false)
fifo.write (value++);
}
try {
Thread.sleep (100);
} catch (InterruptedException e) {
}
}
}
}
/*
* a class that reads data from the FIFO
*/
class Sink extends Thread {
/*
* the FIFO to read from
*/
FIFO fifo;
int value;
/**
* constructor
* saves the FIFO instance and starts the thread
* @param f - an instance of FIFO
*/
public Sink (FIFO f) {
fifo = f;
start ();
}
/*
* the thread that reads all data out after the FIFO is half
* full
*/
public void run () {
boolean empty;
boolean halfFull;
while (true) {
synchronized (fifo) {
halfFull = fifo.halfFull ();
}
if (halfFull) {
try {
Thread.sleep (1000);
} catch (InterruptedException e) {
}
do {
synchronized (fifo) {
value = fifo.read ();
}
try {
Thread.sleep (50);
} catch (InterruptedException e) {
}
synchronized (fifo) {
empty = fifo.empty ();
}
} while (empty == false);
}
try {
Thread.sleep (100);
} catch (InterruptedException e) {
}
}
}
}
/*
* the applet/application class
*/
public class SyncCode extends Applet implements Runnable {
Source source;
Sink sink;
FIFO fifo;
Thread thread;
/*
* called when the applet is loaded
* create instances of FIFO, Source, Sink, and Thread
*/
public void init () {
fifo = new FIFO (200);
source = new Source (fifo);
sink = new Sink (fifo);
thread = new Thread (this);
}
/*
* start the graphics update thread
*/
public void start () {
thread.start ();
}
/*
* the graphics update thread
* call repaint every 100ms
*/
public void run () {
while (true) {
repaint ();
try {
Thread.sleep (100);
} catch (InterruptedException e) {
}
}
}
/**
* called from update() in response to repaint()
* @param g - destination graphics context
*/
public void paint (Graphics g) {
synchronized (fifo) {
fifo.paint (g);
}
}
/**
* main() is the application entry point
* main() is unused when run as an applet
* create a window frame and add the applet inside
* @param args[] - command-line arguments
*/
public static void main (String args[]) {
Frame f = new Frame ("Synchronized code example");
SyncCode syncCode = new SyncCode ();
f.add ("Center", syncCode);
f.setSize (400, 200);
f.show ();
syncCode.init ();
syncCode.start ();
}
}
WaitDemo.java:
import java.awt.*;
import java.applet.Applet;
/*
* a class for handling first in, first out data structure
*/
class FIFO {
/*
* the maximum depth of the FIFO
*/
final int MaxDepth = 200;
/*
* the real depth of this FIFO
*/
int depth;
/*
* write and read indexes into the data array
*/
int writeIndex;
int readIndex;
/*
* the number of data items currently in the FIFO
*/
int nItems;
/*
* the data proper
*/
int data[] = new int[MaxDepth];
/*
* width and height of the FIFO graphical display
*/
int width;
int height;
/*
* x and y position of the upper-left corner of the FIFO
* graphical display
*/
int xpos;
int ypos;
/**
* the constructor
* @param d - depth of the FIFO
*/
public FIFO (int d) {
depth = d;
writeIndex = 0;
readIndex = 0;
nItems = 0;
width = depth + 4;
height = 50;
xpos = 50;
ypos = 75;
}
/**
* write one integer value into the FIFO
* invoke wait() if the FIFO is full
* @param value - the value to write
*/
synchronized void write (int value) {
if (nItems >= depth) {
try {
wait ();
} catch (InterruptedException e) {
}
}
data[writeIndex] = value;
writeIndex += 1;
writeIndex %= depth;
nItems += 1;
notify ();
}
/**
* read one integer value from the FIFO
* invoke wait() if the FIFO is empty
*/
synchronized int read () {
if (nItems < 1) {
try {
wait ();
} catch (InterruptedException e) {
}
}
int value = data[readIndex];
readIndex += 1;
readIndex %= depth;
nItems -= 1;
notify ();
return value;
}
/**
* returns true if the FIFO is empty
*/
synchronized boolean empty () {
return nItems > 0 ? false : true;
}
/**
* returns true if the FIFO is half full
*/
synchronized boolean halfFull () {
return nItems > (depth >> 1) ? true : false;
}
/**
* returns true if the FIFO is full
*/
synchronized boolean full () {
return nItems >= (depth) ? true : false;
}
/**
* draws the FIFO graphical display
* @param g - destination graphics context
*/
synchronized void paint (Graphics g) {
int x, y, w, h;
g.setColor (Color.white);
g.fillRect (xpos, ypos, width, height);
g.setColor (Color.black);
g.drawRect (xpos, ypos, width, height);
x = writeIndex + xpos + 2;
y = ypos - 22;
g.drawLine (x, y, x, y + 20);
g.drawString ("Write index "+writeIndex, x+2, y+10);
x = readIndex + xpos + 2;
y = ypos + height + 22;
g.drawLine (x, y-20, x, y);
g.drawString ("Read index "+readIndex, x+2, y);
if (nItems < 1) return;
if (nItems > (depth>>1)) g.setColor (Color.red);
else g.setColor (Color.green);
x = xpos + 2 + readIndex;
y = ypos + 2;
if (writeIndex > readIndex) w = nItems;
else w = width - readIndex - 4;
h = height - 4;
g.fillRect (x, y, w, h);
if (writeIndex > readIndex) return;
x = xpos + 2;
w = writeIndex;
g.fillRect (x, y, w, h);
}
}
/*
* a class that generates data continuously
*/
class Source extends Thread {
/*
* the FIFO to write into
*/
FIFO fifo;
int value;
/**
* constructor
* saves the FIFO instance and starts the thread
* @param f - an instance of FIFO
*/
public Source (FIFO f) {
fifo = f;
value = 0;
start ();
}
/*
* the thread that writes one word every 50ms on average
*/
public void run () {
while (true) {
if (fifo.full() == false)
fifo.write (value++);
try {
Thread.sleep ((int) (100 * Math.random ()));
} catch (InterruptedException e) {
}
}
}
}
/*
* a class that reads data from the FIFO
*/
class Sink extends Thread {
/*
* the FIFO to read from
*/
FIFO fifo;
int value;
/**
* constructor
* saves the FIFO instance and starts the thread
* @param f - an instance of FIFO
*/
public Sink (FIFO f) {
fifo = f;
start ();
}
/*
* the thread that tries to read one word every 50ms on average
*/
public void run () {
while (true) {
value = fifo.read ();
try {
Thread.sleep ((int) (100 * Math.random ()));
} catch (InterruptedException e) {
}
}
}
}
/*
* the applet/application class
*/
public class WaitDemo extends Applet implements Runnable {
Source source;
Sink sink;
FIFO fifo;
Thread thread;
/*
* called when the applet is loaded
* create instances of FIFO, Source, Sink, and Thread
*/
public void init () {
fifo = new FIFO (200);
source = new Source (fifo);
sink = new Sink (fifo);
thread = new Thread (this);
}
/*
* start the graphics update thread
*/
public void start () {
thread.start ();
}
/*
* the graphics update thread
* call repaint every 100ms
*/
public void run () {
while (true) {
repaint ();
try {
Thread.sleep (100);
} catch (InterruptedException e) {
}
}
}
/**
* called from update() in response to repaint()
* @param g - destination graphics context
*/
public void paint (Graphics g) {
fifo.paint (g);
}
/**
* main() is the application entry point
* main() is unused when run as an applet
* create a window frame and add the applet inside
* @param args[] - command-line arguments
*/
public static void main (String args[]) {
Frame f = new Frame ("FIFO Demo");
WaitDemo waitDemo = new WaitDemo ();
f.add ("Center", waitDemo);
f.setSize (400, 200);
f.show ();
waitDemo.init ();
waitDemo.start ();
}
}