Computing Concepts with Java 2 Essentials
Laboratory Notebook
Chapter 10 - Event Handling


Your name:
Your email address:
Your student ID number:

Once this form has been customized for your institution, you can use this button to send your lab work. Be sure to read the instructions before starting your work.


Lab Objectives

To gain experience with


P1. Listening to mouse events

To listen to mouse events, you need to carry out these steps:

  1. Create a class that extends the MouseAdapter class and override methods such as mousePressed and mouseReleased
  2. Make an object of that class
  3. Install that object as the mouse listener of a component (e.g. an applet)

Let's carry out these steps one by one.

First, create a class MousePressPrinter that extends MouseAdapter and overrides the mousePressed method to print the MouseEvent object to System.out:

public void mousePressed(MouseEvent event)
{  System.out.println(event);
}

Every time the mouse is pressed, the contents of the event will be displayed.

Next, create a class MousePressApplet that extends JApplet. In the constructor, make an object listener of the MousePressPrinter class and call addMouseListener to add that object as a mouse listener.

Now run the applet. Press the mouse button a few times at different locations. What output do you get?

This program just keeps track of where the mouse was pressed--it doesn't do anything useful with the mouse click. The next program will display a message at the mouse click location.

Write an applet MessageApplet that displays a message "Hello, World!" at the fixed location (100, 100). (We will change that location to the mouse click location in the next step.)

Use instance variables

private int messageX;
private int messageY;
private String messageText;

Initialize these instance variables in the constructor. In the paint method, call the drawString method.

Test your applet. It should simply show the message.

Now let's add the mouse listener class. Write a class MousePressListener that extends MouseAdapter and overrides the mousePressed method. In the mousePressed method, set messageX and messageY to the mouse click location, then call repaint:

messageX = event.getX();
messageY = event.getY();
messageText = event.toString();
repaint();

Now you need to put the two classes together. However, since the mousePressed method of the MousePressListener class needs to access the variables of the MessageApplet class, you need to make it into an inner class. Move the listener class inside the applet class. Then add the following code to the applet constructor:

MousePressListener listener = new MousePressListener();
addMouseListener(listener);

This completes the applet.

Now run the applet. Press the mouse button a few times at different locations. What happens?


P2. Implementing a Frame class

Consider the following very simple Java program.

public class HelloTest extends JFrame()
{  public static void main(String[] args)
   {  HelloFrame frame = new HelloFrame();
      frame.show();
   }
}

class HelloFrame extends JFrame
{  public HelloFrame()
   {  setSize(300, 300);
      setTitle("Hello, World!");
   }
}

Compile and run this program. You should get a program with an empty frame, whose title bar has a message "Hello, World!".

Now try closing the application. What do you have to do on your system to terminate the program? (Hint: Clicking on the "Close" button of the frame isn't good enough--that just hides the frame without shutting down the program.)

Of course, this behavior is not desirable. Users want the application to close when its main frame window is closed. Here is how you implement this enhanced behavior in Java.

  1. Create a class that extends the WindowAdapter class and override the windowClosing method
  2. Make an object of that class
  3. Install that object as the window listener of the frame

Here is the class that extends the WindowAdapter class. When the windowClosing method is called, it causes the program to exit.

class WindowCloser extends WindowAdapter
{  public void windowClosing(WindowEvent event)
   {  System.exit(0);
   }
}

In the HelloFrame constructor, you need to place the lines

WindowCloser listener = new WindowCloser();
addWindowListener(listener);

Now put the three classes (HelloTest, HelloFrame and WindowCloser) together. As with all listener classes, WindowCloser should be an inner class.

Run the program and try closing the frame window. The application should now terminate normally.

So far, this program doesn't do anything useful. To show some drawing, you have to work a little harder than with an applet. You can paint on the surface of an applet by placing drawing instructions into the paint method. But you cannot paint directly onto a frame.

Instead, you need to do the following.

  1. Define a class that extends the JPanel class and place drawing instructions into its paintComponent method.
  2. Construct an object of that panel class.
  3. Add the panel object to the content pane of the frame.

Here is a simple panel class:

class HelloPanel extends JPanel
{  public HelloPanel()
   {  messageX = 100;
      messageY = 100;
      messageText = "Hello, World!";
   }

   public void paintComponent(Graphics g)
   {  super.paintComponent(g);
      Graphics2D g2 = (Graphics2D)g;
      g2.drawString(messageText, messageX, messageY);
   }

   private int messageX;
   private int messageY;
   private String messageText;
}

Note that in the paintComponent method, you always have to call super.paintComponent.

(Note: In this method, we don't strictly have to cast g into a Graphics2D object; we just do this to be prepared for the more general case.)

In the constructor of the HelloFrame class, construct an object of this panel class and add it to the center of the content pane:

HelloPanel panel = new HelloPanel();
Container contentPane = getContentPane();
contentPane.add(panel, "Center");

Now put the program together. You should have four classes:

Run the program to make sure it displays the message in the panel inside the frame window.


P3. Adding user interface components

If you add a single panel to a frame, you can just add it to the center of the content pane. However, if you add multiple components to a frame, then you need to specify where you want to add them. By default, the content pane uses a border layout with five positions:

In this assignment, you will add a JTextField into each of the four corner areas, like this:

northField = new JTextField();
northField.setText("North");
contentPane.add(northField, "North");
. . .
// same for the other three directions

Place these instructions into the constructor of your frame class. Supply instance variables for each text field:

private JTextField northField;
. . . 

Write a program called LayoutTest with a class LayoutFrame whose content pane contains these four text fields.


P4. Reading text input

In the preceding exercise, you added four text fields to a frame. Normally you wouldn't do that--the purpose of that exercise was just to show off the layout manager. More commonly, you add a single text field to the bottom of the frame.

Of course, you will want to know what the user typed into the text field.

Whenever the user hits the ENTER key, the text field sends an action event to its action listeners. To react to the event, you have to do the following:

  1. Create a class that extends the ActionListener interface and override the actionPerformed method
  2. Make an object of that class
  3. Install that object as the action listener of the text field

Inside the actionPerformed method, you can read the contents of the text field with the getText method:

class TextFieldListener implements ActionListener
{  public void actionPerformed(ActionEvent event)
   {  String input = textField.getText();
      // now do something with input
   }
}

You attach the action listener in the constructor of the frame class.

TextFieldListener listener = new TextFieldListener();
textField.addActionListener(listener);

Your task is to modify the program from section 2. Place a text field into the "South" area of the content pane. Add the action listener. In the actionPerformed method of the TextFieldListener class, set the message text to the input string and repaint the panel. Note that you will need to add a method to the HelloPanel class to change the message string.

panel.setMessageText(input);
panel.repaint();

Now put the whole program together. Call it TextInputTest. Run it and verify that you can type in a new message in the text field. When you hit ENTER, the message should be displayed in the panel.


Don't forget to send your answers when you're finished.