Handling events
This chapter describes how to add and delete event handlers for components using the Inspector. It also gives specific examples of how to code commonly used event handlers for the JBuilder dialog components.
Event handling code vs. initialization code
In building your Java program, you can think of your code as being divided into two categories: initialization code
and event-handling code
.
- Initialization code is the code that is executed when the UI components are created. You can think of this primarily as "start up" code for the components. This initialization code includes anything in the
jbInit()
method that all JBuilder-designed classes have. This is code that you had JBuilder generate for you by using the visual design tools. An example of this would be a jButton.setText()
method that was generated because you set the text
property of a button using the Inspector.
- Event-handling code is the code that you want to have executed when the user performs some action, such as pressing a button or using a menu item. This is code that you will write inside the body of event-handling methods. JBuilder creates the stub (empty) event-handling method for the component when you double-click an event in the Inspector. By doing this, you are telling JBuilder that you want to execute some lines of code in your program when the user causes that event to occur on that component. You will place those lines of code in the event-handling method JBuilder creates in your code.
Your entire program, then, consists of the initialization code, which says how things should look when they first appear, and the event-handling code, which says what should happen when the user performs operations in the UI.
There are some JBuilder components, most notably the dialogs, that normally appear only when event-handling code is executed. For example, although you may place a dialog into your class using the component palette and the component tree, it isn't part of the UI surface you are designing in the UI designer. Instead, it is a separate UI element which appears transiently as a result of a user operation, such as a menu choice or a button press. Therefore, some of the code associated with using the dialog, such as a call to its show()
method, will have to be placed into the event-handling method. The nature of this code is completely custom, and so you will have to understand how to create and edit it.
Attaching event-handling code to a component event
Using the Events page of the Inspector, you can attach handlers to component events and delete existing event handlers.
To attach event-handling code to a component event,
- Select the component in the component tree or in the UI designer.
- Select the Events tab to display the events for that component.
- Click an event to select it, then double-click its name or press Enter. JBuilder creates an event handler with a default name (which you can override), and switches to that event handler in the source code. JBuilder also inserts some additional code into your class, called an
Adapter
, to make the connection from the event to your event handling method. See Code that JBuilder generates to connect events below.
- Write the code inside the body of the event handler that specifies how you want the program to respond to that component event.
Note: To find out what methods and events a component supports, double-click that component in the structure pane to load the class into the AppBrowser, then click the Doc tab to view the documentation for that class.
Shortcut for creating an event handler
To quickly create an event handler for a component's default event,
- Select a component on the component palette and add it to your UI.
- Double-click the component in the UI designer. An event stub is created and focus switches to that event handler in the source code.
- Add the necessary code to the event handler to complete it.
Note: The default event is defined by BeanInfo
, or as actionPerformed
if none was specified.
Example: Display "Hello World!" when a button is pressed
Here is a simple example of connecting code that displays "Hello World!" in response to a button being pushed. To generate this code yourself,
- Run the Application wizard to start a new application. Accept all the defaults and press Finish.
Frame1.java
opens in the editor
- Click the Design tab at the bottom of
Frame1.java
to display the UI designer.
- Select the
JTextField
and JButton
components on the Swing tab of the component palette and drop them in the component tree or in the UI designer.
- Select
jButton1
, then switch to the Events page in the Inspector. Double-click the actionPerformed
event. You will be taken to a newly generated stub in the source code for the event-handling method.
- Enter the following code inside the braces of the event-handling method:
jTextField1.setText("Hello World!");
- Run the application to try it out. (Click the Run button
on the toolbar, or press F9.)
When your application appears, click the button to see the text "Hello World!" appear in the text field.
In this example, the JFrame
component listens for the actionPerformed
event on the button. When that event occurs, the JFrame
sets the text in the JTextField
.
Code that JBuilder generates to connect events
If you are using standard event adapters, rather than anonymous adapters, when you double-click an event in the Inspector, in addition to generating an event-handling method stub, JBuilder also automatically generates two other pieces of code in your class to hook up the event from the control to your event-handling method: an EventAdapter
and an EventListener
.
Note: You can also choose to use inner classes as event adapters, rather than the standard adapters. See Choosing which style event handlers to use later in this section.
Understanding the EventAdapter and the EventListener classes
- JBuilder creates an
EventAdapter
class for that specific component/event connection and gives it a name which corresponds to that particular component and event. This is several lines of code (which you do not need to edit) that are added in a new class at the bottom of your file.
For example, in the "Hello World!" application, JBuilder generates a type of EventAdapter
called an ActionAdapter
with the following code:
class Frame1_jButton1_actionAdapter implements java.awt.event.ActionListener {
Frame1 adaptee;
Frame1_jButton1_actionAdapter(Frame1 adaptee) {
this.adaptee = adaptee;
}
- JBuilder also creates a line of code in the
jbInit()
method which connects the component's event source through the EventAdapter
to your event-handling method by calling an addListener
method of the component. The addListener
method takes a parameter of the matching EventAdapter
, and in this case the EventAdapter
is constructed in place. Its constructor parameter is the this
reference to your Frame
that contains the event-handling method.
For example, the following is the line of code that performs this in the Hello World application:
jButton1.addActionListener(new Frame1_jButton1_actionAdapter(this));
The adaptor class name is arbitrary and can be anything as long as the reference matches.
JBuilder creates the adapter class with the implementation for the only method in the ActionListener
interface. The method that handles the selected event calls another method in the adaptee (Frame1
) to perform the desired response.
Note: There will be more than one overridden method if more events from one set are handled, like mousePressed
and mouseReleased
.
Choosing which style event handlers to use
When you create an event using the Events tab in the Inspector, JBuilder generates event adapter code in your container class to handle the aspects of event listening.
JBuilder gives you the option to choose which style of event handling code is automatically generated. The two styles of event adapters are:
Each of these is explained below. You can also choose to match the style to that already being used in the code.
To specify which style event adapters JBuilder generates,
- Choose Project|Project Properties.
- Click the Code Style page and select either Standard adapter or Anonymous adapter, as an Event Handling option.
- Click OK.
Now JBuilder will use that selected style in the code it generates for events in the current project.
To choose a default event adapter style for all new projects,
- Choose Project|Default Project Properties.
- Click the Code Style page and select an adapter type.
- Click OK.
The next project, and all subsequent projects, will use the selected type.
To match newly generated adapters to the style used in existing code,
- Choose Project|Default Project Properties.
- Click the Code Style page and select Match Existing Code.
- Click OK.
Now JBuilder checks first to see which style is being used in a class, then uses the same style for all new event adapters.
Standard event adapters
JBuilder generates an action adapter class that implements the ActionListener
interface. It then instantiates the class in the UI file and registers it as a listener for the component (for example, for a jButton1
event, it calls jButton1.addActionListener()
). All this code is visible in the source code. All that's left for you to do is to fill in the event-handling method that the action adapter calls when the event occurs.
For example, here is code that is generated for a focusGained()
event:
jButton1.addFocusListener(new Frame1_jButton1_focusAdapter(this));
void jButton1_focusGained(FocusEvent e) {
// code to respond to event goes here
}
class Frame1_jButton1_focusAdapter extends java.awt.event.FocusAdapter {
Frame1 adaptee;
Frame1_jButton1_focusAdapter(Frame1 adaptee) {
this.adaptee = adaptee;
}
public void focusGained(FocusEvent e) {
adaptee.jButton1_focusGained(e);
}
}
Anonymous inner class adapters
JBuilder can also generate inner class event adapters. Inner classes have the following advantages:
- The code is generated inline, thereby simplifying the appearance of the code.
- No separate class is generated.
- The inner class has access to all variables in scope where it is declared, unlike the standard event adapters that have only public and package level access.
The particular type of inner class event adapters that JBuilder generates are known as anonymous adapters
. This style of adapter avoids the creation of a separate adapter class. The resulting code is compact and elegant.
For example, the following is code that is generated for a focusGained()
event using an anonymous adapter:
jButton1.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(FocusEvent e) {
jButton1_focusGained(e);
}
}
void jButton1_focusGained(FocusEvent e) {
}
Compare this code with the standard adapter code sample shown above. JBuilder generated that code using a standard adapter class. Both ways of using adapters provide the code to handle focusGained()
events, but the anonymous
adapter approach is more compact.
Example event handler
Below is a specific example of a frequently used event handler. For additional examples of event handling code, see the tutorial called Building a Java text editor.
Invoking a dialog box from a menu item
When you design your own programs, you will typically need to add several lines of custom code in the event-handling methods. For example, you might want to extract the file name the user entered from a JFileChooser
dialog and use it to open or manipulate a file.
The following example shows you how to invoke a JFileChooser dialog box from a File|Open menu item:
- Run the Application wizard in a new or existing project.
- Press next on Step 1 to accept the defaults from this step.
- Check Generate Menu Bar on step 2, then press Finish to accept the rest of the defaults.
- Select the
frame
file (Frame1.java
) in the project pane and click the Design tab at the bottom of the AppBrowser to open the visual design tools.
- Select the
JFileChooser
component on the Swing Containers tab of the palette, and click the UI
folder in the component tree. A component called jFileChooser1
is added to the UI section of the tree.
Note: If you drop this component anywhere else in the tree or the designer, it becomes a sub-component of 'this', rather than the UI as a whole and becomes the UI for your Frame1.java
file.
- Create an Open menu item on the File menu as follows: (The example code below was generated with Open as
jMenuItem1
.)
- select
MenuBar1
in the component tree and press Enter to open the menu designer.
- Place the cursor on the File|Exit menu item in the designer and press the Insert Item button
on the menu designer toolbar. A new empty menu item is added.
- Enter Open as a new menu item.
- Select the Open menu item in the designer or on the component tree, then click the Events tab in the Inspector.
- Double-click the
actionPerformed
event in the Inspector to generate the following event-handling method stub in the source code:
void jMenuItem1_actionPerformed(ActionEvent e) {
}
JBuilder takes you to this event-handling method in the source code.
- Inside the braces of the
actionPerformed
event-handling method, type the following:
jFileChooser1.showOpenDialog(this);
- Now save your files then run your program and try File|Open.
Deleting event handlers
To delete an existing event handler,
- Select the component in the component tree or in the UI designer.
- Select the Events tab in the Inspector, and click the event you want to delete.
- Highlight the entire name of the event handler in the right hand column.
- Press Delete and Enter to remove the event handler name.
JBuilder automatically deletes the associated event-handling method and adapter class from the source code if the handler is empty.