|

Focus Events, Click Events, and Drag-and Drop in AJAX Using the GWT and Java
By Richard G. Baldwin
Java Programming Notes # 2556
Preface
Historically, the development of Ajax web applications has been a complex
process. This is due mainly to the requirement to learn and use a variety of
technologies, such as HTML, JavaScript, XML, ASP.NET, Java servlets, various
scripting languages, etc.
Recently several products have emerged that make it possible to develop Ajax
web applications using the Java development environment. Some use exclusively
Java, while others use mainly Java. I have discussed several of these new
programming environments in previous lessons in this series (see
Resources).
The Google Web Toolkit (GWT)
One development environment that allows you to use mainly Java for the
development of web applications is the Google Web Toolkit (GWT) (see
Resources and Download),
which is the primary topic of this tutorial lesson.
Most of the client-side code for a GWT Ajax application can be written in
Java. There is no requirement to write JavaScript code.
Fourth
in a series
This is the fourth lesson in a series designed to help you learn
how to use the GWT to create rich Ajax web applications. You will find links to
the previous lessons in the series in the Resources
section.
Purpose of the tutorial
The main purpose of the tutorial is to teach you how to write
the Java code necessary to perform drag-and-drop operations in AJAX using the
GWT and Java. In addition, I will teach you hot to use of the
FocusListener and ClickListener interfaces.
I recommend that you open another copy of this document in a separate
browser window and use the following links to easily find and view the figures
and listings while you are reading about them. You may also find it useful
to open a third browser window at the Resources section near the end of the
document. That will make it easy for you to open those resources when they
are mentioned in the text.
- Figure 1. The application GUI at startup.
- Figure 2. The application GUI after clicking the
TextBox.
- Figure 3. The application GUI after clicking the
Right button.
- Figure 4. Gaining the focus with the tab key.
- Figure 5. Firing a click event with the space
bar.
- Figure 6. The application GUI at startup.
- Figure 7. Firing a click event with the space
bar.
- Figure 8. Results for mouse events.
- Figure 9. Application GUI for GwtApp018 at
startup.
- Figure 10. Application GUI after dragging the
custom button.
I recommend that you also study the other lessons in my extensive collection
of online Java tutorials. You will find a consolidated index at
www.DickBaldwin.com.
What is focus?
No matter how many applications are running concurrently on a computer and no
matter how many GUIs are showing on the desktop, only one component in one GUI
belonging to one application can respond to the keyboard at any point in time.
The component that can respond to keyboard input is said to have the focus.
Focus event handling has a long history
Focus events have been available in standard Java since at lease version 1.1 in 1997.
With the release of J2SE version 1.4, Sun completely revamped the focus
subsystem. Because they added a large number of new capabilities at that
time, dealing with focus in standard Java became much more difficult with the
release of J2SE version 1.4.
Some resources on focus event handling
For an explanation of what is currently possible and an indication of the
complexity of the Focus subsystem in standard Java, see "The AWT Focus
Subsystem" in Resources.
For additional information on the use of the revamped focus subsystem in
standard Java, see
the following tutorials in Resources:
- "Focus Traversal Policies in Java Version 1.4"
- "Focusability in Java Version 1.4"
- "Changing Focus Traversal Keys in Java V1.4"
Something a little less complicated
For a somewhat less complex discussion of focus and the handling of focus
events, see my early tutorial named "Event Handling in JDK 1.1, Requesting the
Focus" in Resources.
That early tutorial was published
long before the release of the revamped focus subsystem in version 1.4.
However, much of the material in that tutorial maps directly into the GWT focus
subsystem, which is much simpler than the revamped focus subsystem in standard
Java. The focus subsystem in the GWT looks a lot more like the early focus
subsystem in standard Java than the revamped focus subsystem in J2SE
v1.4.
Handling focus events
The programming process
for handling focus events in the GWT is essentially the same as the process
in standard Java except for the names of a couple of methods and
the types of parameters that those methods receive.
|
|
Focus event handlers in standard Java
The focus event handling methods and parameter types in standard Java are:
- void focusGained(FocusEvent e)
- void focusGained(FocusEvent e)
|
|
The programming process
The programming process
for handling focus events in the GWT consists of the following steps:
- Define a class that implements the FocusListener interface.
- Override and provide concrete definitions for the following abstract
methods that are declared in the interface. The behavior that results
from the firing of a focus event is established by the code in the
overridden methods.
- void onFocus(Widget sender)
- void onLostFocus(Widget sender)
- Instantiate an object of the new class and register it on the GUI
component that is expected to fire the focus event.
|
|
The GWT API Map
The GWT API Map in Resources is a very helpful tool
for supplementing the javadocs when searching for this kind of information. |
|
Which GUI components can fire focus events?
Any GUI component that either defines or inherits the registration method
named addFocusListener can fire focus events. This includes at
least the following GWT GUI components and possibly some others that I
overlooked in my search:
- ListBox
- Frame
- PasswordTextBox
- TextBox
- TextArea
- Button
- Checkbox
- RadioButton
- FocusPanel
- Tree
The sample applications in this lesson will concentrate on focus events fired
by Button, TextBox, and FocusPanel objects.
Focus events often occur in pairs
Recall that only one component can
have the focus at any point in time. When a component gains
the focus, it will fire an onFocus event as a result of gaining the
focus. If some other component had the focus before, it will fire an
onLostFocus event as the result of losing the focus. Therefore, focus
events often occur in pairs.
Don't always occur in pairs
Be aware, however, that there are situations where one component can lose the focus
without another component (in the same application at least) gaining the
focus. Similarly, there are situations where a component can gain the
focus but there was no component in the same application that previously had the
focus. An example of this latter situation is the case where the
application first starts running and a component gains the focus at startup.
Since the application was not previously running, it is not possible that some
component belonging to that application could have had the focus.
A visual indication of focus
Most GUI components provide a visual indication to the user that the
component has the focus. (Note the
sidebar later in this document that discusses an apparent bug in the GWT
regarding the visual indication of focus, or the lack thereof.) The actual visual indicator will depend on the
look and feel ascribed to the components being used.
Perhaps the most consistent visual indication of focus among all of the GUI
components across many operating systems is the existence of a blinking cursor
in components that allow the user to enter text into the component. Just
about everyone who uses a computer recognizes the blinking cursor as an
indication that it is OK to enter text. You will see some visual
indications of focus in the sample applications in this tutorial.
Focus traversal
In most cases, repeatedly pressing the tab key will cause the focus to move
among the components in a GUI according to a specified traversal path. Also,
in most cases, holding down the Shift key and repeatedly pressing the tab key
will cause the focus to move among the same components in the reverse of the
specified
traversal path.
Two ways to establish the traversal path
|
|
Standard Java is more complex
If you have looked into the Sun document named "The AWT Focus Subsystem"
(see Resources), you have probably noticed that
the techniques for establishing the traversal path in post-v1.4 standard
Java are much more sophisticated and much more complicated than those
described here for the GWT. The techniques described here for the GWT
are very similar to those that existed for pre-v1.4 standard Java.
|
|
There appear to be at least two ways for the programmer to establish the
focus traversal path in the GWT. The most straightforward way is to allow
the traversal path to be established automatically on the basis of the order in
which the components are placed in their container.
The setTabIndex method
A more complicated way of establishing the traversal path is to invoke a method named setTabIndex on each
component in the GUI passing an int value as a parameter to the method.
According to the GWT documentation, this
"Sets the widget's position in the tab index. If more than one widget
has the same tab index, each such widget will receive focus in an arbitrary
order. Setting the tab index to -1 will cause this widget to be
removed from the tab order."
Having set a tab index value on each component, repeatedly pressing the tab
key will cause the focus to move among the components in increasing numeric
tab-index order. Holding down the Shift key while repeatedly pressing the
tab key will reverse the traversal path.
What is a click event?
A click event is an event that is fired by a component to indicate that a
specific action has occurred with respect to the component. The most common way
to cause a component to fire a click event is to click it with the mouse
(hence the interface name addClickListener and the method name onClick).
In addition, some components can fire click events as a result of certain
keyboard actions while the component has the focus.
Two examples of keyboard actions and click events
For example, pressing the space bar when a Button object has the focus
will cause the button to fire a click event in the GWT and will cause the button
to fire an ActionEvent in standard Java. (A click event in the
GWT is analogous to an action event in standard Java.)
On the other hand, pressing the Enter key when a standard Java TextField
object has the focus will cause it to fire an ActionEvent, but pressing
the Enter key when a GWT Textbox object has the focus will not cause it
to fire a click event. (The similarity between the two breaks down in this case.)
|
|
ActionEvent handling in standard Java
Click events in the GWT are analogous to Action events in standard Java.
The programming process for handling Action events consists of the following steps:
- Define a class that implements the ActionListener interface.
- Override and provide a concrete definition for the following abstract
method that is declared in the interface. The behavior that results
from the firing of an Action event is established by the code in the
overridden method.
- void actionPerformed(ActionEvent e)
- Instantiate an object of the new class and register it on the GUI
component that is expected to fire the Action event.
|
|
Handling click events
The programming process for handling click events in the GWT is essentially the same as the process
in standard Java except for the name of the interface, the name of the single
event handling method, and
the type of parameter that the event handling method receives.
The programming process
The programming process
for handling click events in the GWT consists of the following steps:
- Define a class that implements the ClickListener interface.
- Override and provide a concrete definition for the following abstract
method that is declared in the interface. The behavior that results
from the firing of a click event is established by the code in the
overridden method.
- void onClick(Widget sender)
- Instantiate an object of the new class and register it on the GUI
component that is expected to fire the click event.
Which GUI components can fire click events?
Any component that either defines or inherits the registration method named
addClickListener can fire a click event. This includes at least the
following GWT GUI components and possibly some others that I overlooked during
my search:
- ListBox
- Frame
- PasswordTextBox
- TextBox
- TextArea
- Button
- Checkbox
- RadioButton
- FocusPanel
- Hyperlink
- Image
- Label
- HTML
The first sample application in this lesson will concentrate on click events
fired by Button and TextBox objects.
Credit to Mr. Eric Sessoms
The GWT drag-and-drop sample application in this
lesson is not a creation of my own design. Rather,
the technical information and the ideas behind the sample application were taken
(with written permission via Email) from the original author whose name
is Eric Sessoms. (See Drag and Drop using the GWT in
Resources.)
Will defer to Eric Sessoms blog for background
information
Mr. Sessoms does a much better job than I could do with regard to the
General background information on performing drag-and-drop with the GWT.
Therefore, I will refer you to his blog for that information. I will
content myself with attempting to explain how and why the sample application
behaves as it does.
Depends heavily on handling mouse events
I will point out, however, that the drag-and-drop technique described herein depends heavily
on the use of mouse events, the MouseListener interface, and the
MouseListenerAdapter class. If you haven't already studied my earlier
lesson named "Event driven programming in AJAX using the GWT and Java" (see
Resources) where I explain the handling of mouse
events in some detail, now would be a good time to do so.
Three sample GWT
web applications
I will present and explain three sample GWT applications in this lesson. The
names of the three applications are shown in the following list. This list also
shows the primary topic that each application is designed to illustrate.
- GwtApp016 - Focus events and click events.
- GwtApp017 - Creating a custom button component that fires mouse events.
- GwtApp018 - Performing drag-and-drop operations on the custom button
component.
Discussion
and sample code
Complete program listingsI will discuss
the code for the following applications in fragments. A complete listings
of each application is provided in Listing 22 through Listing 27 near the end of the
lesson.
The HTML host pages
The HTML host pages used for the applications in this lesson are essentially
the same as those used for the applications in my earlier tutorials.
Therefore, I won't discuss them in this lesson. However, a complete listing of
each HTML host page is provided in Listing 22
through Listing 27 along with the Java source code for the application.
The application GUI at startup
Figure 1 shows a screen shot of the application named GwtApp016 at
startup when running in Internet Explorer 6.
Figure 1. The application GUI at startup.
The row of Label objects shown at the bottom in Figure 1 contains column
headers for three columns that will contain the following information:
- Which component (if any) lost the focus?
- Which component (if any) gained the focus?
- Which component (if any) fired a click event?
There is no information showing under those column headers at startup because
no component has yet gained the focus, no component has yet lost the focus, and
no component has yet fired a click event.
The application GUI after clicking the TextBox
Figure 2 shows the state of the GUI after the user started the application
running and then clicked the TextBox object once with the mouse.
Figure 2. The application GUI after clicking the
TextBox.
The information in the middle column shows that this caused the text box to
gain the focus. However, the left column is still blank because at this
point, no component lost the focus because no component had the focus at
startup.
The right column in Figure 2 shows that the text box fired a click event when
the user clicked the text box with the mouse.
The application GUI after clicking the Right button
Figure 3 shows the state of the GUI as a result of the user clicking the
Right button while the text box had the focus.
Figure 3. The application GUI after clicking the
Right button.
|
|
Why no visual indication of focus?
Note that even though the Right button has the focus in Figure 3, the button
is not displaying a visual indication of focus. This problem manifests
itself when the application is run in either IE6 or hosted mode.
However, the problem does not manifest itself when the application is run in Firefox.
A visual indication of focus appears as it should when the application is
run in Firefox. This
strongly suggests that this is a bug in the GWT, and a fairly serious one
from a user perspective.
|
|
The left column in Figure 3 shows that the text box lost the focus. The
middle column shows that the Right button gained the focus. The right
column shows that the Right button also fired a click event as a result of the
user clicking the Right button with the mouse.
Gaining the focus with the tab key
Figure 4 shows the result of restarting the application and pressing the tab
key repeatedly until the Right button gains the focus.
Figure 4. Gaining the focus with the tab key.
|
|
A visual indication of focus.
Note that unlike Figure 3, there is a visual indication of focus on the
Right button in Figure 4. This is what we would expect to always be the case when the
button has the focus. However, it appears that clicking the button in
either IE6 or hosted mode does not cause the button to provide a visual
indication of focus, even though it clearly gains the focus. As
mentioned earlier, this is not a problem in Firefox. |
|
The focus traversal pathBecause of the order in which the components were placed in their container,
the forward focus traversal path for the tab key is from left to right across
the two buttons and the text box. Thus, when the Right button gained the
focus, the text box lost the focus as shown by the information in the two left
columns in Figure 4.
No click event showing
Note that the right column in Figure 4 is still blank because no click events have been fired since the application was restarted.
Firing a click event with the space bar
Figure 5 shows the result of pressing the space bar while the Right button
has the focus as shown in Figure 4.
Figure 5. Firing a click event with the space bar.
A click event was fired
The right column in Figure 5 shows that a click event was fired by the Right
button as a result of pressing the space bar on the keyboard while the Right
button had the focus.
Description of the application
This application demonstrates FocusListener, ClickListener, and
tool tips.
It places two Button objects and a TextBox object in a
HorizontalPanel object as shown in Figure 1.
Listeners
The application defines inner classes (not anonymous inner classes)
that implement listener interfaces. One inner class implements the
FocusListener interface and the other class implements the ClickListener
interface.
The application instantiates and registers FocusListener and
ClickListener objects on each of the buttons and on the text box.
Titles for tooltips
The application also sets a title on each button and on the text box to cause each of
them to show tooltips whenever the mouse pointer hovers over the
component. (Figure 2 shows a tooltip immediately below the Right
button. Note however, that the screen shot did not capture the image of
the mouse pointer in Figure 2.)
A simple table to display event information
As shown in Figure 3, the application uses HorizontalPanel objects,
Label objects, and a VerticalPanel object to create a simple table
that shows which components fired events of the following types (going from
left to right in Figure 3):
- onLostFocus
- onFocus
- onClick
|
|
Not always reliable
Note: The table does not display reliable focus lost and focus gained
information in those cases where the focus leaves all three of the components
shown in Figure 3. |
|
The tooltip titles are also used to identify the components that fired each
specific event when the information is displayed in the table.
Application testing
The application was tested using J2SE 5.0, GWT version 1.2.22, and
jakarta-tomcat-5.0.27 running as a localhost server under WinXP.
Beginning of the class definition
Listing 1 shows the beginning of the class definition and the beginning of
the onModuleLoad method for the application named
GwtApp016.
Listing 1. Beginning of the class definition for
GwtApp016.
package GwtApp.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;
public class GwtApp016 implements EntryPoint{
//These three labels are used for text output. They are
// declared as instance variables to make them accessible
// by the methods in the inner classes.
private Label label20;
private Label label21;
private Label label22;
//This is the entry point method.
public void onModuleLoad(){
//Create the basic structure of the GUI.
HorizontalPanel topPanel = new HorizontalPanel();
topPanel.setSpacing(5);
HorizontalPanel middlePanel = new HorizontalPanel();
middlePanel.setSpacing(5);
HorizontalPanel bottomPanel = new HorizontalPanel();
bottomPanel.setSpacing(5);
VerticalPanel vertPanel = new VerticalPanel();
vertPanel.add(topPanel);
vertPanel.add(middlePanel);
vertPanel.add(bottomPanel);
|
I have explained code similar to the code in Listing 1 in numerous sample
applications in previous lessons. Therefore, there should be no need for a
further explanation of the code in Listing 1 beyond the explanation provided by
the embedded comments.
Populate the top HorizontalPanel object
Listing 2 populates the top HorizontalPanel object with two Button
objects and a TextBox object.
Listing 2. Populate the top HorizontalPanel object.
//Populate the topPanel with two buttons and a TextBox
Button button00 = new Button("Left");
TextBox textBox = new TextBox();
textBox.setText("TextBox");
Button button02 = new Button("Right");
//Make the buttons the same width.
button00.setWidth("50px");
button02.setWidth("50px");
//Add the three components to the horizontal panel
topPanel.add(button00);
topPanel.add(textBox);
topPanel.add(button02);
|
Once again, there is nothing new in Listing 2, so I won't discuss it further.
Some more common code
Listing 3 populates the middle and bottom panels using code similar to the
code that you have seen in numerous previous sample applications.
Therefore, I won't discuss the code in Listing 3 any further.
Listing 3. Some more common code.
//Populate the middle panel with three labels. These
// labels serve simply to explain the contents of the
// three labels below them.
Label label10 = new Label("Lost Focus");
Label label11 = new Label("Gained Focus");
Label label12 = new Label("Was Clicked");
label10.setWidth("85px");
label11.setWidth("85px");
label12.setWidth("85px");
middlePanel.add(label10);
middlePanel.add(label11);
middlePanel.add(label12);
//Populate the bottom panel with three output labels.
// The contents of these three labels are modified by
// the code in the event handlers to explain the
// events.
label20 = new Label("");
label21 = new Label("");
label22 = new Label("");
label20.setWidth("85px");
label21.setWidth("85px");
label22.setWidth("85px");
bottomPanel.add(label20);
bottomPanel.add(label21);
bottomPanel.add(label22);
|
Set the tooltip text
We've finally gotten to some code that is new to this lesson. The code
in Listing 4 sets the tooltip text for each of the three components, by invoking
the setTitle method on each of the components. Invoking the
setTitle method on a component in the GWT is all that is required to cause
the component to display a tooltip.
Listing 4. Set the tooltip text.
button00.setTitle("Left Button");
textBox.setTitle("TextBox");
button02.setTitle("Right Button");
|
The titles that are set in Listing 4 serve not only as tooltip text, but also
serve as text identifiers for the components that gain the focus, lose the focus, and
fire click events. These text identifiers are displayed in the table shown in Figure 3.
Register listener objects
Listing 5 begins by instantiating a listener object of the inner class named
FocusLstnr. Then it registers that single common listener object on
each of the buttons and on the text box.
Listing 5. Register listener objects.
//Register a common focus listener on each button and
// on the text box.
FocusLstnr focusLstnr = new FocusLstnr();
button00.addFocusListener(focusLstnr);
textBox.addFocusListener(focusLstnr);
button02.addFocusListener(focusLstnr);
//Register a common click listener on each button and
// on the text box.
ClickLstnr clickLstnr = new ClickLstnr();
button00.addClickListener(clickLstnr);
textBox.addClickListener(clickLstnr);
button02.addClickListener(clickLstnr);
//Add the vertical panel to the browser window. The
// vertical panel serves as a backbone and the three
// horizontal panels serve as ribs.
RootPanel.get().add(vertPanel);
}//end onModuleLoad method
|
The code in Listing 5 also instantiates a common listener object of the
inner class named ClickLstnr. Then it registers that common
listener object on each of the buttons and on the text box. As a result,
both a focus listener and a click listener are registered on both buttons and on
the text box.
Add the VerticalPanel to the RootPanel and end the
method
Finally, the code in Listing 5 adds the populated VerticalPanel object
to the RootPanel, thereby completing the construction of the application
GUI.
Listing 5 also signals the end of the onModuleLoad method.
Define the inner class named ClickLstnr
|
|
A member class
An inner class is also known as a member class. (See "The
Essence of OOP using Java, Member Classes" in
Resources for more information.)
|
|
Listing 6 defines the inner class named ClickLstnr. It was defined as an inner
class in this application so that the interface method named onClick would have direct access to one of the three output Label objects.
As you can see, this class implements the ClickListener interface and
defines the onClick method that is declared in that interface. This
is the only method that is declared in the ClickListener interface.
Listing 6. Define the inner class named ClickLstnr.
class ClickLstnr implements ClickListener{
public void onClick(Widget sender){
label22.setText(sender.getTitle());
}//end onClick
}//end class ClickLstnr
|
Need to identify the source of the event
The onClick method in Listing 6 is executed any time that any of the
three components fires a click event. Therefore, it is necessary for the
method to
identify the component that fired the event. Fortunately, the incoming parameter named
sender of type Widget points back to the component that fired the
event.
The code in Listing 6 invokes the getTitle method on that reference to
get the tooltip title that was established for the component earlier.
Then it displays that title in the rightmost column in the table in Figure 3 to
identify the component that fired the click event.
Define member class named FocusLstnr
Listing 7 defines the inner (member) class named FocusLstnr.
This class implements the interface named FocusListener and defines the
two event handler methods declared in that class. As before, this class
was made an inner class so that the code in the each method would have
direct access to the label used to display results for that method.
Listing 7. Define member class named FocusLstnr.
class FocusLstnr implements FocusListener{
public void onLostFocus(Widget sender){
label20.setText(sender.getTitle());
}//end onLostFocus
//---------------------------------------------------//
public void onFocus(Widget sender){
label21.setText(sender.getTitle());
}//end onFocus
}//end class FocusLstnr
//=====================================================//
}//end class GwtApp016
|
When are the two methods executed?
As you probably already know, one of the methods in Listing 7 is executed when a
component loses the focus and fires an event whose type corresponds to the onLostFocus
method. The other
method is executed when a component gains the focus and fires an event whose
type corresponds to the onFocus method.
The code in each of the methods in Listing 7 is essentially the same as the code in Listing 6,
except that the identification of the component that fired the event is
displayed in one of the two columns on the left in Figure 3.
The end of the class
Listing 7 also signals the end of the class named GwtApp016.
At this point, you have learned much of what there is to know about the focus
subsystem in the GWT. What you have learned will be useful in
understanding the next two sample applications.
A few things that you haven't learned
As indicated earlier, the GWT focus subsystem is much simpler than the focus
subsystem in post-v1.4 standard Java. However, there are a few features of
the GWT focus subsystem that weren't discussed here. You can learn about
them by going to the index in the javadocs, searching for the word "focus" and
reading about any interesting methods that you turn up in that process.
Do you understand the handling of GWT mouse events?
In order to understand the material in this application, you will need to
understand quite a lot about the handling of mouse events in the GWT. I
explained mouse event handling in the earlier lesson named "Event driven
programming in AJAX using the GWT and Java" (see
Resources). If you haven't studied that lesson yet, I suggest that
you do so at this time.
Which components can fire mouse events?
Any component that either defines or inherits the registration method named
addMouseListener can fire a mouse event. This includes the following GWT
GUI components and possibly some others that I may have missed in my
search:
- Label
- HTML
- Image
- FocusPanel
- Tree
All in all, that is a rather short list, at least in comparison to the number
of GUI components that can fire mouse events in standard Java.
Forcing a GUI component to fire mouse events
|
|
Other event types
This application is written around the concept of forcing a component to fire
mouse events, but it could just as well have been written around the concept of forcing
a component to fire click events or focus events. |
|
What if you have a need for a GWT GUI component to fire mouse events but that
component is not included
in the above list?
I'm going to show you how to force a Button to fire mouse events in this
application. I will show you why you may want to do that in the next
application.Not restricted to Button objects
The technique that I will describe here is not restricted to Button objects. You should
be able to use what I am going to show you in this application to force any
component to fire mouse events, click events, or focus events.
The application GUI at startup
Figure 6 shows the application GUI at startup. The large button in
Figure 6 is a custom button that fires mouse events.
Figure 6. The application GUI at startup.
The output data
The five labels below the button show the results of handling mouse events
and click events that are fired by the button as the user manipulates the mouse and the keyboard with
respect to the button. Each of the labels shows the default values at
startup in Figure 6.
The five labels display the following information:
- Whether the mouse pointer is inside or outside the area occupied by the
custom button. As you can see the default value is Out.
This label will display In when the mouse pointer is inside the
custom button's
area.
- The coordinates of the last location recorded as the mouse is moved
within the area occupied by the custom button. These coordinate values
are dynamic values that continuously change as the mouse is moved within
that area. As you can see, the default coordinate values at startup
are both 0. The coordinate values are given in pixels relative to the
upper left corner of the custom button.
- The coordinates of a point within the custom button's area where a mouse button was most
recently pressed. These coordinate values change each time the user
presses a mouse button while the mouse pointer is inside the area occupied
by the custom button.
- The identification of the component (if any) that fired the most recent click
event.
- The identification of another component (if any) that fired the most recent click
event. The meaning of these two output values will become clearer
once you understand the code that is used to create the custom button.
Firing a click event with the space bar
Figure 7 shows the result of:
- Starting the program.
- Repeatedly pressing the tab key until the custom button gains the focus.
- Pressing the space
bar.
Figure 7. Firing a click event with the space bar.
No mouse events
As you can see, the top three labels that are used to show the results of handling mouse events
still have their default values in Figure 7. That is because no mouse
events had yet been fired when the screen shot was taken. However, using the tab key to cause the custom
button to gain the focus and then pressing the space bar caused two components
to fire click events as shown by the bottom two labels.
Why two components?
It is probably time to provide a little more explanation about the two
components that fired click events. A you can see, the two components are identified in Figure 7
as:
The custom button is actually the composite of a Button object and a
FocusPanel object. The button is wrapped in the focus panel,
and the composite of the two is considered to be the custom button.
However, there are two separate components involved and each has the native ability
to fire a click event.
The Button referred to in Figure 7 is the ordinary button that is
wrapped in the focus panel. The Custom Button that is referred to
in Figure 7 is actually the FocusPanel that wraps the Button.
These are the two components for which click events are recorded in the bottom
two labels in Figure 7.
Results for mouse events
|
|
Where is the mouse pointer?
Note that the process of capturing the screen shot in Figure 8 did not capture
the image of the mouse pointer, which was pointing to the "n" when the
screen shot was taken.
|
|
Figure 8 shows the result of using the mouse to point to and click on the
upper-case "C" in the button caption, and then moving the mouse pointer to the
right and letting it rest on the lower-case "n".
Figure 8. Results for mouse events.
|
|
How many components fired mouse events?
Unlike the click events discussed earlier, in this case only the FocusPanel
that wraps the standard Button object fired mouse events, because the Button
object does not have the native ability to fire Mouse Events.
|
|
Are you in or out?
The first label under the button shows that the mouse pointer was In
the area occupied by the custom button when the screen shot was taken.
The Last Move Location
The second label under the button shows the coordinates of the lower-case
"n", which was the location of the mouse pointer when the screen shot was taken.
The Last Down Location
|
|
Mouse moved versus mouse dragged
The mouse-event results
would have been the same if the mouse button had been held down while making the
move, because unlike standard Java, the GWT makes no distinction between
"mouse moved" and "mouse dragged." |
|
The third label under the button shows the coordinates of the upper-case "C",
which was the location of the mouse pointer when the mouse button was pressed
and then released before moving it to the lower-case "n".
The click event
The bottom two labels show the results of the click event that was fired when
the mouse button was pressed and then released.
Description of the application
This application demonstrates the creation of a custom button that can fire mouse events and
otherwise behaves more or less like a standard Button component.
|
|
What is a FocusPanel?
According to the javadocs, a FocusPanel object is "A simple panel that makes its contents focusable, and adds the ability to catch mouse and keyboard events."
One way to establish the contents of a FocusPanel is to pass another
object's reference as a parameter to the constructor when the panel is
constructed. |
|
Wrap a Button in a FocusPanelThe application wraps a standard Button
object in a FocusPanel object to create the custom button. An object of the
FocusPanel that wraps the standard button then behaves more or less like a standard
button except that it can fire mouse events in addition to click events and focus events.
Set tooltip titles
|
|
Which tooltip is displayed?
The tool tip that is displayed is the title that is set on the standard button
and is not the title that is set on the custom button |
|
The application sets titles on
the standard button and the custom button in order to display tool tips when the
mouse pointer hovers on the custom button.
Another use for tooltip titles
The titles are also used to identify the component that fires a
click event when the mouse button is pressed in the area occupied by the custom
button or when the space bar is pressed while the standard button wrapped in the
FocusPanel has the focus. When this happens, both the standard button and the
custom button fire a click event.
Construction of the GUI
The application puts the custom button along with five Label
objects in a VerticalPanel object as shown in Figure 6. The labels are used to display the fol |