CIS 121 March 15, 2000


Recall the major elements of the programming assignment.
  1. Partitioning the screen into an area in which components are placed and an area in which figures are displayed.
  2. Creating buttons and having actions take place based on button clicks.
  3. Creating textboxes in which information will be placed and from which information will be retrieved.
  4. Creating checkboxes and performing actions based on which box(es) are checked.
  5. Drawing a figure on the screen for a random amount of time.
  6. Setting up a timer.
  7. Capturing a mouse click event and using the coordinates to aim an imaginary gun.
  8. Detecting whether the figure was hit.
  9. 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.
    1. The bullet has time to get to the figure.
    2. 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.