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 //========================================================= |