This lesson takes another look at that topic through the use of programs which apply both low-level event handling and semantic event handling to the same set of visual components. This makes it possible to compare the two types of events in a more meaningful way.
The primary difference appears to reside in the nature of the event object that is passed to the event handler when an event occurs.
Using the information in the event object, low-level events can gain access to the specific Component object that generated the event.
Given a low-level event object, the getComponent() method of the java.awt.event.ComponentEvent class will return a reference to the actual object that generated the event.
Once that reference is available, there are literally dozens of methods of the Component class that can be invoked on the object, such as getLocation(), getLocationOnScreen(), getMaximumSize(), getMinimumSize(), getName(), etc.
A sample program in a previous lesson invoked the getName() method on such an object to determine which object among several objects generated a low-level mouse event.
A sample program that we will see later in this lesson invokes some of the other available methods on such a component object.
All low-level event classes are subclasses of the java.awt.event.ComponentEvent class, so the event handlers for all low-level events have access to the object that generated the event.
Semantic events, on the other hand, do not subclass the ComponentEvent class. Rather, they subclass the superclass of ComponentEvent making them siblings of ComponentEvent.
Because they do not subclass ComponentEvent, the event objects passed into semantic event handlers do not provide a way to obtain a reference to the object that generated the event, and therefore cannot invoke the methods of the Component class on that object.
Whether this is important or not depends on your needs.
For example, if you needed to determine the location of the object that generated an event, you could determine that location by processing a low-level event but you (probably) could not determine that location by processing a semantic event (never say never unless you want some programming genius to prove you wrong).
Regardless of the ability to access the object that generated the event, the name of that object is readily available to the event handlers of both low-level and semantic events.
In both cases, the name of the object is encapsulated in the event object passed as a parameter and can be extracted or tested using methods of the String class. Often knowing the name of the object is sufficient to accomplish the desired result.
A Button object and a TextField object are placed at the top and bottom of a Frame object.
A MouseListener object is instantiated and registered to monitor for low-level mousePressed() events on all three objects.
Whenever a mousePressed() event occurs, the Listener object obtains and displays several pieces of information about the object that generated the event.
Although this demonstration program only obtains and displays information as a result of mousePressed() events, all of the methods of the Component class are available for use at that point. Thus the code in the event handler method could also modify some of the attributes of the object that generated the event.
Finally, a WindowListener object is instantiated and registered to terminate the program when the user closes the Frame object.
Additional information about the program is contained in the comments.
/*File Event13.java Copyright 1997, R.G.Baldwin
Revised 03/09/98 to make it fit the page better.
This program is designed to be compiled and run
under JDK 1.1
The program demonstrates the object-manipulation capability
of low-level events.
A Button object and a TextField object are placed in a
Frame object.
A MouseListener object is instantiated and registered to
monitor for low-level mousePressed() events on all three
objects. Whenever a mousePressed() event occurs, the
Listener object obtains and displays several pieces of
information about the object that generated the event.
Although this demonstration program only obtains and
displays information as a result of mousePressed() events,
all of the methods of the Component class are available for
use at that point. Thus the code in the event handler
method could also modify some of the attributes of the
object that generated the event.
Finally, a WindowListener object is instantiated and
registered to terminate the program when the user closes
the Frame object.
Starting the program and then clicking successively on the
Button, the TextField, and the interior of the Frame
produces the following output.
Name = Button1
Parent's name = Frame
Location = java.awt.Point[x=4,y=23]
Minimum Size = java.awt.Dimension[width=54,height=21]
Size = java.awt.Dimension[width=192,height=21]
Name = TextField1
Parent's name = Frame
Location = java.awt.Point[x=4,y=275]
Minimum Size = java.awt.Dimension[width=104,height=21]
Size = java.awt.Dimension[width=192,height=21]
Name = Frame
No parent name available at this level
Location = java.awt.Point[x=0,y=0]
Minimum Size = java.awt.Dimension[width=112,height=69]
Size = java.awt.Dimension[width=200,height=300]
These results were produced using JDK 1.1.3, under Win95.
**********************************************************/
import java.awt.*;
import java.awt.event.*;
public class Event13 {
public static void main(String[] args){
//instantiate a Graphical User Interface object
GUI gui = new GUI();
}//end main
}//end class Event13
//=======================================================//
class GUI {
public GUI(){//constructor
//Create a visual TextField object
TextField myTextField = new TextField("Initial String");
myTextField.setName("TextField1");
//Create a visual Button object
Button myButton = new Button("Click me");
myButton.setName("Button1");
//Create a visual Frame object
Frame myFrame = new Frame();
myFrame.setSize(200,300);
myFrame.setTitle("Copyright 1997, R.G.Baldwin");
myFrame.setName("Frame");
//Add the Button and the TextField to the Frame object
myFrame.add("North",myButton);
myFrame.add("South",myTextField);
myFrame.setVisible(true);
//Instantiate and register a MouseListener object which
// will process mouse events on the Frame object, the
// Button object, and the TextField object.
MouseProc mouseProcCmd = new MouseProc();
myFrame.addMouseListener(mouseProcCmd);
myTextField.addMouseListener(mouseProcCmd);
myButton.addMouseListener(mouseProcCmd);
//Instantiate and register a Listener object which will
// terminate the program when the user closes the
// Frame object
WProc1 winProcCmd1 = new WProc1();
myFrame.addWindowListener(winProcCmd1);
}//end constructor
}//end class GUI definition
//=======================================================//
//Low-level event monitor.
// This listener class monitors for low-level
// mousePressed() events. Whenever a mousePressed() event
// occurs, the event handler obtains and displays several
// pieces of information about the object that generated
// the event.
class MouseProc extends MouseAdapter{
public void mousePressed(MouseEvent e){
System.out.println(
"Name = " + e.getComponent().getName());
try{
System.out.println("Parent's name = " +
e.getComponent().getParent().getName());
}catch(NullPointerException exception){
System.out.println(
"No parent name available at this level");
}//end try/catch
System.out.println("Location = " +
e.getComponent().getLocation().toString());
System.out.println("Minimum Size = " +
e.getComponent().getMinimumSize().toString());
System.out.println("Size = " +
e.getComponent().getSize().toString());
System.out.println();//blank line
}//end mousePressed()
}//end class MouseProc
//=======================================================//
//The following listener class is used to terminate the
// program when the user closes the Frame object.
class WProc1 extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}//end windowClosing()
}//end class WProc1
//=======================================================// |
As before, a Button object and a TextField object are placed at the top and bottom respectively of a Frame object.
Semantic event handling is provided for Action events. Low-level event handling is provided on the same components for mousePressed() events and Focus events. (Note that prior to 3/2/97, this section erroneously referred to Focus events as Semantic events.)
There are also some issues involving temporary and permanent changes in focus which aren't discussed here, but can be found in the JDK 1.1 documentation.
On the basis of the above description, you should see that there are many different types of components that can generate a focus event. Any component that can gain the focus can generate such an event.
There are some components such as Button objects and TextField objects that automatically gain the focus when they are clicked on by the mouse. There are other components such as Label objects that do not automatically gain the focus when they are clicked on by the mouse. However, even these components can gain the focus by requesting it. We will investigate this in more detail in a subsequent lesson.
For example, if a button is labeled Exit and it is clicked by the user, that means that the user is expecting an action that can be interpreted as Exit in that context.
When an actionPerformed() event is generated, certain information regarding the event is encapsulated into an object that is passed to the actionPerformed() method of the Listener object. This information includes what the JDK 1.1 documentation refers to as a command name. This information can be accessed by the code in the method by invoking the getActionCommand() method on the object. In this program, the command name is accessed and displayed on the screen.
As it turns out, the "command name" associated with a Button is simply the text, caption, or label on the button (whatever you choose to call it). The "command name" associated with a TextField is the current text content of the TextField object.
This information would have different uses for different components in different situations. For example, it might be used to distinguish among several buttons if the captions on the buttons were not allowed to change during the execution of the program. It might be used to extract user input from a TextField object.
The object of type ActionEvent passed to the actionPerformed() method also includes the name of the component which can be used in a conditional test to identify the component that generated the event. One way to do this is through use of the the indexOf() method of the String class to determine if a given component name is included in a specific object.
In this program, each time the actionPerformed() method is invoked, code in the body of the method uses the indexOf() method to identify the component that generated the event and displays a message identifying that component.
Whenever a focusGained() event occurs, a message is displayed identifying the object which gained the focus.
Likewise, whenever a focusLost() event occurs, a message is displayed identifying the object that lost the focus.
The object that gained or lost the focus is identified by performing conditional tests on the FocusEvent object passed in as a parameter in the same manner that the ActionEvent object is used for action events.
The MouseListener object differentiates among the three objects (Frame, Button, and TextField) on the basis of the component name assigned to each object when it is instantiated.
At this point, it would probably be worthwhile to point out that JDK 1.1 Beta 3 does not require the programmer to assign unique names to components when they are instantiated. Assigned component names can be duplicated among components. (I wonder if this is a bug? Other products such as Visual Basic and Delphi prohibit the programmer from assigning duplicate names to components.)
If the programmer does not assign names to the components when they are instantiated, they are automatically assigned by the system, and are probably unique. The names which are automatically assigned have the format frame0, frame1, frame2, etc., with the main body of the name identifying the type of component, and the digit at the end being assigned in the order in which the components are instantiated. A clever programmer should be able to find a way to obtain and make use of those names as an alternative to assigning her own names.
The approach used to obtain the component name in this program uses the indexOf() method of the String class on the MouseEvent object. (This is a slightly less complex approach than the approach used to obtain the component name for a mousePressed() event in an earlier lesson which went all the way back to the component object and invoked the getName() method.)
When a mousePressed() event occurs on any of the three visual objects, the MouseListener object displays a message identifying the object that generated the event.
In order to maintain simplicity, the response to events in this program is limited to simply displaying information. Obviously, once control is within an event handler, significant behavior in response to an event can be programmed.
This program also illustrates the fact that a single user action can cause many different types of events to be generated.
One thing to notice in particular is that since this program was not designed to manipulate the objects that generated the low-level events, there is very little difference in the handling of low-level events and semantic events. However, the handling would have been significantly different if the capability to manipulate the objects that generated the events had been exercised (as in the previous program).
/*File Event12.java Copyright 1997, R.G.Baldwin
Revised 03/09/98 to fit the page better.
This program is designed to be compiled and run
under JDK 1.1
The program supports experimentation with low-level events
and semantic events.
A Button object and a TextField object are placed in a
Frame object.
An ActionListener object is instantiated and registered to
monitor for semantic actionPerformed() events on the Button
and the TextField.
An actionPerformed() event can be generated on a TextField
by pressing the Enter key while the TextField object has
the focus.
An actionPerformed() event can be generated by a Button by
clicking on it with the mouse.
An action event cannot be generated by a Frame object.
Whenever an actionPerformed() event occurs, the Listener
object invokes the getActionCommand() method on the object
to obtain the "command name".
The getActionCommand() method returns the "command name"
associated with the action as a String. The string is
displayed. As it turns out, the "command name" associated
with a Button is simply the text, caption, or label on the
button. The "command name" associated with a TextField is
the current text content of the TextField object.
The ActionEvent object passed to the actionPerformed()
method includes the name of the component which can be
used in a conditional test based on the indexOf() method
of the String class to identify the component that
generated the event.
Each time the actionPerformed() method is invoked, code in
the body of the method uses the indexOf() method to
identify the component that generated the event and
displays a message identifying that component.
A FocusListener object is instantiated and registered to
monitor for low-level focusGained() and focusLost() events
on the Button and the TextField.
Whenever a focusGained() event occurs, a message is
displayed identifying the object which gained the focus.
Likewise, whenever a focusLost() event occurs, a message is
displayed identifying the object which lost the focus. The
object that gained or lost focus is identified by
performing conditional tests on the FocusEvent object
passed in as a parameter.
A MouseListener object is instantiated and registered to
monitor for low-level mousePressed() events on all three
objects. The Listener object differentiates among the
three on the basis of the component name assigned to each
object. The approach used to obtain the component name in
this program uses the indexOf() method of the String class
on the MouseEvent object. This is a somewhat less complex
approach than the approach used to obtain the component
name for a mousePressed() event in an earlier lesson. When
a mousePressed() event occurs on any of the three visual
objects, the Listener object displays a message identifying
the object that generated the event.
Finally, a WindowListener object is instantiated and
registered to terminate the program when the user closes
the Frame object.
Typical outputs from the program follow:
Clicking the mouse inside the frame but outside of both the
TextField and the Button produces the following output:
Got mousePressed event from Frame object
Clicking the mouse on the TextField when the Button has the
focus produces the following output:
Got mousePressed event from TextField1 object
Got focusLost event from Button1 object
Got focusGained event from TextField1 object
Pressing the Enter key when the TextField has the focus
produces the following output:
e.getActionCommand() = Initial String
Got actionPerformed event from TextField1 object
Clicking the mouse on the Button when the TextField has the
focus produces the following output:
Got mousePressed event from Button1 object
Got focusLost event from TextField1 object
Got focusGained event from Button1 object
e.getActionCommand() = Click me
Got actionPerformed event from Button1 object
These results were produced using JDK 1.1.3 under Win95.
**********************************************************/
import java.awt.*;
import java.awt.event.*;
public class Event12 {
public static void main(String[] args){
//instantiate a Graphical User Interface object
GUI gui = new GUI();
}//end main
}//end class Event12
//=======================================================//
//The following class is used to instantiate a graphical
// user interface object.
class GUI {
public GUI(){//constructor
//Create a visual TextField object
TextField myTextField =
new TextField("Initial String");
myTextField.setName("TextField1");
//Create a visual Button object
Button myButton = new Button("Click me");
myButton.setName("Button1");
//Create a visual Frame object and name it Frame
Frame myFrame = new Frame();
myFrame.setSize(200,300);
myFrame.setTitle("Copyright 1997, R.G.Baldwin");
myFrame.setName("Frame");
//Add the Button and the TextField to the Frame object
myFrame.add("North",myButton);
myFrame.add("South",myTextField);
myFrame.setVisible(true);
//Instantiate and register an ActionListener object
// which will monitor for action events on the
// TextField and the Button.
ActionProc actionProcCmd = new ActionProc();
myTextField.addActionListener(actionProcCmd);
myButton.addActionListener(actionProcCmd);
//Instantiate and register a FocusListener object which
// will monitor for focus events on the TextField and
// the Button.
FocusProc focusProcCmd = new FocusProc();
myTextField.addFocusListener(focusProcCmd);
myButton.addFocusListener(focusProcCmd);
//Instantiate and register a MouseListener object which
// will process mouse events on the Frame object, the
// Button object, or the TextField object.
MouseProc mouseProcCmd = new MouseProc();
myFrame.addMouseListener(mouseProcCmd);
myTextField.addMouseListener(mouseProcCmd);
myButton.addMouseListener(mouseProcCmd);
//Instantiate and register a Listener object which will
// terminate the program when the user closes the Frame
// object
WProc1 winProcCmd1 = new WProc1();
myFrame.addWindowListener(winProcCmd1);
}//end constructor
}//end class GUI definition
//=======================================================//
//Semantic event monitor.
// This ActionListener class is used to instantiate a
// Listener object that monitors for action events on the
// TextField and the Button. Whenever an actionPerformed()
// event occurs, it displays the ActionCommand and the
// identification of the component that generated the
// event. The listener object distinguishes between the
// components on the basis of their component names which
// are embedded in the object passed in as a parameter
// when an event occurs.
class ActionProc implements ActionListener{
public void actionPerformed(ActionEvent e){
System.out.println("e.getActionCommand() = " +
e.getActionCommand());
if( e.toString().indexOf("on TextField1") != -1 ){
System.out.println(
"Got actionPerformed event from TextField1 object");
}//end if
if( e.toString().indexOf("on Button1") != -1 ){
System.out.println(
"Got actionPerformed event from Button1 object");
}//end if
}//end actionPerformed()
}//end class ActionProc
//=======================================================//
//Semantic event monitor.
// This FocusListener class is used to instantiate a
// Listener object that monitors for focus events on the
// TextField and the Button. Whenever a focusLost() or
// focusGained() event occurs, it displays the
// identification of the component that generated the
// event. The listener object distinguishes between the
// components on the basis of their component names which
// are embedded in the object passed in as a parameter when
// an event occurs.
class FocusProc implements FocusListener{
public void focusGained(FocusEvent e){
if( e.toString().indexOf("on TextField1") != -1 ){
System.out.println(
"Got focusGained event from TextField1 object");
}//end if
if( e.toString().indexOf("on Button1") != -1 ){
System.out.println(
"Got focusGained event from Button1 object");
}//end if
}//end focusGained()
public void focusLost(FocusEvent e){
if( e.toString().indexOf("on TextField1") != -1 ){
System.out.println(
"Got focusLost event from TextField1 object");
}//end if
if( e.toString().indexOf("on Button1") != -1 ){
System.out.println(
"Got focusLost event from Button1 object");
}//end if
}//end focusLost()
}//end class FocusProc
//=======================================================//
//Low-level event monitor.
// This listener class monitors for mouse presses and
// displays a message when a mousePressed() event occurs on
// the Frame object, the Button object, or the TextField
// object. The message identifies the component that
// generated the event. The listener object distinguishes
// between the components on the basis of their component
// names which are embedded in the object passed in as a
// parameter when an event occurs.
class MouseProc extends MouseAdapter{
public void mousePressed(MouseEvent e){
if( e.toString().indexOf("on Frame") != -1 ){
System.out.println(
"Got mousePressed event from Frame object");
}//end if
if( e.toString().indexOf("on TextField1") != -1 ){
System.out.println(
"Got mousePressed event from TextField1 object");
}//end if
if( e.toString().indexOf("on Button1") != -1 ){
System.out.println(
"Got mousePressed event from Button1 object");
}//end if
}//end mousePressed()
}//end class MouseProc
//=======================================================//
//The following listener is used to display a message and
// terminate the program when the user closes the Frame
// object.
class WProc1 extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}//end windowClosing()
}//end class WProc1
//=======================================================// |
When you click on the TextField object, it disappears. When you click on the Button object, the TextField object reappears.
Use only low-level events.
When you click on the close button in the upper right-hand corner of the Frame object, the program terminates and control is properly returned to the operating system.
A - See program below.
/*From lesson 84 Copyright 1997, R.G.Baldwin Without viewing the following solution, write a Java application that originally displays a Frame object containing a button at the top and a TextField object at the bottom. Cause the TextField to have red letters on a yellow background. When you click on the TextField object, it disappears. When you click on the Button object, the TextField object reappears. Use only low level events.
When you click on the close button in the upper right-hand
corner of the Frame object, the program terminates and
control is properly returned to the operating system.
//=========================================================
*/
import java.awt.*;
import java.awt.event.*;
public class SampProg200 {
public static void main(String[] args){
GUI gui = new GUI();
}//end main
}//end class SampProg200
//=========================================================
class GUI {
public GUI(){//constructor
//Create a visual TextField object
TextField myTextField = new TextField("Initial String");
myTextField.setName("TextField1");
myTextField.setBackground(Color.yellow);
myTextField.setForeground(Color.red);
//Create a visual Button object
Button myButton = new Button("Click me");
myButton.setName("Button1");
//Create a visual Frame object
Frame myFrame = new Frame();
myFrame.setSize(300,100);
myFrame.setTitle("Copyright 1997, R.G.Baldwin");
//Add the Button and the TextField to the Frame object
myFrame.add("North",myButton);
myFrame.add("South",myTextField);
myFrame.setVisible(true);
//Instantiate and register a MouseListener object which
// will process mouse events on the Button object, and
// the TextField object.
MouseProc mouseProcCmd = new MouseProc(
myButton,myTextField);
myTextField.addMouseListener(mouseProcCmd);
myButton.addMouseListener(mouseProcCmd);
//Instantiate and register a Listener object which will
// terminate the program when the user closes the
// Frame object
myFrame.addWindowListener(new WProc1());
}//end constructor
}//end class GUI definition
//=========================================================
//Low-level event monitor.
// This listener class monitors for low-level mousePressed()
// events. Whenever a mousePressed() event occurs, the
// event handler determines which object was the source of
// the event and takes the appropriate action.
class MouseProc extends MouseAdapter{
Button refToButton = null;
TextField refToTextField = null;
String refToButtonName = null;
String refToTextFieldName = null;
public MouseProc(//constructor
Button inRefToButton, TextField inRefToTextField){
refToButton = inRefToButton;
refToTextField = inRefToTextField;
refToButtonName = inRefToButton.getName();
refToTextFieldName = inRefToTextField.getName();
}//end constructor
public void mousePressed(MouseEvent e){
if(e.getComponent().getName().compareTo(
refToTextFieldName) == 0)
refToTextField.setVisible(false);
if(e.getComponent().getName().compareTo(
refToButtonName) == 0)
refToTextField.setVisible(true);
}//end mousePressed()
}//end class MouseProc
//========================================================
//The following listener class is used to terminate the
// program when the user closes the Frame object.
class WProc1 extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}//end windowClosing()
}//end class WProc1
//======================================================== |
Q - Write a Java application that originally displays a Frame object containing a Button object at the top and a TextField object at the bottom. Cause the TextField to have red letters on a yellow background.
When you click on the TextField object, it disappears. When you click on the Button object, the TextField object reappears.
Use a mixture of low-level and semantic events.
When you click on the close button in the upper right-hand corner of the Frame object, the program terminates and control is properly returned to the operating system.
A - See program below.
/*From lesson 84
Copyright 1997, R.G.Baldwin
*/
import java.awt.*;
import java.awt.event.*;
public class SampProg201 {
public static void main(String[] args){
GUI gui = new GUI();
}//end main
}//end class SampProg201
//=========================================================
class GUI {
public GUI(){//constructor
//Create a visual TextField object
TextField myTxtField = new TextField("Initial String");
myTxtField.setBackground(Color.yellow);
myTxtField.setForeground(Color.red);
//Create a visual Button object
Button myButton = new Button("Click me");
//Create a visual Frame object
Frame myFrame = new Frame();
myFrame.setSize(300,100);
myFrame.setTitle("Copyright 1997, R.G.Baldwin");
//Add the Button and the TextField to the Frame object
myFrame.add("North",myButton);
myFrame.add("South",myTxtField);
myFrame.setVisible(true);
//Instantiate and register a MouseListener object which
// will process mouse events on the TextField object.
myTxtField.addMouseListener(new MouseProc(myTxtField));
//Instantiate and register an ActionListener object
// which will process action events on the Button
// object.
myButton.addActionListener(
new MyActionProcessor(myTxtField));
//Instantiate and register a Listener object which will
// terminate the program when the user closes the
// Frame object
myFrame.addWindowListener(new WProc1());
}//end constructor
}//end class GUI definition
//=========================================================
//Low-level event monitor.
// This listener class monitors for low-level
// mousePressed() events.
class MouseProc extends MouseAdapter{
TextField refToTextField = null;
public MouseProc(TextField inRefToTextField){
refToTextField = inRefToTextField;
}//end constructor
public void mousePressed(MouseEvent e){
refToTextField.setVisible(false);
}//end mousePressed()
}//end class MouseProc
//=========================================================
//Semantic event monitor.
// This listener class monitors for semantic action events.
class MyActionProcessor implements ActionListener{
TextField refToTextField = null;
MyActionProcessor(TextField inRefToTextField){//construct
refToTextField = inRefToTextField;
}//end constructor
public void actionPerformed(ActionEvent e){
refToTextField.setVisible(true);
}//end overridden actionPerformed method
}//end class MyActionProcessor
//=========================================================
//The following listener class is used to terminate the
// program when the user closes the Frame object.
class WProc1 extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}//end windowClosing()
}//end class WProc1
//========================================================= |