Suppose that we would like to define a window that looks like the one below. The user is able to type text into each box independently of the other.
Let's write a Java class called TextEntryFrame. With the AWT's built-in classes and behavior, this turns out to be almost too easy:
import java.awt.Frame; import java.awt.TextField; import java.awt.TextArea; public class TextCheckFrame extends Frame { public TextCheckFrame() { setTitle( "Text Component Examples" ); setSize ( 300, 250 ); add( "North", new TextField() ); add( "South", new TextArea () ); } }
This solution comes with a new exercise built right into it:
Suppose that we want any text typed into the text field to appear in the text area, too.What changes do we have to make?
"What do you mean by that?", you ask?
Now our solution needs a custom listener!
Our BallWorlds and our CannonGame only handle events that generated by the active components -- a button and a slider -- that we added to it.
More generally, though, we will want to trap and respond to a mouse action anywhere within the frame. We also need to interact with the event objects that are passed to our listeners.
Any listener that wishes to monitor mouse activity must implement the MouseListener interface:
public interface MouseListener { public void mouseClicked ( MouseEvent e ); public void mouseEntered ( MouseEvent e ); public void mouseExited ( MouseEvent e ); public void mousePressed ( MouseEvent e ); public void mouseReleased( MouseEvent e ); }
As you should guess, the MouseListener interface is part of the java.awt.event package. It specifies what an object must do to be a mouse listener within the Java Event Model.
Consider this simple frame that displays the coordinates of every mouse press. It defines a MouseKeeper class that listens for mouse events. A MouseKeeper responds to only one: mousePressed(). This listener has to maintain state information, the coordinates of the last mouse press, that the frame accesses each time it paints itself.
Notice that we have to define empty methods for the other four responsibilities of mouse listeners, because the interface requires them! More on that soon.
Modify MouseListenerFrame so that it:
As we saw in our cannon game, an AWT Graphics object can draw a line for us:
g.drawLine( xStart, yStart, xEnd, yEnd );
Here's a possible solution, MouseClickDistanceFrame. Now we have to define an active mouseReleased() method, to record the coordinates of the release and tell the frame to repaint itself.
This time, I stored the points as IVs in the frame. Remember: the inner class has access to all the private stuff of its containing class, and the containing class has access to everything in the inner class.
We often find ourselves writing classes like MouseListenerFrame and MouseClickDistanceFrame, in which we want to define only one or two of the required methods in the MouseListener interface. Do we really have to write empty methods for the rest?
Not really. We just have to be sure that our class has them all. We can do that using an AWT class named MouseAdapter. Here's how.
An instance of MouseAdapter implements all five methods of the MouseListener interface, with empty methods. If we write a subclass of MouseAdapter, we have to implement only the methods we care about.
That sounds just like a 3-prong-to-2-prong electrical adapter in the "real world".
It responds to mouse presses and releases.
Nothing, in response to any sort of mouse event.
That is what we call such objects in real life. Java's creators use an analogy to name the object to help us understand it.
Inheritance is not free. Why force programmers who plan to implement most or all of the interface to pay the extra price?
Here's an alternative MouseClickDistanceFrame that defines its listener as a subclass of MouseAdapter. Because we need to define custom behavior only for mouse presses and mouse releases, we only have to write those two methods.
(Notice, too, the new import static... directives at the top of this program. Java 1.5 introduced "static imports", so that we don't have to use fully qulaified names for the Math.pow() and Math.sqrt() method.)
Please read the code of the pinball game construction kit, especially the frame class and the PinBallTarget interface. The frame class uses some of the ideas we learned today.
You can learn more about some of the Java GUI components we used today by read their javadoc: