Abstract Windows Toolkit
- What is an Event?
- Event Class
- Event Handling
- Component class
- AWT Package
- Layout Managers
- The Container, Panel, Window, and Frame Classes
- Overview of the Delegation Model
- Event Hierarchy
What is an Event? |
Windows’ Response to User Activity
Introduction
- Many Java books intermingle their discussion of events with detailed discussions of other aspects of the user interface making it difficult to filter out and understand events and event handling in their own right.
- The handling of events in Java is a significant technology issue, almost completely independent of other aspects of the user interface.
- When a computer is running under Windows, the Windows program or operating system (whichever you prefer to call it) is constantly monitoring the activities of the user. (The same is also true of other operating systems which support a Graphical User Interface).
- The user may be moving the mouse, pressing a mouse button, pressing keys on the keyboard, touching a touch-screen, etc.
- As the user performs these actions, the operating system (OS) responds by sending a stream of messages to the applications that are running.
- These messages contain information about the actions of the user to which the application might need to respond.
- In other words, if the user clicks the mouse on a button, this will result in the OS sending a message to the program.
- The Calvert book describes how to interpret these messages and cause the program to provide an appropriate response.
Where Does Java Fit In
- When we write and execute a Java application or applet, we really aren’t executing our program at the level described by Calvert.
- Rather, the Java runtime system is a program running at that level.
- For example, we could execute a Java application by entering the following command at the operating system prompt:
java MyProgram MyOptionalCommandLineArgument
- As you can see, the program that we are actually executing is a program named java. This causes the Java runtime system to begin execution.
- Our Java application is simply a command-line argument to that program.
- The first command-line argument (the name of a Java class file) is passed to the program named java.
- Additional command-line arguments (if any) are passed to the Java application.
- The Java runtime system causes our Java application to execute under its direct control.
- Similarly, when we execute an applet, there is already a program being executed which we commonly refer to an a browser. Applets execute under control of the browser.
- During the remainder of this lesson, when we refer to the Java runtime system, we will be referring to either the program executed by invoking "java" at the command line, or that portion of the browser which controls the execution of Java applets, whichever is appropriate to the discussion at hand.
- One of the beneficial results of this scheme is that it makes event programming a lot easier for the Java programmer than might otherwise be the case.
- In particular, whenever there is user activity, the OS continues to send the stream of complex messages mentioned earlier in response to that activity. However, those messages are not sent directly to our Java application or applet. Instead, they are sent to the Java runtime system which performs some significant preprocessing on our behalf.
Encapsulating User Activities into Event Objects
The primary pre-processing performed by the Java runtime system is
- to interpret and collect the information in the messages, and
- encapsulateit into objects of the Event class.
The Event class is contained in the java.awt package. This is such an important class that we are going to study it in detail, using information taken from the Java API documents from JavaSoft.
Event Class |
The Event Class
The API describes the Event class as follows:
- "Event is a platform-independent class that encapsulates user events from the local Graphical User Interface (GUI) platform."
Event Extends Object
The Event class begins with the following declaration:
public class java.awt.Event extends java.lang.Object
Thus, the Event class inherits directly from Object, which as you know, is the highest level in the Java class hierarchy.
The declaration for the Event class can be separated into the following parts:
- Fields, instance variables, data members,(or whatever you choose to call them)
- Constants for use with the id field
- Constants for use with the key field
- Constants for use with the modifiers field
- Constructors
- Methods
We will discuss each of these parts of the Event declaration separately.
Fields
The following fields or instance variables are declared in the Event class:
public Object arg;
public int clickCount;
public Event evt;
public int id;
public int key;
public int modifiers;
public Object target;
public long when;
public int x;
public int y;
An understanding of these fields will be very important for the following reason:
Again, the following information regarding the fields was taken from the Java API Documentation.
- arg : An arbitrary argument of the event. The value of this field depends on the type of event.
- clickCount: For MOUSE_DOWN events, this field indicates the number of consecutive clicks. For other events, it is zero.
- evt: The next event. This field is set when putting events into a linked list.
- id:The type of the event.
- key: The key that was pressed in a keyboard event.
- modifiers : The state of the modifier keys.
- target : The target component. This indicates the component over which the event occurred or with which the event is associated.
- when : The time stamp of the event.
- x : The x coordinate of the event.
- y : The y coordinate of the event.
Event Handling |
There are at least two ways that user activity can become associated with an object in a typical system:
- Point to an object and do something.
- Do something at the keyboard while an object has the focus.
Most of you are already familiar with these types of user activities, although you may never have stopped to analyze what you were doing.
-
The first way to associate an object with a user activity is straightforward. Typically, it involves pointing to the object with a pointing device (such as a mouse) and then signaling an action, such as pressing a button on the mouse, selecting a string in a list, selecting a menu item, etc.
- The second way to associate an object with a user activity is a little more indirect, and might require some additional explanation.
- In a GUI system, one object on the display device (and only one object) has the focus at any given time. This is usually visually obvious. The object will be of a different color, have a halo, be blinking, or something to set it apart from the remaining objects on the display.
- For example in a Windows system, when a text-entry object has the focus, it contains a blinking I-beam cursor. When it doesn’t have the focus, it does not have such a cursor.
- There are usually a variety of ways to cause an object to have the focus. Probably the most common are to click on the object with the mouse, or to use the tab key to cycle the focus through a series of objects until it reaches the desired object.
- When an object "has the focus", that is the only object that will accept keyboard input. Therefore, causing an object to have the focus is preparatory to associating keyboard activity with that object.
- Simply pointing to an object with the mouse and clicking on it is often all that is required to associate mouse activity with an object.
- Back then to our original premise, when programming in a GUI system, all meaningful user activity is associated with some object.
Component Class |
The Component class has many methods, all of which are available to objects of classes derived from Component. The particular method of interest to us right now is a method named handleEvent().
This is where we finally learn how it all fits together
- The user engages in some meaningful activity.
- The OS sends a message to the Java runtime system containing information about that activity.
- The Java runtime system encapsulates that information in an object of type Event.
And the next step is, (and this is an absolutely critical step in your understanding of how it all fits together)
- The runtime system makes a call to the handleEvent() method of the object associated with the user activity, passing the Event object as a parameter.
At that point, the handleEvent() method can do one of three things:
- Deal with the event in its entirety leaving nothing more to be done.
- Deal with the event on some sort of partial basis leaving additional work to be done.
- Not deal with the event at all.
Constructors
Our next step on the road to understanding objects of the Event class is to look at the available constructors.
There are three overloaded constructors for the Event class as shown below:
public Event(Object target, int id, Object arg);
public Event(Object target, long when, int id, int x, int y, int key, int modifiers);
public Event(Object target, long when, int id, int x, int y, int key, int modifiers, Object arg);
Methods
- That brings us to the last section in the declaration of the Event class: methods.
- The Event class provides six methods as listed below.
- Therefore, objects of the class have these instance methods in addition to methods that they inherit from the Object class.
public boolean controlDown();
public boolean metaDown();
protected String paramString();
public boolean shiftDown();
public String toString();
public void translate(int dX, int dY);
Methods for modifier Keys
Three of these methods have to do with the modifier keys
- control
- shift
- meta
but as mentioned earlier, the Alt key is not included.
If you use the Event object to invoke these methods, the boolean return value will tell you if the corresponding modifier key was being held down when the event occurred. These are convenience methods which make it possible for you to easily determine something that you can also determine using the bitwise and operation described earlier.
The paramString() Method
Here is the official word on this method, straight from the API Documentation:
"Returns the parameter string representing this event. This string is useful for debugging."
The translate() Method
The official word on this method (from the API Documentation) is:
public void translate(int dx, int dy)
Translates this event so that its x and y position are increased by dx and dy respectively.
Parameters:
dX – the amount to translate the x coordinate
dY – the amount to translate the y coordinate
This method could be useful in any number of situations involving graphics.
The toString() Method
This is a very common method that we have encountered on numerous prior occasions. When this method is invoked on an object of type Event, some information about the object will be returned as a string.
AWT Package |
- The user interface of a modern computer program involves techniques to activate many of the human senses. We use icons, text boxes, images, sound, boardroom graphics, etc.
- This and the next several lessons will concentrate on those aspects of the interface that we commonly refer to as the Graphical User Interface (GUI). We will leave other aspects of the interface, such as sound, to be covered in subsequent lessons.
- Many of the sample programs in the earlier lessons on event handling made use of simple GUI forms without providing much of an explanation as to what was going on. The next few lessons will attempt to rectify that situation by explaining many aspects of creating a Graphical User Interface.
Package java.awt Classes
- There were more than fifty classes defined in package java.awt. Of that total, we will be mainly concerned with the ones discussed in the following sections.
- The classes are grouped in the general order that we will be studying them.
- However, some groups are so large that it may be necessary to break the group up into more than one lesson.
- We will also be making heavy use of the classes in the java.awt.event package, but you are already familiar with most of those classes from your study of the previous lessons on event handling in JDK 1.1.
Layout Managers |
Arranging Components in Containers
- We can place our components in their containers using absolute position coordinates, or we can use any of several different layout managers to do the job.
- Using layout managers is considered by many to be the safer approach because this approach tends to automatically compensate for differences in screen resolution between platforms.
- The different layout managers are defined in classes having the following names:
- FlowLayout
- GridLayout
- BorderLayout
- CardLayout
- GridBagLayout
- GridBagConstraints
In addition to the layout manager classes, there is a class named GridBagConstraints that is used to work with the GridBagLayout class as well as a class named Insets that is used to work with other classes.
The Container Classes
The following hierarchy diagram shows where the container classes Panel, Window, and Frame fit into the overall inheritance hierarchy. We will discuss these three classes as a group, and also discuss their relationship with their superclasses: Container, Component, and Object.
java.lang.Object
|
+----java.awt.Component
|
+----java.awt.Container
|
+----java.awt.Panel
|
+----java.awt.Window
|
+----java.awt.Frame
Generally, these classes are used to contain components or instances of other classes.
The Non-Text Input Components
The components in the next group are generally used to allow the user to input (non-text) information to the program, although in some circumstances they could also be used to output information to the user as well. Non-text in this context means that the user can input information without the requirement to use the keys on the keyboard.
All of these classes extend the class Component.
–Button
–Checkbox
–Choice
–List
The class named CheckboxGroup does not extend Component, but extends Object instead. As the name suggests, objects of this class can be used to group Checkbox components so that they behave in a mutually exclusive fashion.
Button
A Button and a yellow Label are placed in a Frame object. Note that the specified location and size of the components may cause the two objects to overlap. This is one of the potential problems with the use of absolute coordinates. Note also that the initial height of the Frame object may clip off the bottom of the Label. Of course, problems of this sort could be avoided, on one platform at least, by careful design.
If the Frame is resized by the user, the Button and the Label remain fixed in size and position. The Frame can be resized to the point where the two components are no longer visible. Hopefully, a user would know not to do that.
Create and Size the Button Object
The following two statements
Button myButton = new Button("Button");
myButton.setBounds(new Rectangle(25,50,100,75));
it will Create a Button object with the caption “Button” and
Specify that the button is to be located at x = 25 and y = 50, measured in pixels from the upper left-hand corner of the containing object. Positive y is measured going down the screen. The reference point on the button is the upper left-hand corner of the button.
Specify that the button is to be 100 pixels wide and 75 pixels high
Create and Size the Label Object
The next interesting code fragment creates a Label component with a yellow background, again using the setBounds() method to specify its location and size. This code places the upper left-hand corner of the Label object at a coordinate position of 100 by 100 pixels, and causes its width to be 100 pixels and its height to be 75 pixels.
Label myLabel = new Label(" Name ");
myLabel.setBounds(new Rectangle(100,100,100,75));
myLabel.setBackground(Color.yellow);
The setBackground(Color c) method is also a method of the Component class that is inherited by subclasses of Component. This method requires an object of the Color class as a parameter.
Create the Frame Object
The next interesting code fragment creates a Frame object with the title ” ” Frame is the type of object that users of the Windows operating system would probably consider to be a typical “Window”. It is resizable, has a minimize button, a maximize button, a control box button, and a close button.
The default layout for a frame is BorderLayout which we will be studying later.
Frame myFrame = new Frame(" My First Window ");
myFrame.setLayout(null);
In this particular example, we don’t want to accept the default layout. Rather, we want to be able to specify the location and size of our components in absolute coordinates . Therefore, we will override the default layout with a specification of a null layout as a parameter to the setLayout() method.
The setLayout() method is a method of the Container class, of which the Frame class is a subclass. The setLayout() method requires an object of the LayoutManager class or null (indicating no layout manager) as a parameter.
Add the Components to the Frame
The next interesting code fragment causes the two previously defined components to become part of the composite visual object through use of the add() method of the class Container. This method is inherited by the Frame class which is a subclass of Container.
As of 3/6/97, there are five overloaded versions of the add() method. We are using the version that requires an object of type Component as a parameter. Since our Button and Label objects are subclasses of the Component class, they qualify as parameters allowing us to use the following code:
myFrame.add(myButton);
myFrame.add(myLabel);
Size the Frame and Make It Visible
Once we reach this point, all that is left to cause our GUI to appear on the screen at program startup is to establish the size of the Frame object in pixels, and to make it visible. We accomplish this with the following two statements:
myFrame.setSize(250,150);
myFrame.setVisible(true);
A complete listing of the program
import java.awt.*;
import java.awt.event.*;
//=======================================================//
public class Layout01 {
public static void main(String[] args){
//instantiate a Graphical User Interface object
GUI gui = new GUI();
}//end main
}//end class Layout01
//=======================================================//
//The following class is used to instantiate a graphical
// user interface object.
class GUI {
public GUI(){//constructor
//Create a Button object with the specified caption and
// the specified size and location within its container
// (in pixels).
Button myButton = new Button("Button");
//Arguments are x,y,width,height
myButton.setBounds(new Rectangle(25,50,100,75));
//Create a Label object with the specified initial text
// and the specified size and location within its
// container (in pixels). Make it yellow so that its
// outline will be visible.
Label myLabel = new Label(" Name ");
//Arguments are x,y,width,height
myLabel.setBounds(new Rectangle(100,100,100,75));
myLabel.setBackground(Color.yellow);
//Create a Frame object with the specified title, and
// with no layout manager so that size and location of
// components shown above will be effective.
Frame myFrame = new Frame(" My First Window ");
//Note the following null argument.
myFrame.setLayout(null);
//Add the two components to the Frame, set its size in
// pixels, and make it visible.
myFrame.add(myButton);
myFrame.add(myLabel);
myFrame.setSize(250,150);
myFrame.setVisible(true);
}//end constructor
}//end class GUI definition
The Container, Panel, Window, and Frame Classes |
- package java.awt where most of the functionality exists for providing the user interface to your application or applet.
- The next step is to take a look at the variety of components that are available to combine with layout and event handling to produce an effective Graphical User Interface.
- The available components are defined by classes in the package java.awt.
- The Container Classes
- The Non-Text Input Classes
- Text Input and Output Classes
- The Scrollbar Classes
- The Dialog Class
- The Canvas Class
- Menus
- Graphics – Shapes, Fonts, Images
- The PrintJob Class
- The Toolkit Class
The Container Classes
The following hierarchy diagram shows where the Container classes Panel, Window, and Frame fit into the overall inheritance hierarchy. We will discuss these three classes as a group, and also discuss their relationship with their superclasses Container, Component, and Object.
java.lang.Object
|
+----java.awt.Component
|
+----java.awt.Container
|
+----java.awt.Panel
|
+----java.awt.Window
|
+----java.awt.Frame
Generally, the Container classes are used to contain components or instances of other classes.
The Object Class
- We have discussed the Object class and the Component class in previous lessons. The Object class is a member of the java.lang package, and is the root of the class hierarchy. Every class has Object as a superclass.
- All objects, including arrays, implement the methods of the Object class. In keeping with the general concepts of inheritance in Object-Oriented Programming, the methods provided by the Object class are general-purpose in nature.
The Component Class
- The Component class extends the Object class, and is the superclass of many of the classes used to produce Graphical User Interfaces.
- Component has no public constructors so it cannot be instantiated. However, it can be extended which provides a new capability of JDK 1.1 known as Lightweight Components which will be the topic of a subsequent lesson.
The Container Class
- The Container class extends Component. As with Component, there are no public constructors for the class. Therefore, you cannot instantiate objects of the Container class. However, you can extend the class giving rise to Lightweight Components as mentioned earlier.
- As we will see, the Panel class, the Window class, and the Frame class are subclasses of Container and inherit the methods defined in Container.
- During our studies of layout managers, we saw sample programs which used the add() method of the Container class to place other components into objects subclassed from Container.
The Panel Class
- The Panel class inherits from the Container class and can be used to produce a completely generic container. The constructors are:
Panel() — Creates a new panel with a default FlowLayout manager.
Panel(LayoutManager) — Creates a new panel with the specified layout manager. - The default layout manager for a Panel object is FlowLayout. It is also possible to specify a different layout manger for the object when it is instantiated, and it is possible to accept the default initially and change it later using the setLayout() method.
The Window Class
- As shown in the earlier hierarchy diagram, the Window class extends the Container class. It is a top-level window with no borders and no menubar. The JDK documentation indicates that it could be used, for example, to implement a pop-up menu.
- The default layout for a Window object is BorderLayout. Windows are capable of generating the following window events:
WindowOpened,
WindowClosed.
The Frame Class
- Unless you just started reading these lessons at this paragraph, you will not be a stranger to the use of the Frame class.
- We particularly like to use the Frame class for sample programs because it is easy to instantiate, and equally important, it is easy to terminate.
- The Frame class extends the Window class. A Frame object is an (optionally) resizable top-level window with
–a title,
–a minimize box,
–a maximize box,
–a close box, and
–a control box.
The default layout for a Frame object is BorderLayout.
Frames are capable of generating the following types of window events:
–WindowOpened
–WindowClosing
–WindowClosed
–WindowIconified
–WindowDeiconified
–WindowActivated
–WindowDeactivated
The WindowClosing event, highlighted in the earlier program, is the event that we have used to terminate many sample programs. This event occurs whenever the user clicks the close box on the Frame object.
Also, as of that date, it had two overloaded public constructors:
–Frame() — Constructs a new Frame that is initially invisible.
–Frame(String) — Constructs a new, initially invisible Frame with the specified title.
Overview of the Delegation Model |
More Detailed Overview of the Delegation Model
- JDK 1.1 encapsulates events in a class hierarchy with the root class named java.util.EventObject.
- The propagation of an event from a Source object to a Listener object involves invoking a method on the Listener object and passing an object which contains encapsulated information about the event. Note that each event class may include more than one actual type of event.
- A Listener object is an instance of a class that implements a specific EventListener interface extended from the generic java.util.EventListener.
- An EventListener interface declares one or more methods which must be defined in the Listener class, and which are invoked by the event source in response to each specific event type handled by the interface.
- The invoking of these methods is the mechanism by which the Source notifies the Listener of the occurrence of an event of a specific type.
- An Event Source is an object which “originates” or “fires” events by invoking the methods of one or more Listener objects. The Source maintains a list containing a reference to all of the Listener objects that have registered to be notified of events of that class.
- The programmer causes Listener objects to be added to this list using add
Listener method calls. - Placing references to Listener objects on the list is often referred to as registering specific Listeners to receive notification of specific events.
- Once the list is populated (Listener objects are registered), the Source object uses that list to notify each Listener of the occurrence of an event of the specified type without further effort on the part of the programmer.
- The Event Source is often a GUI component and the Listener is commonly an object of a class which implements the appropriate listener interface, but this is not a requirement. For example we will learn later how to cause a program to generate events without any physical involvement on the part of a user and a GUI component.
- The Listener object could also be another AWT component which implements one or more Listener interfaces for the purpose of hooking GUI objects up to each other.
Event Hierarchy |
- As mentioned earlier, events in JDK 1.1 are not represented by a single Event class with numeric identifications as in JDK 1.0.2. Rather, each specific event type is a member of a class of event types and these classes form a hierarchy of event classes.
- Since a single event class may be used to represent more than one event type (i.e. MouseEvent represents mouse up, mouse down, mouse drag, mouse move, etc), some event classes may also contain an “id” (unique within that class) which maps to its specific event types.
- There are no public fields in the new event classes. Rather the data in the event is encapsulated and available only through the use of appropriate set…() and get…() methods.
- The set methods only exist for attributes on an event that can be modified by a listener. If you continue with your studies in Java, you will learn that the set and get methods match a design pattern for Java Beans.
- A concrete set of event classes is defined by the AWT. In addition, programmers may define their own event types by subclassing either java.util.EventObject or one of the AWT event classes.
- Low-level vs. Semantic Events
The AWT provides two conceptual types of events:
–low-level events
–semantic events
A low-level event is one which represents a low-level input or window-system occurrence on a visual component on the screen.
Semantic events are defined at a higher-level to encapsulate the semantics of a user interface component’s model.
Event Listeners
An EventListener interface will typically have a separate method for each distinct event type that the event class represents.
For example, the FocusEventListener interface defines two methods, focusGained() and focusLost(), one for each event type that the FocusEvent class represents.
–java.util.EventListener
–java.awt.event.ComponentListener
–java.awt.event.ContainerListener
–java.awt.event.FocusListener
–java.awt.event.KeyListener
–java.awt.event.MouseListener
–java.awt.event.MouseMotionListener
–java.awt.event.WindowListener
The semantic listener interfaces defined by the AWT are as follows:
–java.util.EventListener
–java.awt.event.ActionListener
–java.awt.event.AdjustmentListener
–java.awt.event.ItemListener
–java.awt.event.TextListener
There is a one-to-one correspondence between semantic listener interfaces and semantic event classes.
Event Sources
- All AWT event sources support a multicast model for listeners.
- This means that multiple listeners can be added and removed from a single source.
- In other words, notification of the occurrence of the same event can be sent to one or more listener objects.
Adapters
- Many EventListener interfaces are designed to listen to multiple event classes. For example, . the MouseListener listens to mouse-down, mouse-up, mouse-enter, etc. The interface declares a method for each of these subtypes.
- When you implement an interface, you are required to define all of the methods that are declared in the interface, even if you define them with empty methods. In some cases, the requirement to define all the methods declared in an interface can be burdensome.
- For this reason (and possibly for some other reasons as well), the AWT provides a set of abstract adapter classes which match up with the defined interfaces. Each adapter class implements one interface and defines all of the methods declared by that interface as empty methods, thus satisfying the requirement to define all of the methods.
- You can then define your listener classes by extending the adapter classes instead of implementing the listener interfaces.. This allows you the freedom to override only those methods of the interface which interest you.
–java.awt.event.ComponentAdapter
–java.awt.event.FocusAdapter
–java.awt.event.KeyAdapter
–java.awt.event.MouseAdapter
–java.awt.event.MouseMotionAdapter
–java.awt.event.WindowAdapter
Filtering for Performance
- Since listeners are registered to handle specific event types, they are notified only of the occurrence of those event types and are not required to deal with event types for which they are not registered.
- That was not the case in JDK 1.0.2 where all events passed through a common set of event handler code whether those events were of interest or not.
- This filtering of events should improve performance, especially with high frequency events, such as mouse-moves.
Recent Comments