Window Focus and State in Java
Java Programming, Notes # 1857
- Preface
- Background Information
- Preview
- Description of the Program
- Run the Program
- Summary
- What's Next
- Complete Program Listing
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 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 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
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 aWindow, 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 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_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 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 addWindowFocusListener, removeWindowFocusListener,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,getWindowStateListeners, isFocusableWindow, getFocusableWindowState,setFocusableWindowState, and isFocused were added to the Window class to support the new event types.
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.
|
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.)
|
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 Frame, Dialog, 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.
-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 |