An event is a special nonvisible object that represents an occurrence or signal. This indicates that something happened during the interaction between the user and the executing program. Usually, the most important events are the ones originated by some user action.
Examples of user actions that originate events are the click of the mouse, starting of mouse movement, a keystroke on the keyboard, and so on.
Note | Each of these actions generates a specific type of event. A program that is dependent on events while it executes is called event-driven, because the behavior of the program depends on the events generated by user actions. |
A listener is an object that waits for a specific event to occur and that responds to the event in some manner. Each listener has a relationship with an event or with a group of similar events. Listener objects must be carefully designed to respond to its type of events.
Buttons and text fields are examples of graphical components that generate events as a result of user actions. The listener object will respond when the user clicks on the button. The behavior of the listener object should be defined in a class. For a button, in addition to declaring and creating the button as an object of class JButton, the declaration and creation of the listener object is also required.
When a user clicks a button, the type of event generated by the button is called an action event. Figure 14.5 illustrates the relationship among the button object, the action event, and the listener object. Creating the action event and invoking the appropriate function of the listener object to handle the event is done automatically.
Figure 14.5: Generation and handling of an action event.
The action event generated by the button is sent to a corresponding listener object that responds to the event. For this, the listener object must be set to respond to an event generated by the button object—this is known as registering the listener object with the button object. The sequence of steps to set up a button is:
Define the class that implements the behavior of the listener object.
Declare the button object variable.
Declare the listener object for the button.
Create the button object with a title.
Create the listener object that will respond to the action event generated by the button.
Register the listener object for the button.
Add the button object to the container.
The AWT and Swing packages provide several classes and interfaces for defining listener objects. For action events, the interface ActionListener must be implemented by the class that defines the behavior of the listener object.
Figure 14.6 shows the UML collaboration diagram for an object of class JButton and a listener object of class Bquithandler (defined in this next section). The button object generates an action event that it sends to the listener object by invoking method actionPerformed. The interaction among these objects occurs automatically (behind the scenes).
Figure 14.6: The UML collaboration diagram for a button and listener objects.
As mentioned earlier, a button is an object of class JButton. The following statements declare an object variable of class JButton.
object mybutton of class JButton
The button object is created with a title. The following statement creates the button object with the title "Push to Quit."
create mybutton of class JButton using "Push to Quit"
The next two steps declare a listener object and create this object, which will respond when the user clicks the button. The actual behavior of the listener object is defined in a class that has to be defined by the programmer. The following statements declare and create the listener object of class Bquithandler.
object butthandler of class Bquithandler ... create butthandler of class Bquithandler
After the button object and its corresponding listener object are created, the listener object has to be registered as the listener to the button object. Recall that a button generates an action event when pressed, which is handled by action listeners. The following statement invokes function addActionListener of the button to register its listener object, butthandler. Function addActionListener is defined in class JButton.
call addActionListener of mybutton using butthandler
The button can now be added to the content pane of the window. The following statement adds the button defined previously to the content pane with the south position. The content pane uses the border layout manager in this example.
call add of cpane using mybutton, BorderLayout.SOUTH
The following class, Kjplogbutton, completely implements a window with three graphical components: a text label, a label with an icon, and a button. An object listener is defined for the button. The listener object terminates the program when the user clicks the button.
On the CD | The KJP code that implements class Kjplogbutton is stored in the file Kjplogbutton.kpl, and the Java implementation is stored in the file Kjplogbutton.java. |
import all javax.swing // Library for graphics import all java.awt // description This class creates and displays a frame window with a text label, an image, and a button. */ class Fpsimbutton is public description This is the main function of the application. */ function main is constants integer WIDTH = 400 integer HEIGHT = 300 objects object frame_obj of class JFrame // window // content pane object cpane of class Container object blabel1 of class JLabel // label object psimlabel of class JLabel // for image object psimimage of class ImageIcon // image object quitbutt of class JButton // layout manager object lmanager of class BorderLayout object butthandler of class Bquithandler begin create frame_obj of class JFrame using "Psim" create blabel1 of class JLabel using "The 00 Simulation Package" create quitbutt of class JButton using "Quit" create psimimage of class ImageIcon using "psim.gif" create psimlabel of class JLabel using psimimage create lmanager of class BorderLayout create butthandler of class Bquithandler set cpane = call getContentPane of frame_obj call setLayout of cpane using lmanager // register the listener object with the // button object call addActionListener of quitbutt using butthandler // add the text image label and text label // components to the content pane of // the window call add of cpane using psimlabel, BorderLayout.CENTER call add of cpane using blabel1, BorderLayout.NORTH call add of cpane using quitbutt, BorderLayout.SOUTH call setSize of frame_obj using WIDTH, HEIGHT call setVisible of frame_obj using true endfun main endclass Fpsimbutton
For every type of event object, there is a type of listener object. Therefore, the class definition that implements the behavior of listener objects depends on the type of events that these objects can handle (or respond to). For action events, the class definition must implement interface ActionListener, which is included in package AWT. The only method specified in the interface is actionPerformed, and it has to be completely implemented in the class defined for action listener objects.
The following class, Bquithandler, defines the behavior of the object listener for the button used in class Kjplogbutton.
import all javax.swing // Library for graphics import all java.awt.event description This class defines the behavior of listener objects for the button. When the user clicks the button, the program terminates. */ class Bquithandler implements ActionListener is public description The only function in the class. */ function actionPerformed parameters object myev of class ActionEvent is begin call System.exit using 0 endfun actionPerformed endclass Bquithandler
On the CD | The KJP code that implements class Bquithandler is stored in the file Bquithandler.kpl, and the Java implementation is stored in the file Bquithandler.java. |
Figure 14.7 shows the window that appears on the screen when the program, which consists of the two classes defined previously, executes. When the user clicks the button, the program terminates.
Figure 14.7: A frame with two labels and a button.
A text field is a very useful component for entering data to an application. This component can also display data. When used for input, this component can generate an action event and send it to an action listener. This implies that an action listener object must be created and registered to the text field object.
When a user enters data in a text field and presses the Enter key, the text field object generates an action event and sends it to an action listener object. The text field is an object of class JTextField, which can be created with a given size and default text.
The following two statements declare an object reference and create the corresponding object of class JTextField of size 20 characters.
object text1 of class JTextField . . . create text1 of class JTextField using 20
To register a listener object with a text field is similar to registering a listener object to a button. The following statements declare and create a listener object, register an action event listener object with the text field object text1, and include the text field in the content pane.
object tfieldlistener of class Tlistener create tfieldlistener of class Tlistener . . . call addActionListener of text1 using tfieldlistener call add of cpane using text1
All data is entered and displayed as strings, so proper conversion needs to be carried out for entering and displaying numerical data. To get string data entered by a user into a text field, method getText of the text field object is used. To display string data in a text field, the method setText is used with the string as the argument. The following statement gets the string data entered by the user in the text field text1, and assigns the string value to variable ss.
string ss . . . set ss = call getText of text1
In a similar manner, the following statement displays string yy on the text field object text1.
string yy . . . call setText of text1 using yy
To convert the string value entered in a text field to numeric of type double, method Double.parseDouble is used with the string value as the argument. This is actually a static method parseDouble in class Double, which is a Java library class. The following statement converts the string ss to a numeric (of type double) variable dd.
double dd . . . set dd = call Double.parseDouble using ss
To display numeric data (of type double) to a text field, it must first be converted to a string value. Method String.valueOf (static method valueOf of class String) must be invoked with the numeric value as the argument. The following statement converts variable dd of type double to a string and assigns it to string variable ss.
set ss = call String.valueOf using dd
For non-integer numeric output, formatting the value to be shown is important; otherwise, too many decimal digits will appear and be shown to the user. The outcome of using a decimal formatter is a string that represents the number in one of several formats. The following statements declare an object variable of class DecimalFormat (a Java library class), create the formatter object using a formatting pattern, and invoke function format of the formatter object using the numeric value to format.
object myformat of class DecimalFormat ... // object for formatting output numeric data create myformat of class DecimalFormat using "###,###.##" ... set form_increase = call format of myformat using dincrease set form_salary = call format of myformat using dsalary
In this example, the two numeric variables of type double: dincrease and dsalary, are formatted with the same pattern, which allows only two decimal digits (after the decimal point). The resulting numeric value is normally rounded to the specified decimal digits.
Note | Formatting includes an implied conversion of the noninteger numeric value to a string. This string data can be shown in a text field in the relevant container. |
This section presents a slightly different version of the solution to the salary problem presented in Chapter 4, Section 4.11.2. The problem presented here includes a GUI for I/O of data when a user interacts with the program.
The window that appears on the screen shows the user the labels to guide the user, indicating what data he needs to input. The text fields are used for data the user enters, such as the name of the person, the age, and the salary. The window also includes two buttons, one for calculating the salary increase and the other for exiting the program.
All these components are arranged on the frame with a grid layout manager. The arrangement is a grid of rows and columns, and the components are of the same size. In this problem, the content pane is divided into five rows and two columns. The following statements declare an object variable for a grid layout manager, create the object with five rows and two columns, and set the content pane of the window with the layout manager.
// layout manager object gridmanager of class GridLayout ... create gridmanager of class GridLayout using 5, 2 ... call setLayout of cpane using gridmanager
The main class of the problem is called Csalarygui. This class implements the window and sets all the components on it. The KJP code that implements this class follows.
import all javax.swing // Library for graphics import all java.awt description This program computes the salary increase for an employee. If his/her salary is greater than $45,000, the salary increase is 4.5%; otherwise, the salary increase is 5%. The program uses the following components: buttons, labels, and text fields. */ class Csalarygui is public description This is the main function of the application. */ function main is constants integer WIDTH = 400 integer HEIGHT = 300 objects object sal_frame of class JFrame object cpane of class Container object namelabel of class JLabel object salarylabel of class JLabel object agelabel of class JLabel object increaselabel of class JLabel object nametfield of class JTextField object agetfield of class JTextField object inctfield of class JTextField object salarytfield of class JTextField // layout manager object gridmanager of class GridLayout object incbutt of class JButton object quitbutt of class JButton object actlistener of class Sal_listener begin create sal_frame of class JFrame using "Salary Problem" set cpane = call getContentPane of sal_frame create gridmanager of class GridLayout using 5, 2 create namelabel of class JLabel using "Enter name: " create agelabel of class JLabel using "Enter age: " create salarylabel of class JLabel using "Enter salary: " create increaselabel of class JLabel using "Salary increase: " create nametfield of class JTextField using 20 create agetfield of class JTextField using 20 create salarytfield of class JTextField using 20 create inctfield of class JTextField using 20 create incbutt of class JButton using "Increase" create quitbutt of class JButton using "Quit" call setLayout of cpane using gridmanager call add of cpane using namelabel call add of cpane using nametfield call add of cpane using agelabel call add of cpane using agetfield call add of cpane using salarylabel call add of cpane using salarytfield call add of cpane using increaselabel call add of cpane using inctfield call add of cpane using incbutt call add of cpane using quitbutt create actlistener of class Sal_listener using salarytfield, inctfield call addActionListener of incbutt using actlistener call addActionListener of quitbutt using actlistener call setSize of sal_frame using WIDTH, HEIGHT call setVisible of sal_frame using true endfun main endclass Csalarygui
On the CD | The complete KJP code that implements class Csalarygui is stored in the file Csalarygui.kpl. The corresponding Java implementation is stored in the file Csalarygui.java. |
Class Sal_listener implements the behavior of the listener object, which responds to the buttons. Part of the code in this class calculates the salary increase and updates the salary. The KJP code that implements this class follows.
import all javax.swing // Library for graphics import all java.awt.event import java.text.DecimalFormat // for formatting description This class defines the behavior of listener objects for the button. When the user clicks the button, the program terminates. */ class Sal_listener implements ActionListener is private objects object salary of class JTextField object increase of class JTextField object myformat of class DecimalFormat public description Constructor that gets the salary, computes salary increase, and updates salary. */ function initializer parameters object fsalary of class JTextField, object fincrease of class JTextField is begin set salary = fsalary set increase = fincrease // object for formatting output numeric create myformat of class DecimalFormat using "###,###.##" endfun initializer description The only function in the class. */ function actionPerformed parameters object actev of class ActionEvent is variables double dsalary double dincrease string ssalary string form_increase string form_salary string actcomm begin // get string for salary from text field set ssalary = call getText of salary // convert to numeric double set dsalary = call Double.parseDouble using ssalary // get command info from action event set actcomm = call getActionCommand of actev if actcomm equals "Increase" then if dsalary > 45000 then set dincrease = dsalary * 0.045 else set dincrease = dsalary * 0.050 endif add dincrease to dsalary // convert salary and increase to strings // using decimal format set form_increase = call format of myformat using dincrease set form_salary = call format of myformat using dsalary // set new string data to field text call setText of salary using form_salary call setText of increase using form_increase else // user pressed quit button call System.exit using 0 endif endfun actionPerformed endclass Sal_listener
On the CD | The implementation of class Sal_listener is stored in the file Sal_listener.kpl. The Java implementation is stored in the file Sal_listener.java. |
When the program executes, the user directly interacts with the GUI presented. The data entered by the user is: "Chris D. Hunt" for attribute name, 45 for age, and 36748.50 for salary. The final data, after the program computes the salary increase and updates the salary, is shown in Figure 14.8.
Figure 14.8: A GUI for the salary problem.