JavaWindow Focus and State in Java

Window Focus and State in Java

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Java Programming, Notes # 1857


Preface

The focus subsystem

This lesson is part of a series of lessons designed to
teach you how to use the focus subsystem.  This is also the first part of a
two-part lesson to teach you how to use the Window focus and state features.

The first lesson in the series was entitled
Focus
Traversal Policies in Java Version 1.4
.  The previous lesson was
entitled
Capturing Keyboard Strokes in Java
.

Previous topics

Previous lessons in this series have taught you how to use several features of the new focus subsystem,
including the following:

  • Defining new focus traversal keys.
  • How to control focusability at runtime.
  • The ability to query for the currently focused Component.
  • The default Focus Traversal Policy.
  • How to establish a focus traversal policy and modify it at runtime.
  • How to control the focus programmatically.
  • Opposite components.
  • The KeyEventDispatcher.
  • The KeyEventPostProcessor.

Topics covered in this lesson

This lesson, which is Part 1 of a two-part lesson, will explain Window
focus and extended Window state.

(Although extended Window state is not a focus topic, it was very
convenient to explain and illustrate the topic in this lesson, so I decided to
include it here.)

Part 2 of this two-part lesson will present and explain a program that
demonstrates various aspects of Window focus and extended Window
state.

What do we mean by focus?

Among all of the applications showing on the desktop at any point in time,
only one will respond to the keyboard.

If that application is a Java application, only one component
within that application’s graphical user interface (GUI) will respond to
the keyboard.  That is the component that has the focus at that
point in time.

It is also possible for a Java Window, (and its
subclasses Frame, JFrame, Dialog, and JDialog)

to gain the focus and to respond to the
keyboard even if the Window contains no focusable components.

A Java component or Window that has the focus also has the ability to fire KeyEvents when it responds to the keyboard. 
The fact that a component or Window can fire KeyEvents confirms that it has the
focus.

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 figures and listings 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.

Background Information

Window focus

An object of the class Window, or its subclasses
Frame, JFrame, Dialog, and JDialog can gain the focus and respond to the
keyboard.  This is true even if the object doesn’t contain any focusable
components.

Extended Window state

Prior to V1.4, the state information maintained by a Window was limited
to:

  • NORMAL
  • ICONIFIED

Subsequent to the release of V1.4, a Window can maintain state information
that includes:

  • MAXIMIZED_HORIZ
  • MAXIMIZED_VERT
  • MAXIMIZED_BOTH

An object of the class Window and its
subclasses Frame and JFrame have the ability to fire events when its state changes. 
A program can respond to those events and determine both the old state and the
new state.  The program can also determine the current state at any point
in time by invoking the getExtendedState method on the Window.

(I discovered this new feature while doing research into the Window
focus topic.  Even though it has little to do with the focus subsystem,
it is relatively easy to illustrate and explain along with Window focus.  Therefore, I decided to
include it in this lesson.)

Uses of Window focus

A couple of uses for the Window focus capability come immediately to
mind.  For example, one might like to display an animated creature in the
client area of a Window, Frame or JFrame, and to control its
movement and behavior using the arrow keys (or any other keys for that
matter).
 

Because the Window can gain the focus, it can also respond to the
keyboard and fire KeyEvents.  Code could be written into the KeyEvent handlers to control the behavior of the animated creature.

Another possibility might be to display an image, (such
as a street map)
in the client area of the Window and to use the
arrow keys and other keys to scroll the image or to zoom in and out on the image.  Once
again, code could be written into KeyEvent handlers to provide the
desired behavior.

Uses of Window state

A Window, a Frame, or a JFrame can fire events when the
state of the Window changes.

(Throughout this lesson, I will often refer to a Frame, a JFrame, a
Dialog, or a JDialog as a Window, because
Window is the superclass of these other classes.)
 

A Window
is in one of the following five states at any point in time:

  • NORMAL
  • ICONIFIED
  • MAXIMIZED_HORIZ
  • MAXIMIZED_VERT
  • MAXIMIZED_BOTH

(This feature doesn’t apply to Dialog and JDialog
objects because they don’t provide user controls that allow the user to
iconify or to maximize them.)

Maximization

Prior to the release of V1.4, the standard windowIconified and windowDeiconified event types could be used by the program to learn that the
user had either iconified or deiconified a Frame or a JFrame
object.

Prior to the release of the extended state feature in V1.4, I was not aware of any mechanism that made it possible for
a program to determine that the user had maximized a Frame or a JFrame

Subsequent to the release of V1.4, that determination is not only possible, it is also easy. 

According to Sun,

"In older versions of the JDK a frame state could only be NORMAL or
ICONIFIED.  Since JDK 1.4 the set of supported frame states is expanded
and frame state is represented as a bitwise mask."

Event notification and state maintenance

A program can now request to be notified each time the state of a Window
changes, and can easily determine both the old state and the new state when the
change occurs.

In addition, the current state is maintained automatically and is available at any time simply by
invoking the getExtendedState method on the Window.

(In older versions, the appropriate query method was getState
The Sun documentation for V1.4.2 declares the getState method to be
obsolete. – Note that I didn’t say deprecated. – The getState method has been replaced by the
getExtendedState method
in V1.4.)

Required modifications to the API

A fairly large number of modifications were required to add these two
features to the API.  Here is a partial list:

  • Definition of a new WindowFocusListener interface.  This
    interface declares two new methods named windowGainedFocus and windowLostFocus.  Each method receives an incoming parameter of
    type WindowEvent.
  • Definition of a new WindowStateListener interface.  This
    interface declares a single new method named windowStateChanged,
    which also receives an incoming parameter of type WindowEvent.
  • Update the WindowAdapter class to cause it to implement the two
    new interfaces listed above.  It was also necessary to update the class
    to define default versions of the three new methods declared in those
    interfaces.
  • Update the WindowEvent class to add three new constants named WINDOW_GAINED_FOCUS,
    WINDOW_LOST_FOCUS, and WINDOW_STATE_CHANGED.  New overloaded constructors were
    also defined that allow for the construction of an object with a specified
    oldState and a specified newState.  New methods named getOldState and
    getNewState were also defined.
  • The Window class was upgraded to add two new methods named processWindowFocusEvent and
    processWindowStateEvent.  These
    two methods are required to support low-level focus and state
    event handling on the Window in conjunction with the enableEvents
    method.  Four new
    registration methods named addWindowFocusListener, removeWindowFocusListener,
    addWindowStateListener, and removeWindowStateListener were added to the
    Window class to
    support high-level event registration and handling of the new focus
    and state event types.  Finally, several new utility methods
    such as getWindowFocusListeners, getWindowStateListeners, isFocusableWindow,
    getFocusableWindowState, setFocusableWindowState, and isFocused
    were added to the Window class to support the new event types.

Order of event delivery

Sun tells us that when focus moves to a component in a Window that is
not currently the active Window, the events relative to the newly active
Window
will be delivered in the following order:

  • WINDOW_ACTIVATED
  • WINDOW_GAINED_FOCUS
  • FOCUS_GAINED on the component gaining the focus

(For the case where the newly active Window doesn’t contain any
focusable components, only the first two events occur.)

Moving the focus to another Window

Similarly, when the focus moves from that component to a component in another
Window, the order of event delivery will be:

  • FOCUS_LOST on the component losing the focus
  • WINDOW_LOST_FOCUS on the currently active Window
  • WINDOW_DEACTIVATED on the currently active Window
  • WINDOW_ACTIVATED on the new active window
  • WINDOW_GAINED_FOCUS on the new active window
  • FOCUS_GAINED on the component that is gaining the focus

Specific order must be maintained

Sun also tells us,

"… each event will be fully handled before the next event is
dispatched. This restriction will be enforced even if the Components are in
different contexts and are handled on different event dispatching threads.

… each event type will be dispatched in 1-to-1 correspondence with
its opposite event type. For example, if a Component receives a FOCUS_GAINED event, under no circumstances can it ever receive another
FOCUS_GAINED event without an intervening FOCUS_LOST event."

Preview

In Part 1 of this lesson, I will explain how a Window
can gain the focus, and can respond to the keyboard while it has the focus, even
if that Window contains no focusable components.

I will describe both low-level and high-level event handlers to
respond to Window focus events.

I will explain how to make use of the extended Window state and will explain how a program can respond to Window state events to
learn that the user has maximized a Window.

I will provide a program for your review that illustrates the above concepts.

I will explain that program in Part 2 of this lesson.

Description of the
Program

The two parts of this lesson present and explain a sample program named FocusWindow02,
which illustrates the ability of a Window

  • To gain and lose the focus
  • To fire events when the focus is gained or lost

The program also illustrates the capability of a Window object to fire
events when the state of the JFrame changes among five different possible
states. Significant among these possible states are three states having to with
maximization of the Window.

A list of the five possible states was provided earlier in this lesson.

The program GUI

The program causes two JFrame objects to appear on the screen as
shown in Figures 1 and 2.



Figure 1 Half of program GUI.

Only one can be active

Both JFrame objects appear on the screen at the same time, but only
one can be active (indicated by the bright blue banner) at any given
time.

(The fact that they both appear to be active in these images is an artifact of the
way that I went about capturing the images.)



Figure 2 The other half of program GUI.

Physical location

The program places the two JFrame objects on the screen, one above the
other. The JFrame object on the top (shown in Figure 1) contains two
JButton objects, both of which are focusable.

The JFrame object on the bottom (shown in Figure 2) contains a
single Canvas object, which is not focusable. Therefore, the JFrame
object on the bottom contains no focusable components.

Coordinates of an invisible point

The JFrame object in Figure 2 illustrates the use of focus on a Window that contains no focusable components.

The coordinates of an
invisible point are displayed on the Canvas near the location of the
invisible point.

(The location of the invisible point is immediately to the left and
slightly below the left-most character in the coordinates.)

Behavior of the JFrame object

When this JFrame object has the focus, pressing the
arrow keys causes an increase or a decrease in the coordinate values for the invisible point.

(Each press on an arrow key increases or decreases the value of one
coordinate by five pixels.)

Thus, pressing the arrow keys modifies and moves the displayed coordinate values.

Demonstrates that the JFrame has the focus

This is
accomplished by servicing KeyEvents on the object, thus demonstrating
that the JFrame object actually has the focus, even though it contains no
focusable components.

Behavior of the other JFrame object

The JFrame object in Figure 1 contains two JButton objects labeled
respectively:

  • Regain focus
  • Send focus to B

Clicking the button labeled Regain focus:

  • Causes the JFrame object in Figure 2 to lose the focus (if it
    has the focus)
  • Causes the JFrame object in Figure 1 to gain the focus (if it
    doesn’t already have the focus)
  • Causes the JButton object labeled Regain focus to gain
    the focus  (if it doesn’t already have the focus)

(Note that I skipped the part about the frames being deactivated and
activated in the above description.)

Clicking the button labeled Send focus to B causes the
JFrame object and the button in Figure 1 to momentarily gain the focus. 
However, the program transfers
the focus to the JFrame object in Figure 2 immediately thereafter with a
very short time delay.  This causes the sequence of events described under
Order of event delivery to occur.

Gaining focus in Figure 2

The JFrame object in Figure 2 will gain the focus if the user clicks
the button labeled Send focus to B in Figure 1.

The JFrame object in Figure 2 will also gain the focus if it is
clicked with the mouse.

(There are also other ways that the JFrame object in Figure 2
can gain the focus, such as being restored from an iconified state.)

Screen output

As each JFrame object gains and loses focus, and becomes iconified or
maximized, information about the
gain and loss of focus and the status of the Window is displayed on the screen.

This is accomplished using both high-level event handling and low-level event
handling.  The event handlers report on events of the following three
types:

  • WINDOW_STATE_CHANGED
  • WINDOW_GAINED_FOCUS
  • WINDOW_LOST_FOCUS

High-level event handling

The high-level approach to event handling involves registering objects of the
interface types WindowFocusListener and WindowStateListener on the
JFrame object.

Low-level event handling

The low-level approach makes use of the following methods:

  • enableEvents(AWTEvent.WINDOW_EVENT_MASK)
  • processWindowEvent(WindowEvent e)
  • processWindowFocusEvent(WindowEvent e)
  • processWindowStateEvent(WindowEvent e)

Other WindowEvent types from earlier versions

The program also uses low-level event handling to display information about
other WindowEvent types such as the following:

  • WINDOW_ACTIVATED
  • WINDOW_CLOSED
  • WINDOW_CLOSING
  • WINDOW_DEACTIVATED
  • WINDOW_DEICONIFIED
  • WINDOW_ICONIFIED
  • WINDOW_OPENED

(This list includes event types that have been a standard part of the
API since before the release of SDK
V1.4.)

Sample screen output

The screen output at startup is shown in Figure 3.

Low:processWindowEvent B
205 WINDOW_ACTIVATED

Low:processWindowFocusEvent B
207 WINDOW_GAINED_FOCUS
High:windowGainedFocus B

Low:processWindowEvent B
200 WINDOW_OPENED

Low:processWindowFocusEvent B
208 WINDOW_LOST_FOCUS
High:windowLostFocus B

Low:processWindowEvent B
206 WINDOW_DEACTIVATED

Low:processWindowEvent A
205 WINDOW_ACTIVATED

Low:processWindowFocusEvent A
207 WINDOW_GAINED_FOCUS
High:windowGainedFocus A
High:focusGained on Regain focus button

Low:processWindowEvent A
200 WINDOW_OPENED

Figure 3

Low-level event handling output

The lines of text that begin with the word Low, and the lines that
begin with a number such as 205 were produced by low-level event handlers.

High-level event handling output

The lines that begin with the word High were produced by high-level
event handlers.

Combined low and high-level event handling

All of the Window focus events were handled both ways.

(All of the Window state events were also handled both ways,
but that is not shown in Figure 3.)

Miscellaneous notes

The low-level event handling always occurs
before the high-level event handling for the same event in this program.

(This is something that you have control over, as I will explain in
Part 2 of this lesson.)

Only low-level event handling was used for the event
types other than Window focus events and Window state events, (such as
the WINDOW_DEACTIVATED event type).
  These event types have been available
for many years, so I saw no need to handle them both ways.

What about a WINDOW_MAXIMIZED event type?

As of this writing, there are ten WindowEvent types:

  • WINDOW_STATE_CHANGED
  • WINDOW_GAINED_FOCUS
  • WINDOW_LOST_FOCUS
  • WINDOW_ACTIVATED
  • WINDOW_CLOSED
  • WINDOW_CLOSING
  • WINDOW_DEACTIVATED
  • WINDOW_DEICONIFIED
  • WINDOW_ICONIFIED
  • WINDOW_OPENED

A standard WindowEvent, (that is directly descriptive of the event)
is fired when a Window is iconified (WINDOW_ICONIFIED) and also
when a Window is deiconified (WINDOW_DEICONIFIED).

However, there is no WindowEvent type (that is directly descriptive
of the event such as WINDOW_MAXIMIZED)
that is fired when a Window is
maximized.

A WINDOW_STATE_CHANGED event type

However, a WINDOW_STATE_CHANGED event is fired when a JFrame is maximized
(or iconified).

Beginning with V1.4, extended state information regarding the state of the Window is
encapsulated in the WindowEvent object when the event is fired. 
This information can be extracted by invoking the
following methods on the WindowEvent object:

  • getOldState
  • getNewState

(The state of the Window can also be obtained by invoking the
getExtendedState method on the Window object.)

Was the Window maximized?

The fact that the JFrame has been maximized can be extracted from the
state of the Window.  The program is no longer deprived of that
information.

Allowable states for a Window

As of the date of this writing, the following five states are defined for a Window:

  • NORMAL
  • ICONIFIED
  • MAXIMIZED_HORIZ
  • MAXIMIZED_VERT
  • MAXIMIZED_BOTH

(Prior to the release of V1.4, only the first two states were defined
for a Window.)

This state information is defined as values of type int, corresponding
to descriptive constants matching the above list. These constants are defined in
the Frame class, so they are accessible both for a Frame and its
subclass JFrame.

What are the values of the constants?

The actual value associated with each constant in the above list (and many
other constants as well)
can be determined by looking the constant up in the
API documentation and selecting the hyperlink named Constant Field Values.

(Ideally, you don’t normally need to know the values of the constants,
but that information can sometimes be useful, if only out of curiosity.)

Possible modifications to the program

Although this program uses Swing components and draws the coordinate
values on a Canvas object, it is a trivial matter to modify the program
to cause it to use only AWT components, and to eliminate the Canvas
object. In that case, the coordinate values are drawn directly on the Frame.
Since the Frame doesn’t contain any components at all in that situation, it is
guaranteed that it doesn’t contain any focusable components.

It is also easy to convert the program to one that uses JDialog
objects in place of JFrame objects. Of course, JDialog objects
can’t be minimized or maximized, so that portion of the program having to do
with the Window State has no meaning with respect to JDialog objects.

The program code

The entire program is provided in Listing 1 near the end of the lesson.

I will break the program down into fragments and discuss it in detail in
Part 2 of this two-part lesson.

Run the Program

Although I haven’t explained the code in Part 1 of this two-part lesson, I encourage you to copy, compile, and run the program provided in
Listing 1 near the end of the lesson.

If you feel comfortable in doing so at this point, experiment with it, making changes and observing the results of your changes.

(If you don’t feel comfortable experimenting with the code yet, I will
explain the code in detail in Part 2 of this lesson.)

One very useful modification to the program for experimental purposes is to
add the following statement in the various event-handler methods:

System.out.println(new Date());

This statement causes the time to be displayed along with the other
information related to an event.  This makes it easier to interpret the
various lines of output on the screen by making it possible to determine which
groups of lines were produced in rapid succession.

Also consider modifying the program to use Frame, Dialog, and
JDialog objects instead of JFrame objects.  Consider
eliminating the requirement for a Canvas object, causing your Window
to contain no components at all, focusable or otherwise.

Summary

I explained a Window can gain the
focus, and can respond to the keyboard while it has the focus, even if that Window contains no focusable components. 

I described both low-level and high-level event handlers to
respond to Window focus events.

I explained how to make use of the extended Window state, and
explained how the program can respond to Window state events to learn
that the user has maximized a Window.

What’s Next?

I provided a program that illustrates the above concepts in Listing 1 near
the end of this lesson.  I will explain that program in Part 2 of this
lesson.

Complete Program Listing

A complete listing of the program discussed in this lesson is provided below.

/*File FocusWindow02.java
Copyright 2004 R.G.Baldwin
Rev 07/30/04
This program illustrates the ability of a Window
to gain and lose the focus, and to fire events
when the focus is gained or lost.  This
capability is new to SDK V1.4.

The program also illustrates the ability of a
JFrame to fire events when the state of the
JFrame changes.  This capability is also new to
SDK V1.4.  A list of the possible states is
provided later in this discussion.

The program places two JFrame objects on the
screen, one above the other.  The JFrame object
on the top contains two JButton objects, both
of which are focusable.

The JFrame object on the bottom contains a single
Canvas object, which is not focusable.  Therefore
the JFrame object on the bottom contains no
focusable components.

The JFrame object on the bottom illustrates the
use of focus on a Window that contains no
focusable components.  The coordinates of an
invisible point are displayed on the Canvas near
the location of the invisible point.  When this
object has the focus, pressing the arrow keys
will change the coordinates of the invisible
point, thus modifying and moving the displayed
coordinate values.  This is accomplished by
servicing KeyEvents on the object, thus
demonstrating that the JFrame object actually
has the focus.

The JFrame object on the top contains two
JButton objects labeled respectively:

Regain focus
Send focus to B

Clicking the first of these two buttons will
cause the JFrame object on the top to gain the
focus, will cause the JFrame object on the bottom
to lose the focus, and will also cause the
JButton object to gain the focus.

Clicking the button labeled "Send focus to B"
will momentarily cause the JFrame object and the
button to gain the focus, but will immediately
transfer the focus to the JFrame object on the
bottom.

The JFrame objet on the bottom will also gain the
focus if it is clicked with the mouse.

As each JFrame object gains and loses focus,
information about the gain and loss of focus is
displayed on the screen, using both high-level
event handling and low-level event handling.

The high-level approach makes use of an object
of type FocusListener.

The low-level approach makes use of the following
methods:

enableEvents(AWTEvent.WINDOW_EVENT_MASK)
processWindowEvent(WindowEvent e)
processWindowFocusEvent(WindowEvent e)
processWindowStateEvent(WindowEvent e)

The program also uses low-level event handling to
display information about other WindowEvent types
such as the following.  Note that this list
includes focus and state events, which are new
to SDK V1.4.

WINDOW_ACTIVATED
WINDOW_CLOSED
WINDOW_CLOSING
WINDOW_DEACTIVATED
WINDOW_DEICONIFIED
WINDOW_ICONIFIED
WINDOW_OPENED
WINDOW_STATE_CHANGED
WINDOW_GAINED_FOCUS
WINDOW_LOST_FOCUS

Note that there is no WindowEvent type that is
fired when a JFrame is maximized.  However, a
windowStateChanged event is fired when a JFrame
is maximized.  Information about the state of
the window is encapsulated in the WindowEvent
object and can be extracted using the following
methods:

getOldState
getNewState

The fact that the JFrame has been maximized can
be extracted from the state of the window.  The
following states are defined:

NORMAL
ICONIFIED
MAXIMIZED_HORIZ
MAXIMIZED_VERT
MAXIMIZED_BOTH

This state information is defined as values of
type int, corresponding to the descriptive
constants in the above list.  These constants are
defined in the Frame class.

The actual value associated with each constant in
the above list (and many other constants as well)
can be determined by looking the constant up in
the API documentation and selecting the hyperlink
named Constant Field Values.

Although this program uses Swing components and
draws the coordinate values on a Canvas object,
it is a trivial matter to modify the program
to use only AWT components, and to eliminate the
Canvas object.  In that case, the coordinate
values are drawn directly on the Frame.  Since
the Frame doesn't contain any components at all,
it is absolutely guaranteed that it doesn't
contain any focusable components.

It is also easy to convert the program to one
that uses JDialog objects in place of JFrame
objects.  Of course, JDialog objects can't be
minimized or maximized, so that portion of the
program having to do with the Window State has
no meaning with respect to JDialog objects.

Tested using JDK 1.4 under WinXP
************************************************/

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

public class FocusWindow02 extends JFrame{

  public static void main(String[] args){
    //Instantiate an object of this class, which
    // will, in turn, instantiate an object of
    // the class named GraphicsGUI.
    FocusWindow02 winA = new FocusWindow02();
  }//end main
//---------------------------------------------//
  public FocusWindow02(){//constructor

    //Instantiate a GraphicsGUI object, The
    // GraphicsGUI object will be identified as B
    // in the screen display.
    final GraphicsGUI winB = new GraphicsGUI();

    //Now construct the object of this class,
    // prepare it to handle events, and make it
    // visible.  This object will be identified
    // as A in the screen display.
    // Begin by setting some properties.
    setTitle("A Copyright 2004, R.G.Baldwin");
    getContentPane().setLayout(new FlowLayout());
    setSize(400,100);
    setDefaultCloseOperation(
                           JFrame.EXIT_ON_CLOSE);

    //Instantiate two buttons, prepare them to
    // handle FocusEvents, and add them to the
    // JFrame.
    JButton regainButton = new JButton(
                                 "Regain focus");
    regainButton.addFocusListener(
                               new FocusLstnr());
    getContentPane().add(regainButton);

    JButton sendButton = new JButton(
                              "Send focus to B");
    sendButton.addFocusListener(
                               new FocusLstnr());
    getContentPane().add(sendButton);

    //Prepare one of the buttons to handle
    // ActionEvents using an anonymous inner
    // class.
    sendButton.addActionListener(
      new ActionListener(){
        public void actionPerformed(
                                  ActionEvent e){
          winB.requestFocus();
        }//end actionPerformed
      }//end new ActionListener
    );//end addActionListener

    //Prepare the JFrame to handle events using
    // the low-level process methods.
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);

    //Prepare the JFrame to handle events using
    // the high-level listener methods.
    addWindowFocusListener(new WindowLstnr());
    addWindowStateListener(new WindowLstnr());

    //Make this JFrame visible.  This will steal
    // the focus from the other JFrame.
    setVisible(true);

  }//end constructor
  //-------------------------------------------//

  //The next three methods are low-level event
  // handler methods that are new to V1.4.  These
  // methods are identical to methods having the
  // same names defined for the class named
  // GraphicsGUI, except that the screen output
  // identifies the object as A rather than B.

  //Sample screen output for this method:
  // Low:processWindowEvent A
  // 205 WINDOW_ACTIVATED
  protected void processWindowEvent(
                                  WindowEvent e){
    System.out.println();
    System.out.println(
                     "Low:processWindowEvent A");
    System.out.print(e.getID() + " ");
    System.out.println(getEventType(e.getID()));
    super.processWindowEvent(e);
  }//end processWindowEvent
  //-------------------------------------------//

  //Sample screen output for this method:
  // Low:processWindowFocusEvent A
  // 207 WINDOW_GAINED_FOCUS
  protected void processWindowFocusEvent(
                                  WindowEvent e){
    System.out.println();
    System.out.println(
                "Low:processWindowFocusEvent A");
    System.out.print(e.getID() + " ");
    System.out.println(getEventType(e.getID()));
    super.processWindowFocusEvent(e);
  }//end processWindowFocusEvent
  //-------------------------------------------//

  //Sample screen output for this method:
  // Low:processWindowStateEvent A
  // 209 WINDOW_STATE_CHANGED
  protected void processWindowStateEvent(
                                  WindowEvent e){
    System.out.println();
    System.out.println(
                "Low:processWindowStateEvent A");
    System.out.print(e.getID() + " ");
    System.out.println(getEventType(e.getID()));
    super.processWindowStateEvent(e);
  }//end processWindowStateEvent
  //-------------------------------------------//

  //Method to convert event ID values to text
  // descriptions.
  String getEventType(int ID){
    if(ID == WindowEvent.WINDOW_ACTIVATED){
      return "WINDOW_ACTIVATED";
    }else if(ID == WindowEvent.WINDOW_CLOSED){
      return "WINDOW_CLOSED";
    }else if(ID == WindowEvent.WINDOW_CLOSING){
      return "WINDOW_CLOSING";
    }else if(ID ==
                 WindowEvent.WINDOW_DEACTIVATED){
      return "WINDOW_DEACTIVATED";
    }else if(ID ==
                 WindowEvent.WINDOW_DEICONIFIED){
      return "WINDOW_DEICONIFIED";
    }else if(ID == WindowEvent.WINDOW_ICONIFIED){
      return "WINDOW_ICONIFIED";
    }else if(ID == WindowEvent.WINDOW_OPENED){
      return "WINDOW_OPENED";
    }else if(ID ==
               WindowEvent.WINDOW_STATE_CHANGED){
      return "WINDOW_STATE_CHANGED";
    }else if(ID ==
                WindowEvent.WINDOW_GAINED_FOCUS){
      return "WINDOW_GAINED_FOCUS";
    }else if(ID ==
                  WindowEvent.WINDOW_LOST_FOCUS){
      return "WINDOW_LOST_FOCUS";
    }else{
      return "Unknown event type";
    }//end else
  }//end getEventType

}//end class FocusWindow02
//=============================================//

//Objects of this class are registered on the two
// JButton objects to report high-level
// focusGained and focusLost events.
//Sample outputs from these methods:
// High:focusGained on Regain focus button
// High:focusLost on Regain focus button
// High:focusGained on Send focus to B button
// High:focusLost on Send focus to B button
class FocusLstnr implements FocusListener{

  public void focusGained(FocusEvent e){
    System.out.println("High:focusGained on "
             + ((JButton)e.getSource()).getText()
             + " button");
  }//wns focusGained
  //-------------------------------------------//

  public void focusLost(FocusEvent e){
    System.out.println("High:focusLost on "
             + ((JButton)e.getSource()).getText()
             + " button");
  }//end focusLost
}//end class FocusLstnr

//=============================================//

//Objects of this class are registered on the two
// JFrame objects to report high-level focus and
// state events on the objects.

//Sample outputs from the methods are:
// High:windowGainedFocus A
// High:windowLostFocus A
// High:windowGainedFocus B
// High:windowLostFocus B
// High:windowStateChanged NORMAL to ICONIFIED B
// High:windowStateChanged NORMAL to ICONIFIED A
// High:windowStateChanged ICONIFIED to NORMAL A
// High:windowStateChanged ICONIFIED to NORMAL B

class WindowLstnr implements
         WindowFocusListener,WindowStateListener{
  public void windowGainedFocus(WindowEvent e){
    System.out.print("High:windowGainedFocus ");
    System.out.println(((JFrame)e.getSource()).
                      getTitle().substring(0,1));
  }//end windowGainedFocus

  public void windowLostFocus(WindowEvent e){
    System.out.print("High:windowLostFocus ");
    System.out.println(((JFrame)e.getSource()).
                      getTitle().substring(0,1));
  }//windowLostFocus

  public void windowStateChanged(WindowEvent e){
    System.out.println("High:windowStateChanged "
             + getState(e.getOldState())
             + " to " + getState(e.getNewState())
             + " "
             + ((JFrame)e.getSource()).
                      getTitle().substring(0,1));
  }//windowStateChanged

  //This method converts state values to text
  // descriptions.  See constant values in Frame
  // class for the correlations between state
  // values and descriptive constants.
  String getState(int state){
    if(state == Frame.NORMAL){
      return "NORMAL";
    }else if(state == Frame.ICONIFIED){
      return "ICONIFIED";
    }else if(state == Frame.MAXIMIZED_HORIZ){
      return "MAXIMIZED_HORIZ";
    }else if(state == Frame.MAXIMIZED_VERT){
      return "MAXIMIZED_VERT";
    }else if(state == Frame.MAXIMIZED_BOTH){
      return "MAXIMIZED_BOTH";
    }else{
      return "Unknown state";
    }//end else
  }//end getState
}//end class WindowLstnr
//=============================================//

//An object of this class is instantiated to
// illustrate the use of focus on a Window that
// contains no focusable components.  The
// coordinates of an invisible point are
// displayed on a Canvas in the JFrame near the
// location of the invisible point.  When this
// object has the focus, pressing the arrow keys
// will change the coordinates of the invisible
// point, thus modifying and moving the displayed
// coordinate values.

class GraphicsGUI extends JFrame{

  //These are the coordinates of the invisible
  // point.
  int xCoor = 200;
  int yCoor = 40;

  public GraphicsGUI(){//constructor
    setBounds(0,100,400,100);
    setTitle("B Copyright 2004 R.G.Baldwin");
    Display display = new Display();
    getContentPane().add(display);

    setDefaultCloseOperation(
                           JFrame.EXIT_ON_CLOSE);

    //Prepare this object to handle low-level
    // WindowEvents using the process methods.
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);

    //Prepare this object to handle high-level
    // KeyEvents using a listener.
    this.addKeyListener(new KeyListnr(display));

    //Prepare this object to handle high-level
    // focus and state events using a listener.
    addWindowFocusListener(new WindowLstnr());
    addWindowStateListener(new WindowLstnr());

    setVisible(true);
  }//end constructor
  //-------------------------------------------//

  //The next three methods are low-level event
  // handler methods that are new to V1.4.  These
  // methods are identical to methods having the
  // same names defined for the class named
  // FocusWindow02, except that the screen output
  // identifies the object as B rather than A.

  //Sample screen output for this method:
  // Low:processWindowEvent B
  // 205 WINDOW_ACTIVATED
  protected void processWindowEvent(
                                  WindowEvent e){
    System.out.println();
    System.out.println(
                     "Low:processWindowEvent B");
    System.out.print(e.getID() + " ");
    System.out.println(getEventType(e.getID()));
    super.processWindowEvent(e);
  }//end processWindowEvent
  //-------------------------------------------//

  //Sample screen output for this method:
  // Low:processWindowFocusEvent B
  // 207 WINDOW_GAINED_FOCUS
  protected void processWindowFocusEvent(
                                  WindowEvent e){
    System.out.println();
    System.out.println(
                "Low:processWindowFocusEvent B");
    System.out.print(e.getID() + " ");
    System.out.println(getEventType(e.getID()));
    super.processWindowFocusEvent(e);
  }//end processWindowFocusEvent
  //-------------------------------------------//

  //Sample screen output for this method:
  // Low:processWindowStateEvent B
  // 209 WINDOW_STATE_CHANGED
  protected void processWindowStateEvent(
                                  WindowEvent e){
    System.out.println();
    System.out.println(
                "Low:processWindowStateEvent B");
    System.out.print(e.getID() + " ");
    System.out.println(getEventType(e.getID()));
    super.processWindowStateEvent(e);
  }//end processWindowStateEvent
  //-------------------------------------------//

  //Method to convert event ID values to text
  // descriptions.
  String getEventType(int ID){
    if(ID == WindowEvent.WINDOW_ACTIVATED){
      return "WINDOW_ACTIVATED";
    }else if(ID == WindowEvent.WINDOW_CLOSED){
      return "WINDOW_CLOSED";
    }else if(ID == WindowEvent.WINDOW_CLOSING){
      return "WINDOW_CLOSING";
    }else if(ID ==
                 WindowEvent.WINDOW_DEACTIVATED){
      return "WINDOW_DEACTIVATED";
    }else if(ID ==
                 WindowEvent.WINDOW_DEICONIFIED){
      return "WINDOW_DEICONIFIED";
    }else if(ID == WindowEvent.WINDOW_ICONIFIED){
      return "WINDOW_ICONIFIED";
    }else if(ID == WindowEvent.WINDOW_OPENED){
      return "WINDOW_OPENED";
    }else if(ID ==
               WindowEvent.WINDOW_STATE_CHANGED){
      return "WINDOW_STATE_CHANGED";
    }else if(ID ==
                WindowEvent.WINDOW_GAINED_FOCUS){
      return "WINDOW_GAINED_FOCUS";
    }else if(ID ==
                  WindowEvent.WINDOW_LOST_FOCUS){
      return "WINDOW_LOST_FOCUS";
    }else{
      return "Unknown event type";
    }//end else
  }//end getEventType
//=============================================//

//Begin inner class definitions

class Display extends Canvas{

  Display(){//constructor
    //Set the focusable property to false to
    // guarantee that the JFrame contains no
    // focusable components.
    setFocusable(false);
  }//end constructor

  //Override the paint method to display the
  // coordinates on the screen near the location
  // specified by the coordinates.
  public void paint(Graphics g){
    super.paint(g);
    g.drawString(
        "" + xCoor + ", " + yCoor, xCoor, yCoor);
  }//end paint()
}//end class Display
//=============================================//

//This listener class monitors for key events,
// increments and displays the stored coordinates
// when the arrow keys are pressed.
class KeyListnr extends KeyAdapter{
  Display display;

  KeyListnr(Display display){//constructor
    this.display = display;//save ref to display
  }//end constructor
  //-------------------------------------------//

  //Override the keyPressed method to increment
  // or decrement the coordinates by five pixels
  // when an arrow key is pressed.  Then repaint
  // the canvas to cause the coordinate values to
  // be displayed. Remember y-coordinates are
  // displayed upside down.
  public void keyPressed(KeyEvent e){
    int code = e.getKeyCode();

    if(code == e.VK_UP){
      yCoor -= 5;
    }else if(code == e.VK_LEFT){
      xCoor -= 5;
    }else if(code == e.VK_RIGHT){
      xCoor += 5;
    }else if(code == e.VK_DOWN){
      yCoor += 5;
    }//end else if

    display.repaint();//Display coordinates
  }//end keyPressed()
}//end class KeyListnr
//=============================================//
}//end GraphicsGUI class
//=============================================//

Listing 1


Copyright 2005, 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.

In addition to his programming expertise, Richard has many years of
practical experience in Digital Signal Processing (DSP).  His first
job after he earned his Bachelor’s degree was doing DSP in the Seismic Research
Department of Texas Instruments.  (TI is still a world leader in DSP.) 
In the following years, he applied his programming and DSP expertise to other
interesting areas including sonar and underwater acoustics.

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-

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories