Window Focus and State in Java

Posted by 겨울에
2011. 7. 6. 13:10 scrap/ Java/JSP
출처 : http://www.developer.com/java/other/article.php/3502181



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 Windowstate.

(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 ofWindow 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 FrameJFrameDialog, 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 FrameJFrameDialog, 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 thegetExtendedState 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 withWindow 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 theWindow 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

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 aWindow, because Window is the superclass of these other classes.) 

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 JFrameobject.

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 getStatemethod 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 typeWindowEvent.
  • 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 namedWINDOW_GAINED_FOCUSWINDOW_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 andgetNewState were also defined.
  • The Window class was upgraded to add two new methods named processWindowFocusEventand processWindowStateEvent.  These two methods are required to support low-level focusand state event handling on the Window in conjunction with the enableEvents method.  Four new registration methods named addWindowFocusListenerremoveWindowFocusListener,addWindowStateListener, and removeWindowStateListener were added to the Windowclass to support high-level event registration and handling of the new focus and state event types.  Finally, several new utility methods such as getWindowFocusListeners,getWindowStateListenersisFocusableWindowgetFocusableWindowState,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 activeWindow, 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 theJFrame 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 Bin 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 typesWindowFocusListener 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 andWindow 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 theWindow 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 aFrame 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 namedConstant 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 theCanvas object. In that case, the coordinate values are drawn directly on the Frame. Since the Framedoesn'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 FrameDialog, and JDialog objects instead of JFrameobjects.  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-

 

'scrap >  Java/JSP' 카테고리의 다른 글

[JAVA] File과 Directory 접근  (0) 2011.07.07
java - system 정보 가져오기  (3) 2011.07.05
JAVA - 자바로 프로세스 관리  (0) 2011.07.04
urlconnection 기능확장으로 편리하게 사용하기  (0) 2011.06.27
파싱?.?  (0) 2011.06.27