15 Event Handling

15.1 INTRODUCTION

An event is any happening or occurring. Event-handling code is the heart of every useful application. All event-driven programs are structured around their event-processing model. Java events are a part of the Java Abstract Windowing Toolkit (AWT) package. An applet is basically an event-driven program in which events are generated by mouse, keyboard and window or other graphical user interface components. The events are passed to the events methods and there are specific methods for recognizing and handling the events.

There are two main models for handling events in Java: the old model, called the Inheritance Event Model, is obsolete; the new model, called the Delegation Event Model, will be discussed in detail.

There were a few flaws with the Java 1.0 Inheritance Event Model. One major problem was that an event could only be handled by the component that generated it or by one of the containers that contained the original component.

Another drawback with the Java 1.0 Inheritance Event Model was that a large number of CPU cycles were wasted on understanding events. Any event in which a program had no interest would just flow through the containment hierarchy before it was eventually discarded. The original model provided no way to disable irrelevant events.

With the new 1.1 Delegation Event Model, a component can be told which object or objects should be notified when it generates a particular type of event. If a component is not interested in an event type, then events of that type will not be propagated.

The primary design goals of the new model in the AWT are the following:

1.   Make it simple and easy to learn.

2.   Support a clean separation between an application and GUI code.

3.   Facilitate a clean creation of robust event which is less error-prone (strong compile-time checking).

4.   Make it flexible enough to enable varied application models for event flow and propagation.

5.   Enable, for visual tool builders, run-time discovery of both events that a component generates as well as the events it may observe.

6.   Support backward binary compatibility with the old model.

15.2 THE DELEGATION EVENT MODEL

The 1.1 Event Model is based on the concept of an "Event Source" and "Event Listeners". Any object that is interested in receiving messages (or events) is called an Event Listener, and any object that generates these messages (or events) is called an Event Source.

The Event Source Object maintains a list of interested objects in receiving events that it produces. The Event Source Object provides method that allows the listeners to add themselves ('register') or remove themselves from this list of 'interested' objects. When the Event Source Object generates an event, or when user input event occurs on the Event Source Object, the Event Source Object notifies all the listeners that the event has occurred.

An event is propagated from a "Source" object to a "Listener" object by invoking a method on the listener and passing in the instance of the event subclass which defines the event type generated. A Listener is an object that implements a specific EventListener interface that extends from the generic java.util. EventListener. An EventListener interface defines one or more methods that are to be invoked by the event source in response to each specific event type handled by the interface. An Event Source is an object that originates or "fires" events.

In an AWT program, the event source is typically a GUI component and the listener is commonly an "adapter" object which implements the appropriate listener (or set of listeners) in order for an application to control the flow/handling of events.

15.3 THE EVENT CLASSES

The Java 1.1 Event Model defines a large number of event classes. At the root of the Java event class hierarchy is java.util.EventObject. Every event is a subclass of java.util.EventObject. It is a very general class with only one method of interest.

Object getSource()

This method returns the object that originated the event. Every event has a source object, from which the event originated. This method returns a reference to that source.

java.awt.AWTEvent: AWT events, which is the main concern here, are subclasses of java. awt.AWTEvent. This is the super class of all the delegation model event classes. The most interesting method in this class is:

int getID()

This method returns the ID of the event. An event's ID is an int that specifies the exact nature of the event. This value is used to distinguish the various types that are represented by any event class.

java.awt.event is the subclass of java.awt.AWTEvent, which represents the various types that can be generated by the various AWT components. All the various types of AWT events are placed in a separate package called java.awt.event for the sake of convenience.

Class Description
ActionEvent Generated by component activation, like when a button is pressed.
AdjustmentEvent Generated by adjustment of adjustable components such as scroll bars.
ContainerEvent Generated when components are added to or removed from a container.
FocusEvent Generated when a component receives input focus.
ItemEvent Generated when an item is selected from a list, choice or check box.
KeyEvent Generated by keyboard activity.
MouseEvent Generated when a component is painted.
PaintEvent Generated when a text component is modified.
TextEvent Generated when a text component is modified.
WindowEvent Generated by window activity like minimizing or maximizing.

Table 15.1 Java Event class

15.4 EVENT LISTENERS

Event Listeners are objects that are responsible for handling a particular task of a component. They are notified when an event is occurred. The Listener typically implements the interface that contains event-handling code for a particular component. An EventListener interface will typically have a separate method for each distinct event type the event class represents.

The methods that receive and process events are defined in a set of interfaces found in java.awt.event(). For example, the FocusListener interface defines two methods, focusGained() and focusLost(), one for each event type that FocusEvent class represents.

Some of the listener interfaces are shown below:

java.awt.event.ComponentListener
java.awt.event.ContainerListerner
java.awt.event.FocusListerner
java.awt.event.keyListener
java.awt.event.MouseListener
java.awt.event.MouseMotionListener
java.awt.event.WindowListener
java.awt.event.ActionListener
java.awt.event.AdjustmentListener
java.awt.event.ItemListener
java.awt.event.TextListener

15.5 EVENT SOURCES

A source is an object that generates an event. A source registers listeners' notifications about events. Every source has different methods for registering the listeners. The general form is as follows:

public void addSTypeListener(STypeListener listener);

In this form, SType represents the event name. The method takes argument of STypeListener that represents reference to the event listener. It is actually an object of the class that implements any of the listener interfaces. For example, a method that registers mouse events is addMouseListener, a method that registers a Component event is addComponentListerner, etc. An event listener may be removed from an Event Source's list of interested Listeners by calling a removeSTypeListener() method, passing in the listener object to be removed.

One source can register more than one listener. Whenever an associated event occurs, all registered listeners are notified about the event-which is known as multicasting the event. In case the source is restricted to register just one listener, it is called unicasting the event.

15.6 DISCUSSION OF EVENT CLASSES

In this section, all the event classes, which have been discussed earlier, are discussed in detail. They are defined within the package java.awt.event.

1.   The ActionEvent class
The class is used for handling events like pressing a button, clicking a menu item or list box item. For all the events just mentioned an ActionEvent is generated. The class defines the following int constants.

images ACTION_PERFORMED
This event id indicates that a meaningful action occurred.

images SHIFT_MASK
It is shift modifier: an indicator that the shift key was held down during the event

images CTRL_MASTK
It is control modifier: an indicator that the control key was held down during the event.

images ALT_MASK
It is alt modifier; an indicator that the alt key was held down during the event.

The important method of this class are as follows:

(i)  public int getModifiers()
The method returns the modifier keys held down during this action event. It actually returns the bitwise-or of the modifier constants.

(ii) public String getActionCommand()
The method returns the command string associated with this action. For example, when a button is pressed, an action event is generated that has a command name equal to the label on that button.

2.   The AdjustmentEvent class
The class represents adjustment events generated by adjustable objects like scroll bar. The class defines five integer constants that represent five types of adjustment events. They are listed below:

images BLOCK_DECREMENT
This constant represents an event when the user clicks inside the scroll bar to decrease its value.

images BLOCK_INCREMENT
This constant represents an event when the user clicks inside the scroll bar to increase its value.

images TRACK
This constant represents an event when the user drags the slider or thumb of the scroll bar.

images UNIT_DECREMENT
This constant represents an event when the user presses the down arrow button at the end of the scroll bar.

images UNIT_INCREMENT
This constant represents an event when the user presses the down arrow button at the end of the scroll bar.

Apart from five integer constants, the class defines one more—ADJUSTMENT_VALUE_CHANGED that represents adjustment value changed event.

The class defines the following methods:

(i)   public Adjustable getAdjustable()
This method returns the Adjustable object where this event originated.

(ii)  public int getAdjustment Type()
This method returns the type of adjustment which caused the value changed event. It will have one of the following values:

(a) UNIT_INCREMENT

(b) UNIT_DECREMENT

(c) BLOCK_INCREMENT

(d) BLOCK_DECREMENT

(e) TRACK

(iii) public int getValue()
This method returns the current value in the adjustment event. For example, when any scroll bar event is generated, the current scroll bar value is returned.

3.   The ComponentEvent class
This class represents a low-level event which indicates that a component moved, changed size or changed visibility. It is the root class for the other component-level events classes like KeyEvent, MouseEvent, WindowEvent, etc. The class defines four integer constants that represent four types of component events. They are listed below:

images COMPONENT_HIDDEN
This event indicates that the component was rendered invisible.

images COMPONENT_MOVED
This event indicates that the component's position changed.

images COMPONENT_RESIZED
This event indicates that the component's size changed.

images COMPONENT_SHOWN
This event indicates that the component was made visible.

The class defines one useful method:

public Component getComponent()

The method returns the originator of the event.

4.   The Container
The class represents a low-level event which indicates that a container's contents changed because a component was added or removed. The two integers constant, COMPONENT_ADDED and COMPONENT_REMOVED, represent the two event types that indicate adding and removing a component to a container such as Panel. Container events are provided for notification purposes only; the AWT will automatically handle changes to the containers' contents internally so that the program works properly regardless of whether the program is receiving these events or not.

The class is the child class of ComponentEvent class . The class defines the two useful methods:

images public Container getContainer()
This method returns the originator of the event.

images public Component getChiled
This method returns the component that was affected by the event (i.e., added or removed).

5.   The FocusEvent class
The class represents a low-level event which indicates that a Component has gained or lost the input focus. This low-level event is generated by a Component (such as a TextField). The event is passed to every FocusListener or FocusAdaptor object which was registered to receive such events using the Component's addFocusListener method. (FocusAdaptor object implements the FocusListener interface.) Each such listener object gets this FocusEvent when the event occurs.

There are two levels of focus events: permanent and temporary. Permanent focus change events occur when focus is directly moved from one Component to another, such as through a call to requestFocus() or as the user uses the TAB key to traverse Components. Temporary focus change events occur when focus is temporarily lost for a Component as the indirect result of another operation, such as Window deactivation or a Scrollbar drag. In this case, the original focus state will automatically be restored once the operation is finished, or, in the case of Window deactivation, when the Window is reactivated. Both permanent and temporary focus events are delivered using the FOCUS_GAINED and FOCUS_LOST event ids; the level may be distinguished in the event using the isTemporary() method.

The method has this signature:

public boolean isTemporary()

It defines the focus change event as temporary or permanent. It returns true if the focus change is temporary, false otherwise.

6.   The InputEvent class
It is the root event class for all component-level input events. The class is the abstract class and MouseEvent and KeyEvent are its direct known subclasses. Input events are delivered to listeners before they are processed normally by the source where they originated. For example, consuming mousePressed events on a button component will prevent the button from being activated.

The class defines the following integer constants which can be used for getting information about the event.

ALT DOWN MASK BUTTON1_DOWN_MASK BUTTON2_DOWN_MASK
BUTTON3_DOWN_MASK CTRL_DOWN_MASK SHIFT_DOWN_MASK

All of the above constants designate pressing of certain keys when the event occurred.

The class defines the following methods that can be used to check whether the particular key was pressed when that event occurred. They are given below:

    boolean isAltDown()
    boolean isControlDown()
    boolean isShiftDown()

Each of the method returns true when any of the modifier Alt key, Ctrl key or Shift key was down on this event.

Apart from these methods there is a method getModifiersEx() that returns all of the flags as shown above in the form of integer constants. Its signature is as shown below:

    public int getModifierEx()

The method returns the extends modifier mask for this event. Extended modifiers represent the state of all modal keys, such as ALT, CTRL, SHIFT and the mouse buttons just after the event occurred.

7.   The ItemEvent class
The class represents a semantic event (occurred on some GUI object) which indicates that an item was selected or deselected. This high-level event is generated by an ItemSelected object (such as a List, Combobox, Checkbox, etc.) when an item is selected or deselected by the user. The event is passed to every ItemListener object which registered to receive such events using the component's addItemListener method.

The class defines the following integer constants:

images SELECTED
This state-change value indicates that an item was selected.

images DESELECTED
This state-change value indicates that a selected item was deselected.

images ITEM_STATE_CHANGED
This event id indicates that an item's state changed.

Useful methods of this class are as follows:

(a) public Object getItem()
This method returns the item affected by the event (i.e., generated the event).

(b) public int getStateChange()
This method returns the type of state change (i.e., an integer) that indicates whether the item was selected or deselected.

(c) public ItemSelectable getItem Selectable()
This method returns the ItemSelectable object that originated the event.

8.   The KeyEvent class
The class represents an event which indicates that a keystroke occurred in a component. This low-level event is generated by a component object (such as text field) when a key is pressed, released or typed. The event is passed to every KeyListener or keyAdapter object which registered to receive such events using the component's addKeyListener method (keyAdapter object implements the keyListener interface). Each such listener object gets this keyEvent when the event occurs.

The class defines following integer constants that recognize the associated event.

images KEY_TYPED
This is a "key typed" event. This event is generated when a character is entered.

images KEY_PRESSED
This is a "key pressed" event. This event is generated when a key is pushed down.

images KEY_RELEASED
This is a "key released" event. This event is generated when a key is released.

The difference between "key press" and "key typed" is that the latter occurs only when a character is pressed and "key press" occurs for any key that is present on the keyboard.

Apart from the above constants, the class also defines virtual key codes. Virtual key codes are used to report which keyboard key has been pressed, rather than a character generated by a combination of one or more keystrokes (such as "A", which comes from shift and "a"). For every key present on the keyboard, a virtual key code is defined that is identified by the following integer constants:

(a) VK_0 to VK_9 for numbers 0 to 9; they are same as ASCII 0 to 9.

(b) VK_A to VK_Z for alphabets A to Z; same as ASCII A to Z.

(c) VK_F1 VK_F24 for function keys F1 to F24.

(d) Some other virtual key codes are given in the following table.

images

The commonly used methods of this class are explained as follows:

i.   public char getKeyChar()
This method returns the character associated with the key in this event. For example, the KEY_TYPED event for shift + "a" returns the value for "A". Actually, the method returns unicode character defined for this key event. If no valid unicode character exists for this key event, CHAR_UNDEFINED is returned.

ii.  public int getKeyCode()
This method returns the integer keyCode associated with the actual key on the keyboard in this event. For KEY_TYPED events, the keyCode is VK_UNDEFINED.

iii. public static String getKeyText(int keyCode)
This method returns a String describing the keyCode, such as "HOME", "F1" or "A".

9.   The MouseEvent class
This class represents an event which indicates that a mouse action occurred in a component. This event is used both for mouse events (click, enter, exit) and mouse motion events (mouse and drags).

The low-level event is generated by a component object for the following:

images Mouse Events

(a) A mouse button is pressed.

(b) A mouse button is released.

(c) A mouse button is clicked (pressed and released).

(d) The mouse cursor enters the unobscured part of component's geometry.

(e) The mouse cursor exits the unobsured part of component's geometry.

images Mouse Motion Events

(a) The mouse is moved.

(b) The mouse is dragged.

For recognizing all the above listed mouse events, the MouseEvent class defines the following integer constants. There are some other constants too that are not used for recognizing the mouse events but are used for some other purpose associated with the event.

Constant Description
MOUSE CLICKED The "mouse clicked" event. This MouseEvent occurs when a mouse button is pressed and released.
MOUSE DRAGGED The "mouse dragged" event. This MouseEvent occurs when the mouse position changes while a mouse button is pressed.
MOUSE ENTERED The "mouse entered" event. This MouseEvent occurs when the mouse cursor enters the unobscured part of component's geometry.
MOUSE EXITED The "mouse exited" event. This MouseEvent occurs when the mouse cursor exits the unobscured part of component's geometry.
MOUSE MOVED The "mouse moved" event. This MouseEvent occurs when the mouse position changes.
MOUSE PRESSED The "mouse pressed" event. This MouseEvent occurs when a mouse button is pushed down.
MOUSE RELEASED The "mouse released" event. This is the only MouseEvent that occurs when a mouse button is let up.
MOUSE WHEEL The "mouse wheel" event. This is the only MouseWheelEvent. It occurs when a mouse equipped with a wheel has its wheel rotated.
BUTTON1 Indicates mouse button #1
BUTTON2 Indicates mouse button #2
BUTTON3 Indicates mouse button #3

Table 15.2 Constants defined by MouseEvent class

Some useful methods of this class are discussed as follows:

(i)   public int getButton()
This method returns one of the following constants: NOBUTTON, BUTTON1, BUTTON2 and BUTTON3 to indicate which mouse button has changed state.

(ii)  public int getClickCount()
This method returns the number of mouse clicks (an integer value) associated with this event.

(iii) public Point getPoint()
This method returns a point object containing the x and y coordinates relative to the source component.

(iv)  public int getX()
This method returns the horizontal x position of the event where mouse event occurred.

(v) public void translatePoint(int x, int y)

This method translates the event's coordinates to a new position by adding specified x (horizonatal) and y (vertical) offsets. Parameters x and y are the horizontal x value and vertical y value to add to the current x and y coordinate position, respectively.

10.   The TextEvent class
This class represents a semantic event which indicates that an object's text changed. This high-level event is generated by an object (such as a TextComponent) when its text changes. The event is passed to every TextListener object which is registered to receive such events using the component's addTextListener method.

This class defines one final integer constant TEXT_VALUE_CHANGED that indicates that object's text changed. No such method of this class is of interest.

11. The WindowEvent class
This class represents a low-level event that indicates that a window has changed its status. This low-level event is generated by a Window object when it is opened, closed, activated, deactivated, iconified or deinconfied, or when focus is transferred into or out of the Window.

The event is passed to every WindowListener or WindowAdapter object which registered to receive such events using the window's addWindowListener method. (WindowAdapter objects implement the WindowListener interface.) Each such listener object gets this WindowEvent when the event occurs.

The various constants for recognizing the window events are listed in Table 15.3.

Constant Description
WINDOW ACTIVATED The window-activated event type. This event is delivered when the Window becomes the active Window. Only a Frame or a Dialog can be the active Window.
WINDOW CLOSED The window closed event. This event is delivered after the window has been closed as the result of a call to dispose.
WINDOW CLOSING The "window is closing" event. This event is delivered when the user attempts to close the window from the window's system menu.
WINDOW DEACTIVATED The window-deactivated event type. This event is delivered when the Window is no longer the active Window. Only a Frame or a Dialog can be the active Window.
WINDOW DEICONIFIED The window deiconified event type. This event is delivered when the window has been changed from a minimized to a normal state.
WINDOW INCONIFIED The window deiconified event type. This event is delivered when the window has been changed from a normal to a minimized state.
WINDOW OPENED The window opened event. This event is delivered only the first time a window is made visible.

Table 15.3 Constants defined by WindowEvent class

The most commonly used method of this class is the getWindow() whose signature is given below:

    public Window getWindow()

The method returns the Window object that originated the event.

15.7 THE LISTENERS INTERFACES

After discussing the Event classes it is time now to discuss the key interface listeners. Listeners are nothing but instances of classes that implement listeners interface defined by java.awt.event package. The Listeners classes implement the interfaces by providing the body for the methods. All listener interfaces have their EventListener as their super interface. All the listener interfaces and their respective methods are discussed below:

1.   The Actionlistener interface
It is the listener interface for receiving action event. The class that is interested in processing an action event implements this interface, and the object created with that class is registered with a component, using the component's addActionListener method. When the action event occurs, that objects' actionPerformed method is invoked.

Source of event for this listener is objects of Button class. The interface has just one method.

     void actionPerformed(ActionEvent e)

The method is invoked when an action occurs (i.e., when a button is pressed).

2.   The Adjustmentlistener interface
It is the listener interface for receiving adjustment events. The interface defines just one method:

     void adjustmentValueChanged(AdjustmentEvent e)

Source of event for this listener is object's Scrollbar class. The method is invoked when the value of the adjustable has changed.

3.   The ComponentListener interface
It is the listener interface for receiving component events. The class that is interested in processing a component event either implements this interface (and all the methods it contains) or extends the abstract ComponentAdapter class (overriding only the methods of interest). The listener object created from that class is then registered with a component using the component's addComponentListener method. When the component's size, location or visibility changes, the relevant method in the listener object is invoked, and the ComponentEvent is passed to it.

Component events are provided for notification purposes only. The AWT will automatically handle component moves and resize internally so that GUI layout works properly regardless of whether a program registers a ComponentListener or not.

The interface has following four methods:

images void componentHidden(ComponentEvent e)
This method is invoked when the component has been made invisible.

images void componentMoved(ComponentEvent e)
This method is invoked when the component's position changes.

images void component Resized(ComponentEvent e)
This method is invoked when the component size changes.

images void componentShown(COmponentEvent e)
This method is invoked when the component has been made visible.

4.   The ContainerListener interface
It is the listener interface for receiving container events. The class that is interested in processing a container event either implements this interface (and all the methods it contains) or extends the abstract ContainerAdapter class (overriding only the method of interest). The listener object created from that class is then registered with a component's addContainerListener method. When the container's content changes because a component has been added or removed, the relevant method in the listener object is invoked, and the ContainerEvent is passed to it.

The interface has the following methods:

images void componentAdded(ContainerEvent e)
This method is invoked when a component has been added to the container.

images void componentRemoved(ContainerEvent e)
This method is invoked when a component has been removed from the container.

5.   The FocusListener interface
It is the listener interface for receiving keyboard focus events on a component. The class that is interested in processing a focus event either implements this interface (and all the methods it contains) or extends the abstract FocusAdaptor class (overriding only the methods of interest). The listener object created from that class is then registered with a component using the component's addFocusListener method. When the component gains or loses keyboard focus, the relevant method in the listener object is invoked, and the FocusEvent is passed to it.

The interface has two methods:

images void focusGained(FocusEvent e)
This method is invoked when a component gains the keyboard focus.

images void focusLost(FocusEvent e)
This method is invoked when a component loses the keyboard focus.

6.   The ItemListener interface
It is the listener interface for receiving item events. The class that is interested in processing an item event implements this interface. The object created with that class is then registered with a component using the component's addItemListener method. When an item-selection event occurs, the listener object's itemStateChanged method is invoked. The signature of the method is shown below:

     void itemStateChanged(ItemEvent e)

This method is invoked when an item has been selected or deselected by the user. The code written for this method performs the operations that need to occur when an item is selected (or deselected).

7.   The KeyListener interface
It is the listener interface for receiving keyboard events (keystrokes). The class that is interested or processing a keyboard event either implements this interface (and all the methods it contains) or extends the abstract keyAdaptor class (overriding only the methods of interest).

The listener object created from that class is then registered with a component using the component's addkeyListener method. A keyboard event is generated when a key is pressed, released or typed. The relevant method in the listener object is then invoked, and the KeyEvent is passed to it.

The interface declares the following methods:

images void keyTyped(KeyEvent e)
This method is invoked when a key has been typed.

images void keyPressed(KeyEvent e)
This method is invoked when a key has been pressed.

images void keyReleased(KeyEvent e)
This method is invoked when a key has been released.

For more about these events refer discussion of KeyEvent class.

8.   The MouseListener interface
It is the listener interface for receiving "interesting" mouse events (press, release, click, enter and exit) on a component. The class that is interested in processing a mouse event either implements this interface (and all the methods it contains) or extends the abstract MouseAdapter class (overriding only the methods of interest). The interface declares the following methods:

images void mouseClicked(MouseEvent e)
This method is invoked when the mouse button has been clicked (pressed and released) on a component.

images void mousePressed(MouseEvent e)
This method is invoked when a mouse button has been pressed on a component.

images void mouseReleased(MouseEvent e)
This method is invoked when a mouse button has been released on a component.

images void mouseEntered(MouseEvent e)
This method is invoked when the mouse enters a component.

images void mouseExited(MouseEvent e)
This method is invoked when the mouse exits a component.

9.   The MouseMotionListener interface
It is the listener interface for receiving mouse motion events on a component. A mouse motion event is generated when the mouse is moved or dragged. The class that is interested in processing a mouse motion event either implements this interface (and all the methods it contains) or extends the abstract MouseMotionAdapter class (overrides only the methods of interest).

The interface declares the following methods:

images void MouseDragged(MouseEvent e)
This method is invoked when a mouse button is pressed on a component and then dragged. MOUSE_DRAGGED events will continue to be delivered to the component where the drag originated until the mouse button is released.

images void mouseMoved(MouseEvent e)
This method is invoked when the mouse cursor has been moved onto a component but no buttons have been pushed.

10. The TextListener interface
It is the listener interface for receiving text event. The class that is interested in processing a text event implements this interface. The object created with that class is then registered with a component using the component's addTextListener method. When the component's text changes, the listener object's textValueChanged method is invoked.

The signature of the method is given below:

     void textValueChnaged(TextEvent e)

11. The WindowListener interface
It is the listener interface for receiving window events. The class that is interested in processing a window event either implements this interface (and all the methods it contains) or extends the abstract WindowAdapter class (overriding only the methods of interest). The listener object created from that class is then registered with a Window using the window's addWindowListener method. When the window's status changes by virtue of being opened, closed, activated or deactivated, iconified or deiconified, the relevant method in the listener object is invoked, and the WindowEvent is passed to it.

The interface declares the following methods for recognizing various window-related events.

images void windowDeactivated(WindowEvent e)
This method is invoked when a Window is no longer the active Window. The active Window is always either the focused Window, or the first Frame or Dialog that is an owner of the focused Window.

images void windowClosed(WindowEvent e)
This method is invoked when a window has been closed as the result of calling dispose on the window.

images void windowClosing(WindowEvent e)
This method is invoked when the user attempts to close the window from the window's system menu.

images void windowActivated(WindowEvent e)
This method is invoked when the Window is set to be the active Window.

images void windowDeiconified(WindowEvent e)
This method is invoked when a window is changed from a minimized to a normal state.

images void windowIconified(WindowEvent e)
This method is invoked when a window is changed from a normal to minimized state.

images void windowOpened(WindowEvent e)
This method is invoked the first time a window is made visible.

15.8 PROGRAMMING EXAMPLE

15.8.1 Handling Mouse Events

/*PROG 15.1 DISPLAYING "JAVA" ON MOUSE CLICK VER 1*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<applet code="mouse1" width =350 height = 120>
</applet>
</html>
*/
public class mouse1 extends Applet implements MouseListener
{
   public void init()
   {
          addMouseListener(this);
   }
   public void mouseClicked(MouseEvent me)
   {
          Graphics g = getGraphics();
          g.drawString("JAVA", me.getX(), me.getY());
   }
   public void mouseExited(MouseEvent me) { }
   public void mousePressed(MouseEvent me) { }
   public void mouseReleased(MouseEvent me) { }
   public void mouseEntered(MouseEvent me) { }
}
OUTPUT:

images

Figure 15.1 Output screen of Program 15.1

Explanation: In this program, the class mouse1 implements MouseListener interface. In the program the mouseClicked method has only been dealt with so code is written only inside this method. But as it is necessary to provide implementation of all the methods of interface no code is written inside the braces of all the other methods like mouseExited, mousePressed, etc. The listener is added using the method addMouseListener that is provided by the Component class. This method can be used directly because the Component class is the super class of Applet class. The method takes a reference of the MouseListener interface. Its signature is as shown below:

public void addMouseListener(MouseListener ml)

Here, ml is a reference to the object receiving mouse events, as this represents current object of the class that has been used as argument to this method.

In the program, the source and listener object as events are generated and listened by the applet. In the programs where GUI elements are used, sources will be Button, List, Checkbox, etc. They will be introduced in the next chapter. The code in the init method can be written as follows:

MouseListener ml;
addMouseListener(ml);

Whenever mouse is clicked in the applet window, mouseClicked event is generated and listener can listen this event. In response to the event mouseClicked, method is called. In the method, current graphics context is obtained by using getGraphics method. The point where mouse was clicked is taken using getX and getY methods, then using drawstring on the current coordinates "JAVA" is displayed.

/*PROG 15.2 DISPLAYING "JAVA" ON MOUCE CLIKC VER 2 */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<applet code="mouse2" width = 350 height = 120>
</applet>
</html>
*/
public class mouse2 extends Applet implements MouseListener
{
   String msg = " ";
   int mx = 0, my = 0;
   static int i = 0;
   public void init()
   {
          addMouseListener(this);
   }
   public void mouseClicked(MouseEvent me)
   {
          Color[]col ={Color.red,Color.green, Color.blue,
                        Color.pink,Color.magenta,
                        Color.yellow};
          mx = me.getX();
          my = me.getY();
          Graphics g = getGraphics();
          g.setColor(col[i%6]);
          i++;
          g.drawString("JAVA",mx,my);
   }
   public void paint(Graphics g)
   {
          g.drawString(msg, mx, my);
   }
   public void mouseExited(MouseEvent me) { }
   public void mousePressed(MouseEvent me) { }
   public void mouseReleased(MouseEvent me) { }
   public void mouseEntered(MouseEvent me) { }
}

images

Figure 15.2 Output screen of Program 15.2

Explanation: The program is similar to the previous one but here "JAVA" has been displayed on current mouse coordinate in colors. For this reason, an array of colors of Color class has been created. Whenever the mouse click event occurs, mouseclicked method is called. In the method, the new foreground color is set by method setForeground. Due to i%6, different indexes between 0 to 5 are generated and entries between col[0] and col[5] are selected.

/*PROG 15.3 DEMO OF MOUSE_ENTERED AND EXITED EVENT */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<applet code="mouse3" width =350 height = 120>
</applet>
</html>
*/
public class mouse3 extends Applet implements MouseListener
{
   String msg = " ";
   public void init()
   {
          addMouseListener(this);
   }
   public void mouseExited(MouseEvent me)
   {
          setBackground(Color.red);
          msg = "Mouse Pointer Out";
   }
   public void mouseEntered(MouseEvent me)
   {
          setBackground(Color.green);
          msg = "Mouse Pointer In";
   }
   public void paint(Graphics g)
   {
          g.drawString(msg, 50, 50);
   }
   public void mousePressed(MouseEvent me) { }
   public void mouseReleased(MouseEvent me) { }
   public void mouseClicked(MouseEvent me) { }
}

images

Figure 15.3 Output screen of Program 15.3

Explanation: The program demonstrates mouseEntered and mouseExited methods. The program is simple: When the mouse pointer is inside the applet, mouseEntered method is called. This cause to paint method on the background of the applet window because, mouseExited method is invoked. This causes to paint the background of the applet window in red color and display string " Mouse Pointer Out". Note the paint is called default after both the events.

/*PROG 15.4 BEHAVIOUR OF METHODS OF MOUSELISTENER INTERFACE */
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
/*
<html>
<applet code="mouse4" width =350 height = 120>
</applet>
</html>
*/
public class mouse4 extends Applet implements MouseListener
{
   String msg = " ";
   int mx, my;
   public void init(){
          addMouseListener(this);
   }
   public void mousePressed(MouseEvent me)
   {
          setForeground(Color.red);
          msg = "Mouse Pressed";
          mx = me.getX();
          my = me.getY();
  }
  public void mouseReleased(MouseEvent me)
  {
         setForeground(Color.green);
         msg = "Mouse Released ";
         mx = me.getX();
         my = me.getY();
  }
  public void paint(Graphics g) {
         g.drawString(msg, mx, my);
  }
  public void mouseClicked(MouseEvent me)
  {
         //msg = "Mouse Clicked";
  }
  public void mouseEntered(MouseEvent me) { }
  public void mouseExited(MouseEvent me) { }
}

images

Figure 15.4 Output screen of Program 15.4

Explanation: The program is simple to understand. The code is written over mousePressed and mouseReleased methods. One important thing to note here is that mousePressed is called first, then mouseClicked, and when both are implemented, mouseReleased does not work.

/*PROG 15.5 DRAWING RANDOM LINES, KEEPING ONE POINT FIX */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<applet code="mouse5" width =350 height = 120>
</applet>
</html>
*/
public class mouse5 extends Applet implements
MouseMotionListener
{
    int x, y, w, h;
    public void init(){
           addMouseMotionListener(this);
           h = this.getSize().height;
           w = this.getSize().width;
   }
   public void mouseDragged(MouseEvent me)
   {
   }
   public void mouseMoved(MouseEvent me){
      x = (int)(Math.random() * 10000);
      y = (int)(Math.random() * 10000);
      Graphics g = getGraphics();
      g.setColor(new Color(x%255, y%255,(x * h)%255));
      g.drawLine(w / 2, h / 2, x % w, y % h);
     }
}

images

Figure 15.5 Output screen of Program 15.5

Explanation: In this program, the MouseMotion Listener interface is implemented. Here, only the mouseMoved event has been dealt with so any coding has not been given in the mouseDragged method. The listener is added using the addMouseMotion Listener which is provided by the Component class as explained with the first program. The signature of the method is given below:

public void addMouseMotionListener(MouseMotionListener mml)

The method takes a reference to the object receiving mouse motion events.

Applet window's width and height are obtained using this.getSize().width and this. getSize().height. Actually, the getSize() method returns a reference of Dimension class, and height and width are its two members. So the code can also be written as:

Dimension D = this.getSize();
w = D.width;
h = D.height;

When the mouse is moved mouseMoved method is called. This is how the listener is registered. In this method, two random integer numbers between 0 and 10,000 are returned in x and y. Using these random integers, random colors are generated. While drawing lines of random length, one point is kept fixed at the centre of the applet window. The end is anywhere between the height and width of the applet window.

/*PROG 15.6 FREEHAND DRAWING USING MOUSE */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<applet code="mouse6" width =350 height = 120>
</applet>
</html>
*/
public class mouse6 extends Applet implements MouseListener,
MouseMotionListener
{
   String msg = " ";
   int px, py, cy, cx;
   boolean press = true;
   public void init()
   {
          addMouseListener(this);
          addMouseMotionListener(this);
          cx = cy = px = py = 0;
   }
   public void mousePressed(MouseEvent me)
   {
          if (press == true)
          {
               px = me.getX();
               py = me.getY();
               press = false;
          }
  }
  public void mouseReleased(MouseEvent me)
  {
         press = true;
  }
  public void mouseDragged(MouseEvent me)
  {
         cx = me.getX();
         cy = me.getY();
         Graphics g = getGraphics();
         g.drawLine(px, py, cx, cy);
         px = cx;
         py = cy;
   }
   public void mouseClicked(MouseEvent me)
   {
   }
   public void mouseEntered(MouseEvent me) { }
   public void mouseExited(MouseEvent me) { }
   public void mouseMoved(MouseEvent me) { }
}

Explanation: The program demonstrates how freehand drawing can be performed using mouse events. The logic is simple. Think of a line as a series of connected points so close to each other that the line appears smooth. One boolean variable press is taken. The initial value of this is true. When the mouseDragged method is called in response to mouse-dragged event, press will be true. The current mouse coordinate is saved in the px and py coordinate and method returns due to if condition. The value of press becomes false here. It is necessary that till the mouse is dragged, initial point is to be saved only once. Next time when the method is called again, new points are saved in cx and cy. Now a line is drawn from point (px, py) to (cx, cy). After drawing the line, the current coordinates become the previous ones as they are saved to px and py. Next time again when method is called, line is drawn and cx and cy are saved to px and py.

images

Figure 15.6 Output screen of Program 15.6

When the mouse is released, press becomes true again.

15.8.2 Handling Keyboard Events

/*PROG 15.7 IMPLEMENTING KEYLISTENER INTERFACE VER 1 */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<applet code="keypress1" width =350 height = 120>
</applet>
</html>
*/
public class keypress1 extends Applet implements KeyListener
{
   String msg = " ";
   public void init()
   {
          addKeyListener(this);
   }
   public void keyPressed(KeyEvent ke)
   {
          msg = "Key is down";
          repaint();
   }
   public void keyReleased(KeyEvent ke)
   {
          msg = "Key is UP";
          repaint();
   }
   public void keyTyped(KeyEvent ke) { }
   public void paint(Graphics g)
   {
          g.drawString(msg, 20, 20);
   }
}

images

Figure 15.7 Output screen of Program 15.7

Explanation: In this program, KEY_PRESSED and KEY_RELEASED events are demonstrated. Similar to implementing MouseListener and MouseMotionListener interface, KeyListener interface has to be implemented. We also add a listener using addKeyListener method. The signature of the method is as shown:

public void addKeyListener(KeyListener l);

The method adds the specified key listener to receive key events from this component.

When a KEY_PRESSED event occurs, keyPressed method is called and when KEY_RELEASED event occurs, keyPressed method is called. When any key is pressed, the method keyPressed executes and msg contains "Key is down". The method repaint() calls the paint method and "Key is down" is displayed at (20, 20). When the key is released, the method keyReleased executes and msg contains "Key is UP". The method repaint() calls the paint method and "Key is UP" is displayed at (20, 20).

/*PROG 15.8 IMPLEMENTING KEYLISTENER INTERFACE VER 2*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<applet code="keypress2" width =350 height = 120>
</applet>
</html>
*/
public class keypress2 extends Applet implements KeyListener
{
   String msg = " ";
   public void init()
   {
          addKeyListener(this);
   }
   public void keyPressed(KeyEvent ke) { }
   public void keyReleased(KeyEvent ke) { }
   public void keyTyped(KeyEvent ke)
   {
          char ch = ke.getKeyChar();
          msg = msg + ch;
          repaint();
   }
   public void paint(Graphics g)
   {
          g.drawString(msg, 10, 20);
   }
}

images

Figure 15.8 Output screen of Program 15.8

Explanation: In this program, the KEY_TYPED event is used. The event is used when the character from the generated key is required. When KEY_TYPED event occurs, keyTyped method is called. In this method, the character associated with the key typed using getKeyChar method is obtained. The character is concatenated with the msg string. The resultant string thus obtained is displayed in the paint method. The method is invoked in response to repaint() method.

/*PROG 15.9 IMPLEMENTING KEYLISTENER INTERFACE VER 3*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class keypress3 extends Applet implements KeyListener
{
   String msg = " ";
   int x, y, px, py;
   public void init()
   {
          addKeyListener(this);
          px = 30; py = 50;
          x = px;
          y = py;
   }
   public void keyPressed(KeyEvent ke)
   {
          int code = ke.getKeyCode();
          switch (code)
          {
                case KeyEvent.VK_LEFT:
                       x--;
                       break;
                case KeyEvent.VK_RIGHT:
                       x++;
                       break;
                case KeyEvent.VK_UP:
                       y--;
                       break;
                case KeyEvent.VK_DOWN:
                       y++;
                       break;
          }
          Graphics g = getGraphics();
          g.drawLine(px, py, x, y);
          px = x;
          py = y;
      }
      public void keyReleased(KeyEvent ke) { }
      public void keyTyped(KeyEvent ke) { }
}

images

Figure 15.9 Output screen of Program 15.9

Explanation: In this program, the virtual key codes are used for the arrow keys. The key code is taken using the method getKeyCode and stored in the code variable. In the program, lines are needed to be drawn using arrow keys. For this purpose, the starting coordinate chosen is 30 and 50 and stored in px and py. The same is stored in x and y also. Now depending on which arrow key is pressed, x and y are incremented/decremented accordingly. For example, when left arrow key is pressed, x is decremented by 1 and when up arrow key is pressed, y is decremented by 1. Outside the switch block, line is drawn from point (px, py) to (x, y) and old points are updated with the values of x and y.

15.9 ADAPTER CLASSES

Some of the listener interface, such as MouseListener and ComponentListener, include a lot of methods. The rules for interfaces say that when a class implements an interface, it must include a definition for each method declared in the interface. For example, if empty is included only using the mousePressed method of the MouseListener interface, one ends up including empty definitions for mouseClicked (), mouseReleased(), mouseEntered() and mouseExited(). If a specially created nested class is used to handle events, there is a way to avoid this. As a convenience, the package java.awt.event includes several adapter classes, such as MouseAdapter and ComponentAdapter. An adapter class is a class that provides an empty implementation of all methods in an event listener interface. Adapter classes can be used when one is not interested in all of the methods of the interface, except one or two. The MouseAdapter class is a trivial class that implements the MouseListener interface by defining each of the methods in that interface to be empty. To make the programmer's mouse listener classes, one can extend the MouseAdapter class and override just those methods of interest. ComponentAdapter and other adapter classes work in the same way.

All of the Adapter classes are defined within the java.awt.event package. They are listed in Table 15.4 along with the related listener interface.

Adapter Class Listener Interface
ComponentAdapter ComponentListener
ContainerAdapter ContainerListener
KeyAdapter KeyListener
MouseAdapter MouseListener
MouseMotionAdapter MouseMotionListener
WindowAdapter WindowListener

Table 15.4 Adapter classes and counterpart listeners

The use of Adapter classes is explained with the help of a small program. The "Java" program is written (i.e., wherever in the applet window mouse is clicked then "Java" will be displayed at that point).

/*PROG 15.10 DEMO OF MOUSEADAPTER CLASS */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<pre>
<applet code="Ademo" width =350 height = 120>
</applet>
</html>
*/
public class Ademo extends Applet
{
   public void init()
   {
          MyMouseAdapter mma = new MyMouseAdapter(this);
          addMouseListener(mma);
   }
}
class MyMouseAdapter extends MouseAdapter
{
   Ademo m;
   public MyMouseAdapter(Ademo ad)
   {
     m = ad;
   }
   public void mouseClicked(MouseEvent me)
   {
          Graphics g = m.getGraphics();
          g.drawString("Java", me.getX(), me.getY());
   }
}

images

Figure 15.10 Output screen of Program 15.10

Explanation: In this program, a new class MyMouseAdapter is created that extends MouseAdapter class. In this class, the default empty implementation of mouseClicked method is overridden. In the main applet window class Ademo, an instance of MyMouseAdapter class is implemented and passed as argument to addMouseListener method. Note while creating an instance of MyMouseAdapter class reference of the current object of Ademo class is passed. For this reason, a reference m of Ademo class is created as a member of MyMouseAdapter class. This is necessary as the passed instance can be used for calling any of the method of Component or Applet class. Using this reference, the method getGraphics is called for getting a reference to Graphics class. The rest is simple to understand. As another example keyTyped is written using KeyAdapter class.

As another example keyTyped is written using KeyAdapter class.

/*PROG 15.11 DEMO OF KEYADAPTER CLASS */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<html>
<applet code="Adapter1" width =350 height = 120>
</applet>
</html>
*/
public class Adapter1 extends Applet
{
   String msg = " ";
   public void init()
   {
          addKeyListener(new MyKeyAdapter(this));
   }
   public void paint(Graphics g)
   {
          g.drawString(msg, 10, 20);
   }
}
class MyKeyAdapter extends KeyAdapter
{
   Adapter1 mka;
   MyKeyAdapter(Adapter1 m)
   {
          mka = m;
   }
   public void keyTyped(KeyEvent ke)
   {
          char ch = ke.getKeyChar();
          mka.msg = mka.msg + ch;
          mka.repaint();
   }
}

images

Figure 15.11 Output screen of Program 15.11

Explanation: This program is simple to understand on the basis of explanation of the previous one.

15.10 NESTED AND INNER CLASSES

It is possible to place a class definition within another class definition. This is called nested class . The nested class is a valuable feature because it allows the programmer to group classes that logically belong together and to control the visibility of one within the other. The scope of nested class is limited to the scope of the class in which it is nested. For example, if class In is defined inside the class Out, In will be known to Out class only, but the reverse is not true. Class In can access all the members of the Out class directly regardless of their type: be it private, protected or any other, but class Out cannot access any of the member of the In class.

There are two types of nested classes: static nested class and non-static nested class.

A static nested class is the one that has static keyword written before class definition. A static class can access all the members of its enclosing class only through objects. It cannot access them directly. In general, static nested class is called simply the nested class.

A non-static nested class is the one where static keyword is not present before class definition. The most important type of nested class is the inner class. It can access all the members of its enclosing class without using an object. This being the reason, it is frequently used. In general, non-static nested class is called the inner class. Fields and methods in ordinary inner classes can only be at the outer level of a class, so ordinary inner classes cannot have static data, static fields or nested classes. Inner classes are covered in this section and the static nested classes in the next.

As an elementary example of inner class consider the program given below:

/*PROG 15.12 DEMO OF INNER CLASS VER1 */
class demo
{
   void show()
   {
         demo1 d1 = new demo1();
         d1.display();
   }
   class demo1
   {
         void display()
         {
                System.out.println("Hello from display of
                                    inner class");
         }
   }//inner class ends
}//outer class ends
class JPS1
{
   public static void main(String[] args)
   {
          demo d = new demo();
          d.show();
   }
}
OUTPUT:

Hello from display of inner class

Here, class demo1 is defined within the class demo, so it is an example of nested inner class. The class demo1 has only one function display. The outer class demo defines one method named show in which an object of inner class demo is created through which the object display method is called. Note the reverse will not be true; one cannot call show method through an object of demo class. In the main, an object of outer class demo is created and show method is called which in turn calls the display method of inner class demo1 using d1.

Take one more example where temp method is accessed from inner class demo. The private members are also introduced to in the outer class demo.

/*PROG 15.13 DEMO OF NESTED INNER CLASS VER2 */
class demo
{
   private int dx = 20;
   private String str = "Outer Class";
   void show()
   {
          demo1 d1 = new demo1();
          d1.display();
   }
   void temp()
   {
      System.out.println("HELLO FROM TEMP OF OUTER CLASS");
   }
   class demo1
   {
          void display()
          {
                 System.out.println("
Inside display of
                                     inner class");
                 System.out.println("dx = " + dx);
                 System.out.println("str = " + str);
                 temp();
          }
   }//inner class ends
}//outer class ends
class JPS2
{
   public static void main(String[] args)
   {
          demo d = new demo();
          d.show();
   }
}
OUTPUT:

Inside display of inner class
dx = 20
str = Outer Class
HELLO FROM TEMP OF OUTER CLASS

The outer class demo has two private members and two methods: show and temp. Inside show, an object of inner class demo1 is created and the display method of inner class is called. In the display method of inner class, the private members dx and str of demo class are accessed. The temp function of demo class is also accessed. Thus, the inner class has full access to all the members of its enclosing class directly. Put in different perspective, treat inner class as any other data member or method of the outer class, then understanding inner class will not be a problem.

Next, consider an example where the members of the inner class is to be accessed in the outer class. Members of the inner class are known only within the scope of the inner class and may not be used by the outer class.

/*PROG 15.14 DEMO OF NESTED AND INNER CLASS VER 3 */
class demo
{
   private String str_out = "OUTER CLASS";
   void show()
   {
          demo1 d1 = new demo1();
          d1.display();
   }
   class demo1
   {
         private String str_in = "INNER CLASS";
         void display()
         {
                System.out.println("
Inside display of
                                    inner class");
                System.out.println("str_in = " + str_in);
                System.out.println("str_out = " + str_out);
         }
   }//inner class ends
   void temp()
   {
          System.out.println("
Inside temp of outer
                                  class");
          System.out.println("str_in = " +str_in);
          System.out.println("str_out = " +str_out);
   }
}//outer class ends
class JPS3
{
   public static void main(String[] args)
   {
          demo d = new demo();
          d.show();
          d.temp();
   }
}
OUTPUT:

C:JPSch15>javac JPS3.java
JPS3.java:23: cannot find symbol
symbol  : variable str_in
location: class demo
                 System.out.println("str_in = " +str_in);
                                                 ^
1 error

Clearly, the data member str_in of inner class is only within the scope of inner class demo1. It can only be used within the class demo1, but not outside (i.e., not within its enclosing class that is demo). So the compilation error is flashed.

The next example demonstrates how a method can be created in the outer class which returns a reference to inner class. Using this reference in the main, members of inner class can be accessed.

/*PROG 15.15 DEMO OF NESTED AND INNER CLASS VER 4 */
class demo
{
   private String str_out = "OUTER CLASS";
   class demo1
   {
          private String str_in = "INNER CLASS";
          void display()
          {
                 System.out.println("
 Inside display of
                                        inner class");
                 System.out.println(" str_in  = " + str_in);
                 System.out.println(" str_out = " + str_out);
          }
   }//inner class ends
   demo1 getref()
   {
         return new demo1();
   }
}//outer class ends
class JPS4
{
   public static void main(String[] args)
   {
          demo d = new demo();
          demo.demo1 d1 = d.getref();
          d1.display();
   }
}
OUTPUT:

Inside display of inner class
str_in  = INNER CLASS
str_out = OUTER CLASS

Here, the class demo1 is inner class once again. The outer class demo is having one method getref which is returning a reference of inner class. This is perfectly valid. In the main, an object d of outer class demo is created. Note how a reference d1 of inner class demo1 has been created:

demo.demo1 d1;

As demo1 is the inner class for demo class, it can be written using dot operator. Now as method getref is returning a reference of demo1 class, that method is called using object d of demo class and assigned it to d as:

demo.demo1 d1 = d.getref();

As it has a valid object of inner class demo1 represented by d1, the method display of inner class can be called. The concept to build here is that:

"If you want to make an object of the inner class anywhere except from within a non-static method of the outer class, you must specify the type of that object as OuterClassName.InnerClassName, as seen in main()."

However, there is another way of getting the reference of the inner class with slightest of variation from the previous program.

/*PROG 15.16 DEMO OF NESTED AND INNER CLASS VER 5 */
class demo
{
   private String str_out = "OUTER CLASS";
   class demo1
   {
          private String str_in = "INNER CLASS";
          void display()
          {
                 System.out.println("
 Inside display of
                                     inner class");
                 System.out.println(" str_in  = " + str_in);
                 System.out.println(" str_out = " + str_out);
          }
   }//inner class ends
}//outer class ends
class JPS5
{
   public static void main(String[] args)
   {
          demo d = new demo();
          demo.demo1 d1 = d.new demo1();
          d1.display();
   }
}
OUTPUT:

Inside display of inner class
str_in  = INNER CLASS
str_out = OUTER CLASS

Here, to create the object of inner class demo1, an object d of outer class demo is first created and using d.new demo1() statement, the object of class demo1 is created.

/*PROG 15.17 DEMO OF NESTED AND INNER CLASS VER 6 */
class demo
{
   static int num = 20;
   class demo1
   {
          static void display()
          {
            System.out.println("Hello from display num:"+num);
          }
   }//inner class ends
}//outer class ends
class JPS6
{
   public static void main(String[] args)
   {
          demo.demo1.display();
   }
}
OUTPUT:

C:JPSch15>javac JPS6.java
JPS6.java:7: inner classes cannot have static declarations
                static void display()
                            ^
1 error

As stated above, inner classes cannot have static data or method. So the compiler flashes error.

15.10.1 Inner Classes in Methods and Scopes

In all the earlier examples, the inner class has been defined within the scope of outer class. But there are a number of other ways for defining inner classes; inner classes can be created within a method or even an arbitrary scope. For example, an inner class can be defined within the block defined by a method or even within the body of a while/for loop. This is very useful when a complicated problem is being solved and a class is to be created to aid in the solution, but one does not want it publicly available.

Consider first an example where an inner class is defined within a loop.

/*PROG 15.18 DEMO OF NESTED INNER CLASSES VER 7 */
class demo
{
   boolean flag = true;
   void show()
   {
             for (int i = 0; i < 5; i++)
             {
                    class demo1
                    {
                        demo1()
                        {
                            System.out.println("
flag = " + flag);
                        }
                    }//inner class ends
                    new demo1();
             }//for loop ends
      }//method show ends
}//outer class ends
class JPS7
{
    public static void main(String[] args)
    {
           demo d = new demo();
           d.show();
    }
}
OUTPUT:

flag = true
flag = true
flag = true
flag = true
flag = true

In this program, inner class demo1 has been defined within the scope of for loop. The inner class demo has got just one default constructor which displays the value of data member flag defined within an object of demo1 class which calls the default constructor. Note as the inner class is defined within the scope of for loop when new demo1() executes, it calls the default constructor and executes five times. This displays the value of flag five times. We could have also written the code in this manner, if instead of default constructor methods say display was used.

demo1 d = new demo1();
d1.display();

Note: Creation of a class within a local scope is known as local inner class. The scope may be created using a method, loop or any other scope.

In the next example, an inner class is defined within if conditional block, that is also within a method.

/*PROG 15.19 DEMO OF INNER CLASS VER 8 */
class demo
{
   void show(boolean b)
   {
          if (b)
          {
                      class demo1
                      {
                            String str;
                            demo1(String s)
                            {
                                   str = s;
                            }
                            String getstr()
                            {
                                   return str;
                            }
                      }//inner class ends;
                      demo1 d1 = new demo1("Inner");
                      String st = d1.getstr();
                      System.out.println("
In show str = " + st);
             }//if ends here
      }//method show ends
}//outer class ends
class JPS8
{
   public static void main(String[] args)
   {
          demo d = new demo();
          d.show(true);
   }
}
OUTPUT:

In show str = Inner

In the show method of outer class demo, an inner class demo1 has been defined. The creation of demo1 class is dependent on the boolean argument passed to the show method. If the boolean argument b is true, the inner class demo1 is created. The class has got one argument constructor which takes a String parameter. The method getstr returns the string. Just before the end of if block, an object of demo1 class is created using one argument String constructor. The string passed is returned back using the getstr method. The same is displayed in the next line. Note the class demo1 is nested inside the scope of an if statement. This does not mean that the class is conditionally created: it gets compiled along with everything else. However, it is not available outside the scope in which it is defined. Other than that, it looks just like an ordinary class.

15.10.2 Static Nested Class

A brief overview of static nested class has already been given earlier. They are not frequently employed so there is not much concentration on this topic; however, a few programs will be given. They are used where connection between the inner class object and the outer class object is not required. This is commonly called a nested class. To understand the meaning of static when applied to inner classes, it must be remembered that the object of an ordinary inner class implicitly keeps a reference to the object of the enclosing class that created it. This being the reason, in inner classes one is able to access members without objects. It was mentioned earlier that fields and methods in ordinary inner classes can only be at the outer level of a class, so ordinary inner classes cannot have static data, static fields or nested classes. However, nested classes can have all of these.

Consider the example given below:

/*PROG 15.20 DEMO OF STATIC NESTED CLASS */
class demo
{
   int num = 20;
   static class demo1
   {
      void display()
      {
         demo d = new demo();
         System.out.println("
Hello from display num: "
                               +d.num);
      }
   }//inner class ends
}//outer class ends
class JPS9
{
      public static void main(String[] args)
      {
             demo.demo1 d1 = new demo.demo1();
             d1.display();
      }
}
OUTPUT:

Hello from display num: 20

Explanation: In this program, the class demo1 is static modifier written prior to class keyword. Due to this, members of the enclosing class cannot be accessed directly inside demo1 class. An object of the demo class must be created and using that object, the members of enclosing class can be called. This is what has been done for accessing the member num of enclosing class demo.

15.10.3 Inner Classes in Event Handling

The concept of inner classes has been discussed in the previous section. In this section, it is used to show how useful they can be in event handling. Consider the program given below which is a modified form of the program shown earlier.

/*PROG 15.21 DEMO OF INNER CLASS IN EVENT HANDLING VER 1*/
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
<html>
<applet code="Inner" width =350 height = 120>

</applet>
</html>
public class Inner extends Applet
{
   public void init()
   {
          addMouseListener(new MyMouseAdapter());
   }
   class MyMouseAdapter extends MouseAdapter
   {
          public void mousePressed(MouseEvent me)
          {
                 Graphics g = getGraphics();
                 g.drawString("HELLO", me.getX(), me.getX());
          }
   }
}

images

Figure 15.12 Output screen of Program 15.21

Explanation: In this program, the class MyMouseAdapter is defined within the class Inner so it becomes inner class for Inner. Now, all the methods of Applet and Component class can be used without defining in the MyMouseAdapter class. See how easy it has become to write the event handling code using inner and adapter class.

/*PROG 15.22 DEMO OF INNER CLASS IN EVENT HANDLING VER 2 */
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
<html>
<applet code="tem1" width =350 height = 120>
</applet>
</html>
public class tem1 extends Applet
{
   public void init()
   {
          addMouseListener(new MyMouseAdapter());

}
class MyMouseAdapter extends MouseAdapter
{
       public void mousePressed(MouseEvent me)
       {
              Graphics g = getGraphics();
              switch(me.getButton())
              {
                case MouseEvent.BUTTON1:
                     g.drawString("HELLO1", me.getX(),
                                   me.getY());
                     break;
                case MouseEvent.BUTTON2:
                     g.drawString("HELLO MIDDLE",
                                   me.getX(),me.getY());
                     break;
                case MouseEvent.BUTTON3:
                     g.drawString("HELLO RIGHT",
                                   me.getX(), me.getY());
                     break;
               }
       }
   }
}

images

Figure 15.13 Output screen of Program 15.22

Explanation: This program is simple compared to the previous one, but here the types of mouse button pressed are recognized on the basis of writing string onto the current mouse coordinate.

15.10.4 Anonymouse Inner Class

Anonymous inner classes are inner classes that do not have a name. To understand this, consider the code given below:

/*PROG 15.23DEMO OF ANONYMOUSE CLASS VER 1 */
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
<html>
<applet code="AICdemo" width =350 height = 120>
</applet>
</html>
public class AICdemo extends Applet
{
   public void init()
   {
          addMouseListener(new MouseAdapter()
          {
            public void mousePressed(MouseEvent me)
            {
              Graphics g = getGraphics();
              g.drawString("HELLO", me.getX(), me.getY());
            }
          }); //anonymous inner class ends here
   }//init method ends here
}//class ends here

images

Figure 15.14 Output screen of Program 15.23

Explanation: A new anonymous class is created inside the addMouseListener method. Note the class has no name but it has body. The body of the class is shown here separately for better understanding:

{
      public void mousePressed(MouseEvent me)
      {
             Graphics g = getGraphics();
             g.drawString("Hello",me.getX(),me.getY());
      }
}

The above class is anonymous class as it is having no name but written as an expression/argument for the addMouseListener method. Note the entire class is within the parenthesis so when closing parenthesis is put, semicolon has to be written. The class is instantiated automatically when the above code executes. The important point to note here is that syntax new MouseAdapter() tells the compiler that anonymous class extends the MouseAdapter class.

/*PROG 15.24 DEMO OF ANONYMOUS CLASS VER 2 */
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
/*
<html>
<applet code="tem2" width =350 height = 120>
</applet>
</html>
*/
public class tem2 extends Applet
{
   public void init()
   {
          addMouseListener(new MouseAdapter()
          {
                public void mousePressed(MouseEvent me)
                {
                       Graphics g = getGraphics();
                       //setForeground(Color.blue);
                       g.fillOval(me.getX()-10,me.getY()-10,20,
                                   20);
                 }
          });//anonymous inner class ends here
          addKeyListener(new KeyAdapter()
          {
           public void keyPressed(KeyEvent ke)
           {
                if (ke.getKeyCode() == KeyEvent.VK_R)
                     setForeground(Color.red);
                else if (ke.getKeyCode() == KeyEvent.VK_G)
                     setForeground(Color.green);
                if (ke.getKeyCode() == KeyEvent.VK_B)
                     setForeground(Color.blue);
            }
          });//anonymous inner class ends here
   }//init method ends here
}//class ends

images

Figure 15.15 Output screen of Program 15.24

Explanation: In this program, two anonymous classes have been created. In the first anonymous inner class, the code is written to handle mouse-clicked event. On the mouseClicked event handler, the code is written to draw small filled circle of radius 10 wherever the mouse is clicked in the applet window. The circles are drawn in the default fill color black.

In the other anonymous inner class inside the addKeyListener method, the KeyAdapter class has been extended and in it written the keyPressed method. Now depending on three keys 'R', 'G' and 'B', the foreground color is changed to red, green and blue, respectively.

15.11 PONDERABLE POINTS

1.   An event is any happening or occurring.

2.   There are two main models for handling events in Java: The old model is known as Inheritance Event Model and the new one Delegation Event Model. For implementing event-handling mechanism using Delegation Event Model, the package java.awt.event must be imported.

3.   Event model is based on the concept of an "Event Source" and "Event Listener". Any object that is interested in receiving messages (or events) is called an Event Listener. Any object that generates these messages (or events) is called Event Source.

4.   In an AWT program, the vent source is typically a GUI component and the listener is commonly an "adapter" object which implements the appropriate listener (or set of listeners) in order for an application to control the flow/handling of events.

5.   The ActionEvent class is used for handling events like pressing a button, clicking a menu item or list box item. For all these events an ActionEvent is generated.

6.   The AdjustmentEvent class represents adjustment events generated by adjustable objects like a scroll bar.

7.   The class represents a low-level event which indicates that a component moved, changed size, or changed visibility. It is the root class for the other component-level events classes like KeyEvent, MouseEvent, WindowEvent, etc.

8.   The ItemEvent class represents a semantic event (occurred on some GUI object) which indicates that an item was selected or deselected.

9.   The KeyEvent class represents an event which indicates that a keystroke occurred in a component.

10. The MouseEvent class represents an event which indicates that a mouse action occurred in a component.

11. For handling Button related event, ActionListener interface must be implemented.

12. For handling ScrollBar related event, AdjustmentListener interface must be implemented.

13. For handling List, CheckBox, radio button related event, ItemListener interface must be implemented.

14. For handling keyboard related event, KeyListener interface must be implemented.

15. For handling mouse events like press, click, enter and exit on a component, MouseListener interface must be implemented.

16. For handling mouse events like mouse move and mouse dragged on a component, MouseMotionListener interface must be implemented.

17. An Adapter class is a class that provides an empty implementation of all methods in an event listener interface. Adapter classes can be used where one is interested in all of the methods of the interface except one or two.

18. It is possible to place definition within another class definition. This is called nested class.

19. A static nested class is the one that has static keyword written before class definition. A static class can access all the members of its enclosing class only through objects. It cannot access them directly. In general, static nested class is called simply nested class.

20. A non-static nested class is that class where static keyword is not present before class definition. The most important type of nested class is the inner class. It can access all the members of its enclosing class without using an object. This being the reason, it is frequently used. In general, non-static nested class is called inner class.

REVIEW QUESTIONS

1.   What is event handling? Also explain low level events and high level events.

2.   Explain the Event Class hierarchy in Java.

3.   What are processing events? Explain with an example.

4.   Explain the following terms:

(a) Mouse listeners

(b) Mouse motion listeners

(c) Key events

(d) Modifier keys

(e) Mouse button modifiers

(f) Focus events

(g) Component events

(h) Consuming event

5.   Write a program to create a calculator using event handling.

6.   What is event queue? Explain with the help of a suitable example.

7.   Write a program to demonstrate the use of ActionListener.

8.   Write a program to demonstrate the use of mouse handling events.

9.   Write a program to create a menu for a typical gas agency system.

Multiple Choice Questions

1.   For implementing event handling mechanism using Delegation Event Model, the package________ must be imported.

(a) java.Applet.event

(b) java.applet.event

(c) java.awt.event

(d) java.Awt.event

2.   Event model is based on the concept of an

(a) Applets

(b) Event source

(c) Event listeners

(d) (b) and (c)

3.   For handling list, checkbox, radio button related event,_______ must be implemented

(a) ActionListener interface

(b) ActionEvent class

(c) ItemListener interface

(d) None of the above

4.   For handling keyboard related event________ must be implemented

(a) KeyEvent interface

(b) KeyListener interface

(c) KeyStroke interface

(d) None of the above

5.   Which of the following is used to provide an empty implementation of all methods in an event listener interface?

(a) KeyEvent class

(b) Adapter object

(c) Adapter class

(d) ItemListener

6.   ________ is generated when components are added to or removed from a container.

(a) ActionEvent class

(b) AdjustmentEvent class

(c) ContainerEvent class

(d) FocusEvent class

7.   Every event is a subclass of

(a) java.applet.event

(b) java.util.EventObject

(c) java.io.Event

(d) None of the above

8.   Every source has different methods for registering the listeners. The general form is

(a) void addSTypeListener()

(b) public void addSTypeListener()

(c) public void addSType(STypeListener listener)

(d) public void addSTypeListener (STypeLis-tener listener)

9.   When a button is pressed, an action event is generated that has a command name equal to the label on the button-which of the following will be used?

(a) String getAction()

(b) public String getAction

(c) public String getActionCommand()

(d) None of the above

10. Which method returns a Point object containing the x and y coordinator relative to the source component?

(a) public int getX()

(b) public int getY()

(c) public Point getPoint()

(d) (a) and (b)

KEY FOR MULTIPLE CHOICE QUESTIONS

1.   c

2.   d

3.   c

4.   b

5.   c

6.   c

7.   b

8.   d

9.   c

10. c

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.168.211