CIS 121 March 15, 2000
Recall the major elements of the programming assignment.
- Partitioning the screen into an area in which components are placed
and an area in which figures are displayed.
- Creating buttons and having actions take place based on button
clicks.
- Creating textboxes in which information will be placed and from which
information will be retrieved.
- Creating checkboxes and performing actions based on which box(es) are
checked.
- Drawing a figure on the screen for a random amount of time.
- Setting up a timer.
- Capturing a mouse click event and using the coordinates to aim an
imaginary gun.
- Detecting whether the figure was hit.
- Handle any exceptions which might occur.
Let us look at how we have dealt with some of these aspects.
1. Partitioning the screen into an area in which components are
created and an area in which figures are displayed.
Recall that Panel is a descendant of Container and Component. Panels are
useful because Panels may be placed inside of Panels unlike Windows. We
can't place a Window object or Frame object inside of another container.
But Panels allow us to do this.
The constructor we normally use for a Panel has one parameter, a Layout
manager. If we do not want to use one of Java's Layout Managers, then we
may use null as a parameter.
So for example, to create:
| A Panel with a FlowLayout manager |
new Panel(new FlowLayout()) |
| A Panel with no Layout manager |
new Panel(null) |
Applet extends Panel and so we can place Panels in Applets. Let us look at
a simple example.
import java.awt.*;
import java.applet.*;
public class ExampleApplet1 extends Applet {
public ExampleApplet1() {
setLayout(null);
Panel panel1 = new Panel(null);
Panel panel2 = new Panel(null);
Panel panel3 = new Panel(null);
panel1.setSize(500,100);
panel1.setLocation(0,0);
panel2.setSize(500,100);
panel2.setLocation(0,100);
panel3.setSize(500,100);
panel3.setLocation(0,200);
panel1.setBackground(Color.red);
panel2.setBackground(Color.white);
panel3.setBackground(Color.blue);
add(panel1);
add(panel2);
add(panel3);
}
}
Example Applet 1
2. Creating buttons and having actions take place based on
button clicks.
Recall that components can be placed into containers so we can place
components in Panels. Let us modify the above example to take advantage of
this fact.
import java.awt.*;
import java.applet.*;
public class ExampleApplet2 extends Applet {
public ExampleApplet2() {
setLayout(null);
Panel panel1 = new Panel(null);
Panel panel2 = new Panel(null);
Panel panel3 = new Panel(null);
panel1.setSize(500,100);
panel1.setLocation(0,0);
panel2.setSize(500,100);
panel2.setLocation(0,100);
Button myButton = new Button("Press Me");
myButton.setSize(100,20);
myButton.setLocation(200,50);
panel2.add(myButton);
panel3.setSize(500,100);
panel3.setLocation(0,200);
panel1.setBackground(Color.red);
panel2.setBackground(Color.white);
panel3.setBackground(Color.blue);
add(panel1);
add(panel2);
add(panel3);
}
}
Example Applet 2
Let us now modify the example so that we can perform an action when the
user clicks the button.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class ExampleApplet3 extends Applet implements ActionListener {
Label myLabel;
boolean labelOn = false;
public ExampleApplet3() {
setLayout(null);
Panel panel1 = new Panel(null);
Panel panel2 = new Panel(null);
Panel panel3 = new Panel(null);
panel1.setSize(500,100);
panel1.setLocation(0,0);
panel2.setSize(500,100);
panel2.setLocation(0,100);
Button myButton = new Button("Press Me");
myButton.setSize(100,20);
myButton.setLocation(200,50);
myButton.addActionListener(this);
panel2.add(myButton);
myLabel = new Label("Hello");
myLabel.setSize(100,20);
myLabel.setLocation(50,50);
myLabel.setVisible(labelOn);
panel2.add(myLabel);
panel3.setSize(500,100);
panel3.setLocation(0,200);
panel1.setBackground(Color.red);
panel2.setBackground(Color.white);
panel3.setBackground(Color.blue);
add(panel1);
add(panel2);
add(panel3);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Press Me")) {
if (labelOn) {
myLabel.setVisible(false);
labelOn = false;
} else {
myLabel.setVisible(true);
labelOn = true;
}
}
}
}
Example Applet 3
3. Creating textboxes in which information will be placed and from
which information will be retrieved.
Recall that what is in the TextField is text so if we want to use it as an
integer for arithmetic operations we must convert it by using the static
method valueOf in the Integer class.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class ExampleApplet4 extends Applet implements ActionListener {
Label myLabel;
boolean labelOn = false;
TextField myTextField1;
TextField myTextField2;
public ExampleApplet4() {
setLayout(null);
Panel panel1 = new Panel(null);
Panel panel2 = new Panel(null);
Panel panel3 = new Panel(null);
panel1.setSize(500,100);
panel1.setLocation(0,0);
myTextField1 = new TextField("5");
myTextField1.setSize(100,30);
myTextField1.setLocation(200,50);
panel1.add(myTextField1);
panel2.setSize(500,100);
panel2.setLocation(0,100);
Button myButton = new Button("Press Me");
myButton.setSize(100,20);
myButton.setLocation(200,50);
myButton.addActionListener(this);
panel2.add(myButton);
myLabel = new Label("Hello");
myLabel.setSize(100,20);
myLabel.setLocation(50,50);
myLabel.setVisible(labelOn);
panel2.add(myLabel);
panel3.setSize(500,100);
panel3.setLocation(0,200);
myTextField2 = new TextField("10");
myTextField2.setSize(100,30);
myTextField2.setLocation(200,50);
panel3.add(myTextField2);
panel1.setBackground(Color.red);
panel2.setBackground(Color.white);
panel3.setBackground(Color.blue);
add(panel1);
add(panel2);
add(panel3);
}
public void actionPerformed(ActionEvent e) {
int temp1;
int temp2;
if (e.getActionCommand().equals("Press Me")) {
if (labelOn) {
myLabel.setVisible(false);
labelOn = false;
} else {
myLabel.setVisible(true);
labelOn = true;
}
temp1 = (Integer.valueOf(myTextField1.getText())).intValue();
temp2 = (Integer.valueOf(myTextField2.getText())).intValue();
myTextField1.setText(String.valueOf(temp2));
myTextField2.setText(String.valueOf(temp1));
}
}
}
Example Applet 4
4. Creating checkboxes and performing actions based on which
box(es) are checked.
Recall that we must implement ItemListener in order to detect and act on
checking or unchecking checkboxes.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class ExampleApplet5 extends Applet implements ActionListener,ItemListener {
Label myLabel;
boolean labelOn = false;
TextField myTextField1;
TextField myTextField2;
boolean changeMessage = false;
boolean switchTextFields = false;
public ExampleApplet5() {
setLayout(null);
Panel panel1 = new Panel(null);
Panel panel2 = new Panel(null);
Panel panel3 = new Panel(null);
panel1.setSize(500,100);
panel1.setLocation(0,0);
myTextField1 = new TextField("5");
myTextField1.setSize(100,30);
myTextField1.setLocation(200,50);
panel1.add(myTextField1);
panel2.setSize(500,100);
panel2.setLocation(0,100);
Button myButton = new Button("Press Me");
myButton.setSize(100,20);
myButton.setLocation(200,50);
myButton.addActionListener(this);
panel2.add(myButton);
myLabel = new Label("Hello");
myLabel.setSize(100,20);
myLabel.setLocation(50,50);
myLabel.setVisible(labelOn);
panel2.add(myLabel);
panel3.setSize(500,100);
panel3.setLocation(0,200);
myTextField2 = new TextField("10");
myTextField2.setSize(100,30);
myTextField2.setLocation(200,50);
panel3.add(myTextField2);
Checkbox myCheckbox1 = new Checkbox("Change message");
Checkbox myCheckbox2 = new Checkbox("Switch text fields");
myCheckbox1.setSize(150,30);
myCheckbox1.setLocation(0,20);
myCheckbox2.setSize(150,30);
myCheckbox2.setLocation(0,50);
myCheckbox1.addItemListener(this);
myCheckbox2.addItemListener(this);
panel3.add(myCheckbox1);
panel3.add(myCheckbox2);
panel1.setBackground(Color.red);
panel2.setBackground(Color.white);
panel3.setBackground(Color.blue);
add(panel1);
add(panel2);
add(panel3);
}
public void actionPerformed(ActionEvent e) {
int temp1;
int temp2;
if (e.getActionCommand().equals("Press Me")) {
if (changeMessage)
if (labelOn) {
myLabel.setVisible(false);
labelOn = false;
} else {
myLabel.setVisible(true);
labelOn = true;
}
if (switchTextFields) {
temp1 = (Integer.valueOf(myTextField1.getText())).intValue();
temp2 = (Integer.valueOf(myTextField2.getText())).intValue();
myTextField1.setText(String.valueOf(temp2));
myTextField2.setText(String.valueOf(temp1));
}
}
}
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
if (e.getItem() == "Change message")
changeMessage = true;
if (e.getItem() == "Switch text fields")
switchTextFields = true;
}
if (e.getStateChange() == ItemEvent.DESELECTED) {
if (e.getItem() == "Change message")
changeMessage = false;
if (e.getItem() == "Switch text fields")
switchTextFields = false;
}
}
}
Example Applet 5
5. Drawing a figure on the screen for a random amount of time.
In order to accomplish this we need to first look at the concepts of Threads.
Threads
Recall that a thread is a single sequential flow of control. In
all of the programs that you wrote in CIS 120 and this the first part
of this semester ran in their own thread. Java allows us to have more
than one thread executing simulataneously. Since the CPU can only
process one thing at a time, multithreading is accomplished by very
quickly switching threads in and out of the processor.
Multithreading is sometimes necessary when developing applets. Recall
that an applet cannot have a main method, and, therefore, must be run
in the context of a browser or appletviewer. The browser/appletviewer
runs in its own thread, and so we must make sure that the methods in
the applet do not take a long time to execute. In particular, we shouldn't
have infinite loops in the methods of an applet if we intend to have
that applet run in the thread of the browser/appletviewer.
The following is a partial sequence of execution when an applet runs in the
thread of a browser/appletviewer.
| The browser/appletviewer loads the applet |
| The init() method in the applet is executed |
| The start() method in the applet is executed |
The class Thread is found in the java.lang. Since each applet we create
extends the class Applet, we can't make the applet a subclass of Thread.
In order to run an applet in its own thread we implement the interface
Runnable. The Runnable interface has one method which must be overridden,
public void run(). This method is run when the thread is started.
There a few methods available in the Thread class that are important. Suppose we have
a Thread object called thread.
| thread.start() |
causes the thread to begin executing. The run() method is then
called. |
| thread.suspend() |
temporarily halts the execution of the thread. |
| thread.resume() |
resume execution of the thread |
| thread.stop() |
permanently stops the execution of the thread |
There is a static method called sleep in the class Thread which takes
as an argument a number of milliseconds. We can use this method to cause
the Thread to sleep for a number of milliseconds. This method must be
called in a try block since it might cause an InterruptedException to
be thrown. This occurs if the user halts the applet while the thread is
sleeping.
import java.awt.*;
import java.applet.*;
public class ExampleApplet7 extends Applet {
Panel panel;
Thread thread1;
Thread thread2;
public class Writer implements Runnable {
String s;
public Writer(String s) {
this.s = s;
}
public void run() {
int x;
int y;
Graphics g = panel.getGraphics();
while (true) {
System.out.println(s);
x = (int)(500*Math.random());
y = (int)(100*Math.random());
g.setColor(Color.black);
g.drawString(s,x,y);
try {
Thread.sleep(1000);
} catch (InterruptedException exc) {
System.exit(1);
}
g.setColor(Color.white);
g.clearRect(x,y-30,100,100);
}
}
}
public ExampleApplet7() {
setLayout(null);
panel = new Panel(null);
panel.setSize(500,100);
panel.setLocation(0,0);
add(panel);
}
public void init() {
if (thread1 == null) {
thread1 = new Thread(new Writer("Ping"));
thread1.start();
}
if (thread2 == null) {
thread2 = new Thread(new Writer("Pong"));
thread2.start();
}
}
public void destroy() {
thread1.stop();
thread2.stop();
}
}
Example Applet 7
Let us now look at an example of using Threads to draw a figure for
a random amount of time.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class ExampleApplet6 extends Applet implements ActionListener,Runnable {
Graphics panel1g;
Thread drawer;
Panel panel1;
TextField myTextField;
public class Figure {
int x;
int y;
int duration;
public Figure(int x,int y) {
this.x = x;
this.y = y;
duration = (int)(10*Math.random());
myTextField.setText(String.valueOf(duration));
}
public void draw() {
panel1g = panel1.getGraphics();
panel1g.setColor(Color.black);
panel1g.fillOval(x,y,10,10);
}
public void clear() {
panel1g = panel1.getGraphics();
panel1g.setColor(Color.white);
panel1g.fillOval(x,y,10,10);
}
}
public ExampleApplet6() {
setLayout(null);
setBackground(Color.white);
panel1 = new Panel(null);
Panel panel2 = new Panel(new FlowLayout());
panel1.setSize(500,400);
panel1.setLocation(0,0);
panel1g = panel1.getGraphics();
panel2.setSize(500,100);
panel2.setLocation(0,400);
Button myButton = new Button("Draw Figure");
myButton.addActionListener(this);
panel2.add(myButton);
myTextField = new TextField(20);
panel2.add(myTextField);
add(panel1);
add(panel2);
}
public void init() {
if (drawer == null) {
drawer = new Thread(this);
drawer.start();
}
}
public void run() {
while (true) {
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Draw Figure")) {
Figure myFigure = new Figure(250,250);
myFigure.draw();
try {
Thread.sleep(myFigure.duration*1000);
} catch (InterruptedException exc) {
System.exit(1);
}
myFigure.clear();
}
}
}
Example Applet 6
6. Setting up a timer.
Now let us look at an example of a Timer.
import java.awt.*;
import java.applet.*;
import java.util.*;
public class ExampleApplet8 extends Applet {
TextField timeLeft;
Thread timer;
public class Timer implements Runnable {
int hours;
int minutes;
int seconds;
Calendar time;
int base;
boolean first=true;
int basehours;
int baseminutes;
int baseseconds;
public void run() {
timeLeft.setText(" ");
while (true) {
if (first) {
time = Calendar.getInstance();
basehours = time.get(Calendar.HOUR_OF_DAY);
baseminutes = time.get(Calendar.MINUTE);
baseseconds = time.get(Calendar.SECOND);
System.out.println(basehours + " " + baseminutes + " " + baseseconds);
base = basehours*60*60+baseminutes*60+baseseconds;
System.out.println(base);
first=false;
}
time = Calendar.getInstance();
hours = time.get(Calendar.HOUR_OF_DAY);
minutes = time.get(Calendar.MINUTE);
seconds = time.get(Calendar.SECOND);
int current = hours*60*60+minutes*60+seconds;
timeLeft.setText(String.valueOf(301-(current-base)));
try {
Thread.sleep(1000);
} catch (InterruptedException exc) {
System.exit(1);
}
}
}
}
public ExampleApplet8() {
setLayout(new FlowLayout());
timeLeft = new TextField("300");
add(timeLeft);
}
public void init() {
if (timer == null) {
timer = new Thread(new Timer());
timer.start();
}
}
public void destroy() {
timer.stop();
}
}
Example Applet 8
7. Capturing a mouse click event and using the coordinates to aim an
imaginary gun.
Recall that we use a MouseListener to detect a mouse click. Recall the
example we looked at a few weeks ago. This example uses a Frame, but it
can be easily adapted to use an Applet.
import java.awt.*;
import java.awt.event.*;
class MouseTester extends Frame implements MouseListener,WindowListener {
TextField myTextField;
public MouseTester(String s) {
super(s);
setBackground(Color.yellow);
setLayout(new FlowLayout());
myTextField = new TextField(20);
add(myTextField);
addMouseListener(this);
addWindowListener(this);
}
public void mouseClicked(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
myTextField.setText("[" + String.valueOf(x) + "," + String.valueOf(y) + "]");
}
public void windowActivated(WindowEvent e) { }
public void windowClosed(WindowEvent e) { }
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { }
public void windowIconified(WindowEvent e) { }
public void windowOpened(WindowEvent e) { }
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
By detecting the coordinates of the mouse click, we can determine the
distance it is away from a fixed point by using the distance formula:
d((x1,y1),(x2,y2)) = sqrt((x1-x2)2 + (y1-y2)2)
8. Detecting whether the figure was hit.
There are two criteria to determining whether or not the figure has been
hit.
- The bullet has time to get to the figure.
- The gun is aimed in the direction of the figure.
There are different ways of determining whether or not the gun is aimed
in the right direction. We could use the arcsin fuction from the Math
class to determine whether or not the angle the trajectory of the bullet
makes with the horizontal is between the angles made by the corners of
the figure. We could also use the coordinates of the point where we
click to determine whether or not it is within the figure.
To determine whether there is enough time for the bullet to get to the
figure we use the simple distance formula, distance = rate * time. We
know the speed of the bullet, and we know the distance from the gun to
where we clicked the mouse. So we use the amount of time that the figure
is on the screen to determine whether or not there is enough time for
the bullet to get to the figure.
9. Handle any exceptions which might occur.
Recall the examples we had of Exception Handling.
This example is found at http://www.cs.qc.edu/~lord/cs101/Examples.
PriceException.java
public class PriceException extends IllegalArgumentException {
public PriceException (String ErrorMessage) {
super (ErrorMessage);
}
}
TestException.java
/*
generate problems with "price" by forcing it to be negative
and greater then 100000
*/
public class TestException {
public static void main(String[] args) throws PriceException {
PriceException BadPrice = new PriceException("Invalid price");
int testPrices[] = {23, -2, 200000};
boolean valid = true;
for (int i = 0; i< testPrices.length; i++) {
System.out.println("The price is "+Integer.toString(testPrices[i]));
try {
valid = true;
if ((testPrices[i] < 0) || (testPrices[i] > 100000))
throw BadPrice;
}
catch (PriceException pe) {
System.out.println("Houston, we have a problem: Price exception.");
valid = false;
}
catch (NumberFormatException nfe) {
System.out.println("Houston, we have a problem: NFE!");
valid=false;
}
finally {
if (!valid)
System.out.println("Because the price was "+
Integer.toString(testPrices[i]));
System.out.println("Let's try another one...");
}
} // for
} //main
} // class
We can use this exception handling model in this program to deal with
any exceptions that occur.