October 21, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

An Automated Test Program using the Java Robot Class

  • July 29, 2003
  • By Richard G. Baldwin
  • Send Email »
  • More Articles »

Java Programming Notes # 1474


Preface

Programming in Java doesn't have to be dull and boring.  In fact, it's possible to have a lot of fun while programming in Java.  This is the second lesson in a short miniseries that shows you how to use the Robot class to write programs that are both fun and useful.

New features in SDK Version 1.3

One of the new features that was released in SDK Version 1.3 was the Robot class.  According to Sun,

"This class is used to generate native system input events for the purposes of test automation, self-running demos, and other applications where control of the mouse and keyboard is needed. The primary purpose of Robot is to facilitate automated testing of Java platform implementations."

What is a Java robot?

The Robot class makes it possible for your Java program to temporarily take control of the mouse and keyboard input functionality at the operating-system level.

Several instance methods are available

The Robot class provides several instance methods, (including the following), by which your program can produce mouse and keyboard input, just as though that input were being provided by a human user.

  • mouseMove - Moves the mouse pointer to a set of specified absolute screen coordinates given in pixels.
  • mousePress - Presses one of the buttons on the mouse.
  • mouseRelease - Releases one of the buttons on the mouse.
  • keyPress - Presses a specified key on the keyboard.
  • keyRelease - Releases specified key on the keyboard.

A word of caution

A runaway Java Robot object has the ability to wrest control away from the human user, so you need to be a little careful.  For example, if you allow your Java Robot program to go into an infinite loop, making mouse moves, clicking the mouse, and entering keystrokes, you may find that the only practical way to regain control of your computer is to either turn off the power or press the reset button to force your computer to restart.

Three lessons in the miniseries

According to my current plans, this miniseries on the Robot class will consist of three lessons.  The first lesson, entitled Introduction to the Java Robot Class in Java, demonstrated the low-level nature of an object of the Robot class.  That was accomplished by showing you how to create a Java robot that can manipulate other non-Java programs, such as Windows Notepad and Internet Explorer.

This lesson, which is the second lesson in the miniseries, will show you how to use a robot to perform automatic testing on a Java GUI.

The third lesson will show you how to write a robot program to provide a visual animated demonstration of the use of a Java GUI.

Viewing tip

You may find it useful to open another copy of this lesson in a separate browser window.  That will make it easier for you to scroll back and forth among the different listings and figures while you are reading about them.

Supplementary material

I recommend that you also study the other lessons in my extensive collection of online Java tutorials.  You will find those lessons published at Gamelan.com.  However, as of the date of this writing, Gamelan doesn't maintain a consolidated index of my Java tutorial lessons, and sometimes they are difficult to locate there.  You will find a consolidated index at www.DickBaldwin.com.

Preview

I will discuss the sample programs named Robot02 and Robot02Slave in this lesson.

(The program named Robot02 uses a Robot object to perform tests on an instance of the class named Robot02Slave.)

The sample programs in this lesson will show you how to use a Java robot to perform automatic testing on a Java GUI.

Discussion and Sample Code

Description of the program named Robot02Slave

Figure 1 shows the GUI produced by the program named Robot02Slave on startup, before being exercised by the Robot object belonging to the program named Robot02.  The GUI contains eight JToggleButton objects and one JTextField object in a GridLayout.

Figure 1 Test program GUI on startup

As you can see, the JToggleButton in the upper left corner has the focus and none of the toggle buttons are selected at startup.

Can be manipulated by Robot02

The class named Robot02Slave is used to instantiate a GUI object that can be manipulated by an object of the class named Robot02.  The class can also be used to instantiate a GUI object that can be manipulated manually using the mouse and the keyboard, independent of the robot object.

Will fire action and focus events

When you click on any of the buttons, the button will fire an ActionEvent.  Also, when you click on any of the buttons, the button will gain the focus and fire a FocusEvent if the button didn't already have the focus.

Button will toggle between two states

Because the button is a JToggleButton, it will also toggle between being selected and not being selected.  When the button is not selected, it is colored a light shade of gray, and appears to protrude from the screen (due to the Motif look and feel). When the button is selected, it is colored a dark shade of gray and appears to be pushed into the screen (see Figure 2 later for an example of selected buttons).

Text field also fires action and focus events

When you click the text field, it will gain the focus.  When you press the ENTER key while the text field has the focus, it will fire an ActionEvent

Focus traversal

If you successively press the focus traversal key, the focus will traverse the components using the focus traversal policy that is in effect.  I did not implement a new focus traversal policy, nor did I change the focus traversal key.  Therefore, the default focus traversal policy and the default focus traversal key are both in effect.  Successively pressing the TAB key will cause the focus to move from one component to the next, top to bottom, left to right, and then back to the top left.

If you hold down the SHIFT key and successively press the TAB key, the focus will traverse the components in the reverse direction.

Focus events

In all cases that the focus moves from one component to another, regardless of the cause, the component that gains the focus and the component that loses the focus will each fire a FocusEvent.

Common event handlers

A common ActionEvent handler is registered on each of the eight buttons and the text field.  The event handler gets and displays the value of the actionCommand property for the component that fired the event.

Whenever a component loses or gains the focus, that component will fire a FocusEvent.  A common FocusEvent handler is registered on each of the eight buttons and the text field.  The event handler gets and displays the value of the name property for the component that fired the event, along with an indication as to whether the focus was lost or gained by that component.

Sample screen outputs

Here is the screen output produced by the event handlers as a result of manually clicking the button with the H while the button with the A has the focus.

A lost focus H gained focus
ActionCommand = H

(Note that the value of the name property for each button was set to match the text on the face of the button.  The text on the face of a button is the default action command for the button.  Also note that the value of the name property for the text field was set to I.)

Here is the screen output produced by pressing the TAB key several times in succession, causing the focus to traverse the components in a forward direction.

H lost focus I gained focus
I lost focus A gained focus
A lost focus B gained focus
B lost focus C gained focus
C lost focus D gained focus
D lost focus E gained focus
E lost focus F gained focus

Note that the button showing the H had the focus when this sequence began.

Nothing special was required

With one exception, nothing special was done to cause this program to be suitable for manipulation by the program named Robot02.  That exception has to do with the main methodAs you will see later, the main method does not include any code that is necessary for this program to behave properly.  The code in the main method simply instantiates an object of the controlling class.

The program was tested using SDK 1.4.1 under WinXP.

The main method for the program named Robot02Slave

I will discuss this program in fragments.  A complete listing of the program is shown in Listing 24 near the end of the lesson.

Most of the code in this program is straightforward, and is explained in other tutorial lessons on my web site.  Therefore, the discussion of this program will be very brief.  The more detailed discussion will be reserved for the program named Robot02 later in the lesson.

The program named Robot02Slave begins in Listing 1 where the main method starts by instantiating an object of the class to which it belongs.
 

public class Robot02Slave extends JFrame
implements ActionListener,FocusListener{

public static void main(String[] args){
new Robot02Slave();
}//end main

Listing 1

This main method can be used to run the program in a standalone mode independent of the robot program.

(Note than this class implements two listener interfaces.  Therefore, an object of this class is a valid listener for action events and focus events.)

Prepare the JFrame for use

The constructor for the class begins in Listing 2.  The code in Listing 2 prepares the JFrame for use by setting the title, layout, location on the screen, size, etc.
 

  public Robot02Slave(){//constructor

setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE );
getContentPane().setLayout(
new GridLayout(3,3));
setBounds(10,10,250,200);
setTitle("Copyright 2003, R.G.Baldwin");

Listing 2

Create the button objects

The code in Listing 3 instantiates eight anonymous JToggleButton objects and adds them to the content pane.
 

    for(int cnt = 0; cnt < 8; cnt++){
getContentPane().add(new JToggleButton(
"" + (char)('A' + cnt)));
}//end for loop

Listing 3

The text on the faces of the buttons is set to the letters A through H.

Add a text field

The code in Listing 4 adds a JTextField object as the ninth component.
 

    getContentPane().add(new JTextField(""));

Listing 4

Get a list of the components

The code in Listing 5 gets a list of references to all nine components and stores them in the elements of an array of references of type Component.

    Component[] components =
getContentPane().getComponents();

Listing 5

Register event listeners on the components

The code in Listing 6 registers action and focus listeners on each of the components.
 

    for(int cnt = 0; cnt < components.length;
cnt++){
//Must downcast in order to register an
// action listener.
if(components[cnt] instanceof
JToggleButton){
((JToggleButton)components[cnt]).
addActionListener(this);
}else if(components[cnt] instanceof
JTextField){
((JTextField)components[cnt]).
addActionListener(this);
}//end else

//Register a focus listener on each
// component
components[cnt].addFocusListener(this);

//Give each component a name. Make the
// name match the text on the face of the
// buttons. Name the text field "I"
components[cnt].setName(
"" + (char)('A' + cnt));
}//end for loop

Listing 6

In addition, the code in Listing 6 sets the value of the name property of each component to a unique value by which we can recognize it later.

The code in Listing 6 is straightforward, so I won't discuss it further.

Set the look and feel, and make the GUI visible

The code in Listing 7 sets the look and feel to Sun's Motif, and makes the GUI visible.
 

    String plafClassName =
"com.sun.java.swing.plaf.motif." +
"MotifLookAndFeel";
try{
UIManager.setLookAndFeel(plafClassName);
}catch(Exception ex){ex.printStackTrace();}

//Cause the new L&F to be applied
SwingUtilities.updateComponentTreeUI(this);

//Make the frame visible
setVisible( true );
}//end constructor

Listing 7

Once again, the code in Listing 7 is straightforward, so I won't discuss it further.

Listing 7 signals the end of the constructor.

Define the action listener

Because the class named Robot02Slave implements the ActionListener interface, it must define the method named actionPerformed, which is declared in the interface.  This is accomplished in Listing 8.
 

  public void actionPerformed(ActionEvent e){
System.out.println("ActionCommand = " +
e.getActionCommand());
}//end actionPerformed

Listing 8

This code makes it possible to register this object as an action listener on each of the components in Listing 6.

Display the actionCommand property

The code in the actionPerformed method gets and displays the actionCommand property belonging to the component that fired the ActionEvent.  The default value for the actionCommand property for a JToggleButton object is the text on the face of the button.  The value of the actionCommand property for a JTextField object is the contents of the text field when the event was fired.

Define the focus listener

Because the class named Robot02Slave implements the FocusListener interface, it must define the methods named focusLost, and focusGained, which are declared in the interface.  This is accomplished in Listing 9.
 

  public void focusLost(FocusEvent e){
System.out.print(e.getComponent().getName()
+ " lost focus ");
}//end focus lost

public void focusGained(FocusEvent e){
System.out.println(e.getComponent().getName()
+ " gained focus");
}//end focusGained

}//end class definition

Listing 9

As is the case with the action listener, this code makes it possible to register this object as a focus listener on each of the components in Listing 6.

Firing focus events

Whenever the focus moves from one component to another, the component losing the focus and the component gaining the focus each fire a focus event.

Among other things, the FocusEvent object passed to the focusLost method identifies the component that lost the focus.  The FocusEvent object passed to the focusGained method identifies the component that gained the focus.

Display the value of the name property

When a focus event is fired, the code in Listing 9 displays the value of the name property belonging to the component that either lost or gained the focus, causing it to fire the event.

End of Robot02Slave program

Listing 9 also signals the end of the program named Robot02Slave.

Description of the program named Robot02

There is no GUI for the program named Robot02.  The program simply starts, instantiates an object of the Robot02Slave class, executes a series of mouse moves, mouse clicks, and keyboard inputs on that object, and then terminates.

A dynamic process

Because this is a dynamic process, you will need to actually run the program to see exactly how it behaves.  Figure 2 shows the GUI produced by the program named Robot02Slave after being exercised by the Robot object belonging to the program named Robot02.

Figure 2 Test program GUI after being exercised by the robot

You may find it useful to compare the appearance of the GUI in Figure 2 with the appearance of the GUI at startup shown earlier in Figure 1.

Behavior of the program named Robot02

This program illustrates the use of the Robot class, which was released in SDK Version 1.3, to exercise the various features of a Java GUI.

The program instantiates an object of the class named Robot02Slave.  The GUI belonging to this object contains eight JToggleButton objects and a JTextField object in a GridLayout as shown in Figures 1 and 2.  This program uses an object of the Robot class to exercise the GUI belonging to the Robot02Slave object.

Focus traversal

The upper-left button in the GUI shown in Figure 1 holds the focus when the program starts.

The robot presses the TAB key a sufficient number of times to cause the focus to traverse all of the components once in the forward direction according to the focus traversal policy in effect.  Because the default focus traversal policy is in effect, this causes the focus to move from left to right, top to bottom, ending on the text field in the bottom right as shown in Figure 2.

Then the robot holds down the SHIFT key and presses the TAB key a sufficient number of times to cause the focus to traverse all of the components once in the reverse direction.  At this point, the button in the upper left once again holds the focus, as shown in Figure 1.

A time delay is inserted between successive presses of the TAB key so that you can view the focus as it traverses the components.

Click the mouse on each button

The program identifies each of the components in the GUI produced by Robot02Slave, and determines the physical location of each of those components on the screen.

Once the robot has determined the location of a component, it presses and then releases the left mouse button on that component.  This constitutes a click on the button.

How do the components behave?

Clicking the mouse on a JToggleButton object causes the button to fire an ActionEvent and a FocusEvent.

Clicking the mouse on a JTextField object causes the text field to fire a FocusEvent.

Enter text into the JTextField object

Then, the program determines if the component being processed is a JTextField object.  If so, it types the text Done into the text field and presses the ENTER key to cause the text field to fire an ActionEvent.

This program was tested on my machine using SDK 1.4.1 under WinXP

Will discuss in fragments

As usual, I will discuss this program in fragments.  A complete listing of the program is shown in Listing 23 near the end of the lesson.  The class definition begins in Listing 10 with the declaration of a reference variable to hold a reference to an object of type Robot.

public class Robot02{
Robot robot;

Listing 10

Create an object to be exercised

The code in Listing 11 instantiates a new object of the class named Robot02Slave, discussed earlier in this lesson.  That object's reference is saved in a reference variable named slave, in order that it can be manipulated by the robot.

  Robot02Slave slave = new Robot02Slave();

Listing 11

Create some keycodes

The code in Listing 12 creates an array object of type int, and initializes the elements of the array to contain the virtual keycodes for the characters done.

(Note that regardless of the case of the characters in the names of the virtual keycodes, these keycodes must be combined with the virtual SHIFT keycode to produce upper-case versions of the characters.)

  int keyInput[] = {
KeyEvent.VK_D,
KeyEvent.VK_O,
KeyEvent.VK_N,
KeyEvent.VK_E
};//end keyInput array

Listing 12

As shown earlier in Figure 2, these characters will be automatically entered into the JTextField object belonging to the GUI being exercised by the robot.

The main method

The main method for the program named Robot02 is shown in Listing 13.
 

  public static void main(String args[]){
System.out.println("Start test program");
new Robot02();
System.out.println("\nEnd test program");
}//end main

Listing 13

As you can see, the code in the main method simply displays starting and ending messages and instantiates an object of the Robot02 class.

The constructor

The behavior of the program is controlled by code in the constructor, (which begins in Listing 14), and code in a method that is called by code in the constructor.

  public Robot02(){//constructor
try{
robot = new Robot();
}catch(AWTException e){
e.printStackTrace();
}//end catch

Listing 14

The constructor begins by instantiating an object of the Robot class, and saving that object's reference in the instance variable named robot, which was declared in Listing 10.  Because the reference is saved in an instance variable, it is accessible throughout the class.

Is the slave object visible?

Because of delays involved in displaying graphics, it is possible that the robot could become ready to be manipulate the GUI before the GUI is ready to be manipulated.  Therefore, the code in Listing 15 loops until the showing property of the GUI object becomes true.
 

    while(!(slave.isShowing())){
//loop until slave is showing on the screen
}//end while loop

Listing 15

(In order to avoid tying up computer resources with a tight loop, and slowing things down even more, it might be better to cause the current thread to sleep for a short period of time during each iteration of the loop in Listing 15.)

Get a list of GUI components

The code in Listing 16 gets a list of the components belonging to the GUI and saves the references to those components in the elements of an array object of type Component.
 

    Component[] components =
slave.getContentPane().getComponents();

Listing 16

The length of the array will be used by the robot to determine how many times to press the TAB key to cause the focus to traverse all of the components in the GUI.

The references stored in the array will be used by the robot later to click the mouse on each of the components.

Traverse the components in the forward direction

The code in Listing 17 prints a message, and then presses the TAB key a sufficient number of times to cause the focus to traverse all of the components once in the forward direction.
 

    System.out.println("\nTraverse forward");
for(int cnt = 0;
cnt < (components.length - 1); cnt++){
robot.keyPress(KeyEvent.VK_TAB);
//Insert delays to cause the focus to
// traverse the components slowly.
robot.delay(1000);
}//end for loop

Listing 17

A one-second delay is inserted between each key press to make it possible to view the focus as it traverses the components.

Focus events

Because focus events are fired each time the focus moves from one component to the next, the code in Listing 17 produces the following output on the screen.

Traverse forward
A lost focus B gained focus
B lost focus C gained focus
C lost focus D gained focus
D lost focus E gained focus
E lost focus F gained focus
F lost focus G gained focus
G lost focus H gained focus
H lost focus I gained focus

Each line of text shown above (except for the first line) was actually the result of two focus events being fired.  One event was fired by the component that lost the focus.  The other event was fired by the component that gained the focus.

(If you review the event handler methods in Listing 9, you will see that I invoked the print method for focusLost and the println method for focusGained.  This causes each pair of events to produce a single line of text in the output.)

Where is the screen output produced?

It is important for you to understand that except for the first line of text shown above, the screen output that is produced when the focus moves is being produced by the event handler methods belonging to the GUI object, and is not being produced by the robot.  The robot simply causes the focus to move by pressing the TAB key.  The behavior that results is strictly dependent on the event handlers belonging to the GUI being manipulated.

Traverse the components in the reverse direction

The code in Listing 18 prints a message and then presses the SHIFT key.
 

    System.out.println("\nTraverse backwards");
//Press the shift key.
robot.keyPress(KeyEvent.VK_SHIFT);
for(int cnt = 0;
cnt < (components.length - 1); cnt++){
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(1000);
}//end for loop
//Release the shift key.
robot.keyRelease(KeyEvent.VK_SHIFT);

Listing 18

Then the robot presses the TAB key a sufficient number of times to cause the focus to traverse all of the components once in the reverse direction.  Then the robot releases the SHIFT key.

Focus events

Again, because focus events are fired each time the focus moves from one component to the next, the code in Listing 18 produces the following output on the screen.

Traverse backwards
I lost focus H gained focus
H lost focus G gained focus
G lost focus F gained focus
F lost focus E gained focus
E lost focus D gained focus
D lost focus C gained focus
C lost focus B gained focus
B lost focus A gained focus

Click the components and enter text into the text field

The robot's next task is to execute a mouse click on each of the components and to enter text into the JTextField object.  This process begins in Listing 19, which shows the beginning of a for loop that is used to execute this process.
 

    System.out.println("\nClick all components");
for(int cnt = 0; cnt < components.length;
cnt++){
Point location =
components[cnt].getLocationOnScreen();
System.out.print("Click at: " +
location.x + ", " + location.y + " ");

Listing 19

Get and save screen location for each component

As shown in Listing 19, the first task in the for loop is to get, save, and display the actual screen coordinates for each component.

(Note that these are absolute coordinates in pixels relative to the upper-left corner of the screen, and are not coordinates relative to the upper-left corner of the object containing the components.)

Partial screen output

The code in Listing 19 produced the following screen output during the first iteration of the for loop.

Click all components
Click at: 14, 33

The first line of text shown above was produced by the first statement in Listing 19, which is outside the for loop.  The second line of text shown above shows the absolute screen coordinates of the upper left-hand corner of the component whose reference is stored in the first element of the array object referred to by the reference variable named components.

(The setBounds method invoked by the GUI constructor in Listing 2 causes the upper-left corner of the GUI to be located at screen coordinates 10, 10.  The above output indicates that the upper-left corner of the component is four pixels to the right of and 23 pixels below the upper-left corner of the JFrame object that is the container for the GUI.  Compare that with Figure 1 to confirm those numbers in your own mind.)

Execute a mouse click on the component

The code in Listing 20 invokes the mouseMoveAndClick method to execute a mouse click on the physical location on the screen where the component resides.
 

      mouseMoveAndClick(location.x,location.y);

Listing 20

The mouseMoveAndClick method

At this point, I am going to set the for loop in the constructor aside momentarily and discuss the method named mouseMoveAndClick, as shown in its entirety in Listing 21.

  public void mouseMoveAndClick(
int xLoc, int yLoc){
robot.mouseMove( xLoc,yLoc );
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);

robot.delay(1000);
}//end mouseMoveAndClick

Listing 21

The code in Listing 21 causes the robot to move the mouse pointer to a screen location specified by the incoming parameters.

Then the robot presses and releases the left mouse button, which represents a mouse click on that screen location.

Events may be fired

If a JToggleButton object, which does not already have the focus, is located at those coordinates, the combination of the operating system and the Java virtual machine working together causes the button at that location to gain the focus and to fire both an ActionEvent and a FocusEvent(If the button already has the focus, it won't fire the FocusEvent.)

If a JTextField object, which does not already have the focus, is located at those coordinates, the combination of the operating system and the Java virtual machine causes the text field to gain the focus and to fire a FocusEvent(If the text field already has the focus, it won't fire the FocusEvent.)

(Recall that if one component loses the focus when another component gains the focus, the component losing the focus will also fire a FocusEvent.)

A one-second delay

The code in Listing 21 also inserts a one-second delay to make it possible to view the effect of clicking the button.

Enter text into the text field

Returning to the discussion of the for loop in the constructor, the code in Listing 22 tests to see if the component being processed during the current iteration of the for loop is a JTextField object.

      if(components[cnt] instanceof JTextField
&& components[cnt].hasFocus()){
System.out.println("\nEnter text");
robot.keyPress(KeyEvent.VK_SHIFT);
for (int cnt2 = 0;
cnt2 < keyInput.length; cnt2++){
if(cnt2 > 0){
robot.keyRelease(KeyEvent.VK_SHIFT);
}//end if
robot.keyPress(keyInput[cnt2]);
robot.delay(1000);
}//end for loop
//Cause the text field to fire an
// ActionEvent
robot.keyPress(KeyEvent.VK_ENTER);
}//end if
}//end for loop
}//end constructor

Listing 22

Execute key presses to enter text and fire ActionEvent

If the component is a JTextField object, and if it has the focus, the code in Listing 22 causes the robot to type the text Done into the text field as shown in Figure 2.

(Note the use of the virtual SHIFT key to cause the first character to be entered in upper case and the remaining characters to be entered in lower case.  Also note the use of the virtual ENTER key to cause the text field to fire an ActionEvent after all the characters have been typed into the text field.)

The screen output

The code in Listings 19 through 22 causes the following screen output.

Click all components
Click at: 14, 33 ActionCommand = A
Click at: 94, 33 A lost focus B gained focus
ActionCommand = B
Click at: 174, 33 B lost focus C gained focus
ActionCommand = C
Click at: 14, 90 C lost focus D gained focus
ActionCommand = D
Click at: 94, 90 D lost focus E gained focus
ActionCommand = E
Click at: 174, 90 E lost focus F gained focus
ActionCommand = F
Click at: 14, 147 F lost focus G gained focus
ActionCommand = G
Click at: 94, 147 G lost focus H gained focus
ActionCommand = H
Click at: 174, 147 H lost focus I gained focus

Enter text
ActionCommand = Done

The screen output is mixed

The screen output shown above is a mixture of output produced by the Robot02 program and output produced by the event handlers belonging to the GUI object being manipulated by the robot.  The coordinate information is displayed by the robot.  The information regarding action events and focus events is produced by the event handlers belonging to the GUI.

The end of the Robot02 program

And that is the end of the code for the program named Robot02.

Run the Program

I encourage you to copy the code from Listings 23 and 24 into your text editor, compile it, and execute it.  Experiment with it, making changes, and observing the results of your changes.

The Robot class was first released in SDK Version 1.3, so you will need to be running Version 1.3 or later.  This program was tested on my machine using SDK 1.4.1 under WinXP

Summary

In this lesson, I have taught you how to use a Java robot to perform automatic testing on a Java GUI.

What's Next?

The next lesson in this miniseries will show you how to write an animated robot program to provide an animated visual demonstration of the use of a Java GUI.

Complete Program Listings

Complete listings of the programs discussed in this lesson are shown in Listings 23 and 24 below.
 
/*File Robot02.java
Copyright 2003 R.G.Baldwin

Illustrates the use of the java.awt.Robot class,
which was released in SDK Version 1.3.

The program instantiates an object of the class
named Robot02Slave. This object contains eight
JToggleButton objects and a JTextField object
in a GridLayout.

The program begins with the upper-left button
holding the focus.

The program presses the tab key eight times in
succession to cause the focus to traverse all of
the components in the forward direction according
to the default focus traversal policy, which
moves the focus from top left to bottom right.

At this point, the text field in the bottom right
holds the focus.

Then the program holds down the shift key and
presses the tab key eight more times in
succession to cause the focus to traverse all of
the components in the reverse direction.

At this point, the button in the upper left
holds the focus.

The program identifies each of the components
in the GUI produced by Robot02Slave. It
determines the physical location of each of those
components on the screen. Once it has determined
the location of a component, it presses the left
mouse button on that component and then releases
the left mouse button on that component. If the
component is a button, this causes the button to
fire an ActionEvent along with a FocusEvent.

If the component is a text field, it simply fires
a FocusEvent when clicked by the mouse.

Then, the program determines if the component is
a JTextField object. If so, it enters the text
"Done" into the text field and presses the Enter
key to cause the text field to fire an
ActionEvent.

Tested using SDK 1.4.1 under WinXP
************************************************/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Robot02{
//Create a robot object that will be used to
// exercise a GUI object.
Robot robot;

//The following GUI object will be exercised by
// the robot.
Robot02Slave slave = new Robot02Slave();

//The following text will be entered into the
// text field on the GUI.
int keyInput[] = {
KeyEvent.VK_D,
KeyEvent.VK_O,
KeyEvent.VK_N,
KeyEvent.VK_E
};//end keyInput array
//-------------------------------------------//

public static void main(String args[]){
System.out.println("Start test program");
new Robot02();
System.out.println("\nEnd test program");
}//end main
//-------------------------------------------//

public Robot02(){//constructor
try{
robot = new Robot();
}catch(AWTException e){
e.printStackTrace();
}//end catch

//Make certain that the slave is visible on
// the screen.
while(!(slave.isShowing())){
//loop until slave is showing on the screen
}//end while loop

//Get a list of the components on the slave
Component[] components =
slave.getContentPane().getComponents();

//Traverse the focus path from the beginning
// to the end in the forward direction.
System.out.println("\nTraverse forward");
for(int cnt = 0;
cnt < (components.length - 1); cnt++){
robot.keyPress(KeyEvent.VK_TAB);
//Insert delays to cause the focus to
// traverse the components slowly.
robot.delay(1000);
}//end for loop

//Traverse the focus path from the end to the
// beginning in the reverse direction.
System.out.println("\nTraverse backwards");
//Press the shift key.
robot.keyPress(KeyEvent.VK_SHIFT);
for(int cnt = 0;
cnt < (components.length - 1); cnt++){
robot.keyPress(KeyEvent.VK_TAB);
robot.delay(1000);
}//end for loop
//Release the shift key.
robot.keyRelease(KeyEvent.VK_SHIFT);

//Automatically click each button on the
// slave GUI. Then enter text into the text
// field
System.out.println("\nClick all components");
for(int cnt = 0; cnt < components.length;
cnt++){
//Get, save, and display actual screen
// location of a component
Point location =
components[cnt].getLocationOnScreen();
System.out.print("Click at: " +
location.x + ", " + location.y + " ");

//Execute a mouse click on the physical
// location on the screen where the
// component resides.
mouseMoveAndClick(location.x,location.y);

//If the component is a JTextField object,
// execute keystrokes that will enter the
// word "Done" into the text field. Note
// the use of upper and lower case.
if(components[cnt] instanceof JTextField
&& components[cnt].hasFocus()){
System.out.println("\nEnter text");
robot.keyPress(KeyEvent.VK_SHIFT);
for (int cnt2 = 0;
cnt2 < keyInput.length; cnt2++){
if(cnt2 > 0){
robot.keyRelease(KeyEvent.VK_SHIFT);
}//end if
robot.keyPress(keyInput[cnt2]);
robot.delay(1000);
}//end for loop
//Cause the text field to fire an
// ActionEvent
robot.keyPress(KeyEvent.VK_ENTER);
}//end if
}//end for loop
}//end constructor
//-------------------------------------------//

public void mouseMoveAndClick(
int xLoc, int yLoc){
robot.mouseMove( xLoc,yLoc );
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);

robot.delay(1000);
}//end mouseMoveAndClick

}//end class Robot02

Listing 23

 

/*File Robot02Slave.java
Copyright 2003 R.G.Baldwin

Illustrates the use of the java.awt.Robot class,
which was released in SDK Version 1.3.

This program is used to instantiate a GUI object
that is manipulated by an object of the class
named Robot02. The program can also be used to
instantiate a GUI object that can be manipulated
manually using the mouse and the keyboard,
independent of the robot object.

An object of this class contains eight
JToggleButton objects and a JTextField object
in a GridLayout.

When you click on any of the buttons with the
mouse, the button fires an ActionEvent. Because
it is a JToggleButton, it also changes between
a light shade of gray and a dark shade of gray.
When you enter text into the text field, the text
field fires an ActionEvent.

The same ActionEvent handler is registered on all
eight buttons and the text field. The event
handler gets and displays the ActionCommand for
the component that fires the event.

Whenever any of the components lose or gain the
focus, they fire a FocusEvent. The same
FocusEvent handler is registered on all eight
buttons and the text field. The event handler
gets and displays the name of the component along
with an indication as to whether the focus was
lost or gained.

Tested using SDK 1.4.1 under WinXP
************************************************/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Robot02Slave extends JFrame
implements ActionListener,FocusListener{

//This main method can be used to run the
// program in a standalone mode independent of
// the robot.
public static void main(String[] args){
new Robot02Slave();
}//end main
//-------------------------------------------//

public Robot02Slave(){//constructor

//Prepare the JFrame for use
setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE );
getContentPane().setLayout(
new GridLayout(3,3));
setBounds(10,10,250,200);
setTitle("Copyright 2003, R.G.Baldwin");

//Create eight buttons and add them to the
// content pane
for(int cnt = 0; cnt < 8; cnt++){
getContentPane().add(new JToggleButton(
"" + (char)('A' + cnt)));
}//end for loop

//Add a text field as the ninth component
getContentPane().add(new JTextField(""));

//Get a list of the components
Component[] components =
getContentPane().getComponents();

//Register listeners on each component and
// give each component a name
for(int cnt = 0; cnt < components.length;
cnt++){
//Must downcast in order to register an
// action listener.
if(components[cnt] instanceof
JToggleButton){
((JToggleButton)components[cnt]).
addActionListener(this);
}else if(components[cnt] instanceof
JTextField){
((JTextField)components[cnt]).
addActionListener(this);
}//end else

//Register a focus listener on each
// component
components[cnt].addFocusListener(this);

//Give each component a name. Make the
// name match the text on the face of the
// buttons. Name the text field "I"
components[cnt].setName(
"" + (char)('A' + cnt));
}//end for loop

//Set the look and feel to Motif
String plafClassName =
"com.sun.java.swing.plaf.motif." +
"MotifLookAndFeel";
try{
UIManager.setLookAndFeel(plafClassName);
}catch(Exception ex){ex.printStackTrace();}

//Cause the new L&F to be applied
SwingUtilities.updateComponentTreeUI(this);

//Make the frame visible
setVisible( true );
}//end constructor
//-------------------------------------------//

//Define the ActionEvent handler that is
// registered on each of the components.
public void actionPerformed(ActionEvent e){
System.out.println("ActionCommand = " +
e.getActionCommand());
}//end actionPerformed
//-------------------------------------------//

//Define the FocusEvent handlers that are
// registered on each of the components.
public void focusLost(FocusEvent e){
System.out.print(e.getComponent().getName()
+ " lost focus ");
}//end focus lost

public void focusGained(FocusEvent e){
System.out.println(e.getComponent().getName()
+ " gained focus");
}//end focusGained

}//end class definition

Listing 24


Copyright 2003, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects, and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Programming Tutorials, which has gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

Baldwin@DickBaldwin.com

-end-
 







Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel