Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
AhmadLang / Introduction to Programming Using Java-1.pdf
Скачиваний:
71
Добавлен:
31.05.2015
Размер:
5.27 Mб
Скачать

CHAPTER 6. INTRODUCTION TO GUI PROGRAMMING

260

user drags the mouse outside the drawing area while drawing a line, the mouseDragged routine changes the x and y coordinates to make them lie within the drawing area.

6.4.5Anonymous Event Handlers

As I mentioned above, it is a fairly common practice to use anonymous nested classes to define listener objects. As discussed in Subsection 5.7.3, a special form of the new operator is used to create an object that belongs to an anonymous class. For example, a mouse listener object can be created with an expression of the form:

new MouseListener() {

public void mousePressed(MouseEvent evt) { . . . } public void mouseReleased(MouseEvent evt) { . . . } public void mouseClicked(MouseEvent evt) { . . . } public void mouseEntered(MouseEvent evt) { . . . } public void mouseExited(MouseEvent evt) { . . . }

}

This is all just one long expression that both defines an un-named class and creates an object that belongs to that class. To use the object as a mouse listener, it should be passed as the parameter to some component’s addMouseListener() method in a command of the form:

component.addMouseListener( new MouseListener() { public void mousePressed(MouseEvent evt) { . . . }

public void mouseReleased(MouseEvent evt) { . . . } public void mouseClicked(MouseEvent evt) { . . . } public void mouseEntered(MouseEvent evt) { . . . } public void mouseExited(MouseEvent evt) { . . . }

} );

Now, in a typical application, most of the method definitions in this class will be empty. A class that implements an interface must provide definitions for all the methods in that interface, even if the definitions are empty. To avoid the tedium of writing empty method definitions in cases like this, Java provides adapter classes. An adapter class implements a listener interface by providing empty definitions for all the methods in the interface. An adapter class is useful only as a basis for making subclasses. In the subclass, you can define just those methods that you actually want to use. For the remaining methods, the empty definitions that are provided by the adapter class will be used. The adapter class for the MouseListener interface is named MouseAdapter. For example, if you want a mouse listener that only responds to mouse-pressed events, you can use a command of the form:

component.addMouseListener( new MouseAdapter() {

public void mousePressed(MouseEvent evt) { . . . } } );

To see how this works in a real example, let’s write another version of the ClickableRandomStringsApp application from Subsection 6.4.2. This version uses an anonymous class based on MouseAdapter to handle mouse events:

import java.awt.Component; import java.awt.event.MouseEvent;

import java.awt.event.MouseListener; import javax.swing.JFrame;

public class ClickableRandomStringsApp {

CHAPTER 6. INTRODUCTION TO GUI PROGRAMMING

261

public static void main(String[] args) {

JFrame window = new JFrame("Random Strings"); RandomStringsPanel content = new RandomStringsPanel();

content.addMouseListener( new MouseAdapter() {

//Register a mouse listener that is defined by an anonymous subclass

//of MouseAdapter. This replaces the RepaintOnClick class that was

//used in the original version.

public void mousePressed(MouseEvent evt) { Component source = (Component)evt.getSource(); source.repaint();

}

} );

window.setContentPane(content); window.setDefaultCloseOperation(JFrame.EXIT ON CLOSE); window.setLocation(100,75);

window.setSize(300,240);

window.setVisible(true);

}

}

Anonymous inner classes can be used for other purposes besides event handling. For example, suppose that you want to define a subclass of JPanel to represent a drawing surface. The subclass will only be used once. It will redefine the paintComponent() method, but will make no other changes to JPanel. It might make sense to define the subclass as an anonymous nested class. As an example, I present HelloWorldGUI4.java. This version is a variation of HelloWorldGUI2.java that uses anonymous nested classes where the original program uses ordinary, named nested classes:

import java.awt.*; import java.awt.event.*; import javax.swing.*;

/**

*A simple GUI program that creates and opens a JFrame containing

*the message "Hello World" and an "OK" button. When the user clicks

*the OK button, the program ends. This version uses anonymous

*classes to define the message display panel and the action listener

*object. Compare to HelloWorldGUI2, which uses nested classes.

*/

public class HelloWorldGUI4 {

/**

*The main program creates a window containing a HelloWorldDisplay

*and a button that will end the program when the user clicks it. */

public static void main(String[] args) {

JPanel displayPanel = new JPanel() {

// An anonymous subclass of JPanel that displays "Hello World!". public void paintComponent(Graphics g) {

super.paintComponent(g);

g.drawString( "Hello World!", 20, 30 );

}