1/*
2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.awt.event;
27
28import java.awt.Window;
29import java.lang.annotation.Native;
30import sun.awt.AppContext;
31import sun.awt.SunToolkit;
32
33/**
34 * A low-level event that indicates that a window has changed its status. This
35 * low-level event is generated by a Window object when it is opened, closed,
36 * activated, deactivated, iconified, or deiconified, or when focus is
37 * transferred into or out of the Window.
38 * <P>
39 * The event is passed to every {@code WindowListener}
40 * or {@code WindowAdapter} object which registered to receive such
41 * events using the window's {@code addWindowListener} method.
42 * ({@code WindowAdapter} objects implement the
43 * {@code WindowListener} interface.) Each such listener object
44 * gets this {@code WindowEvent} when the event occurs.
45 * <p>
46 * An unspecified behavior will be caused if the {@code id} parameter
47 * of any particular {@code WindowEvent} instance is not
48 * in the range from {@code WINDOW_FIRST} to {@code WINDOW_LAST}.
49 *
50 * @author Carl Quinn
51 * @author Amy Fowler
52 *
53 * @see WindowAdapter
54 * @see WindowListener
55 * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a>
56 *
57 * @since 1.1
58 */
59public class WindowEvent extends ComponentEvent {
60
61    /**
62     * The first number in the range of ids used for window events.
63     */
64    public static final int WINDOW_FIRST        = 200;
65
66    /**
67     * The window opened event.  This event is delivered only
68     * the first time a window is made visible.
69     */
70    @Native public static final int WINDOW_OPENED       = WINDOW_FIRST; // 200
71
72    /**
73     * The "window is closing" event. This event is delivered when
74     * the user attempts to close the window from the window's system menu.
75     * If the program does not explicitly hide or dispose the window
76     * while processing this event, the window close operation will be
77     * cancelled.
78     */
79    @Native public static final int WINDOW_CLOSING      = 1 + WINDOW_FIRST; //Event.WINDOW_DESTROY
80
81    /**
82     * The window closed event. This event is delivered after the displayable
83     * window has been closed as the result of a call to dispose.
84     * @see java.awt.Component#isDisplayable
85     * @see Window#dispose
86     */
87    @Native public static final int WINDOW_CLOSED       = 2 + WINDOW_FIRST;
88
89    /**
90     * The window iconified event. This event is delivered when
91     * the window has been changed from a normal to a minimized state.
92     * For many platforms, a minimized window is displayed as
93     * the icon specified in the window's iconImage property.
94     * @see java.awt.Frame#setIconImage
95     */
96    @Native public static final int WINDOW_ICONIFIED    = 3 + WINDOW_FIRST; //Event.WINDOW_ICONIFY
97
98    /**
99     * The window deiconified event type. This event is delivered when
100     * the window has been changed from a minimized to a normal state.
101     */
102    @Native public static final int WINDOW_DEICONIFIED  = 4 + WINDOW_FIRST; //Event.WINDOW_DEICONIFY
103
104    /**
105     * The window-activated event type. This event is delivered when the Window
106     * becomes the active Window. Only a Frame or a Dialog can be the active
107     * Window. The native windowing system may denote the active Window or its
108     * children with special decorations, such as a highlighted title bar. The
109     * active Window is always either the focused Window, or the first Frame or
110     * Dialog that is an owner of the focused Window.
111     */
112    @Native public static final int WINDOW_ACTIVATED    = 5 + WINDOW_FIRST;
113
114    /**
115     * The window-deactivated event type. This event is delivered when the
116     * Window is no longer the active Window. Only a Frame or a Dialog can be
117     * the active Window. The native windowing system may denote the active
118     * Window or its children with special decorations, such as a highlighted
119     * title bar. The active Window is always either the focused Window, or the
120     * first Frame or Dialog that is an owner of the focused Window.
121     */
122    @Native public static final int WINDOW_DEACTIVATED  = 6 + WINDOW_FIRST;
123
124    /**
125     * The window-gained-focus event type. This event is delivered when the
126     * Window becomes the focused Window, which means that the Window, or one
127     * of its subcomponents, will receive keyboard events.
128     */
129    @Native public static final int WINDOW_GAINED_FOCUS = 7 + WINDOW_FIRST;
130
131    /**
132     * The window-lost-focus event type. This event is delivered when a Window
133     * is no longer the focused Window, which means keyboard events will no
134     * longer be delivered to the Window or any of its subcomponents.
135     */
136    @Native public static final int WINDOW_LOST_FOCUS   = 8 + WINDOW_FIRST;
137
138    /**
139     * The window-state-changed event type.  This event is delivered
140     * when a Window's state is changed by virtue of it being
141     * iconified, maximized etc.
142     * @since 1.4
143     */
144    @Native public static final int WINDOW_STATE_CHANGED = 9 + WINDOW_FIRST;
145
146    /**
147     * The last number in the range of ids used for window events.
148     */
149    public static final int WINDOW_LAST         = WINDOW_STATE_CHANGED;
150
151    /**
152     * The other Window involved in this focus or activation change. For a
153     * WINDOW_ACTIVATED or WINDOW_GAINED_FOCUS event, this is the Window that
154     * lost activation or focus. For a WINDOW_DEACTIVATED or WINDOW_LOST_FOCUS
155     * event, this is the Window that gained activation or focus. For any other
156     * type of WindowEvent, or if the focus or activation change occurs with a
157     * native application, a Java application in a different VM, or with no
158     * other Window, null is returned.
159     *
160     * @see #getOppositeWindow
161     * @since 1.4
162     */
163    transient Window opposite;
164
165    /**
166     * TBS
167     */
168    int oldState;
169    int newState;
170
171
172    /*
173     * JDK 1.1 serialVersionUID
174     */
175    private static final long serialVersionUID = -1567959133147912127L;
176
177
178    /**
179     * Constructs a {@code WindowEvent} object.
180     * <p>This method throws an
181     * {@code IllegalArgumentException} if {@code source}
182     * is {@code null}.
183     *
184     * @param source    The {@code Window} object
185     *                    that originated the event
186     * @param id        An integer indicating the type of event.
187     *                     For information on allowable values, see
188     *                     the class description for {@link WindowEvent}
189     * @param opposite  The other window involved in the focus or activation
190     *                      change, or {@code null}
191     * @param oldState  Previous state of the window for window state change event.
192     *                  See {@code #getOldState()} for allowable values
193     * @param newState  New state of the window for window state change event.
194     *                  See {@code #getNewState()} for allowable values
195     * @throws IllegalArgumentException if {@code source} is null
196     * @see #getWindow()
197     * @see #getID()
198     * @see #getOppositeWindow()
199     * @see #getOldState()
200     * @see #getNewState()
201     * @since 1.4
202     */
203    public WindowEvent(Window source, int id, Window opposite,
204                       int oldState, int newState)
205    {
206        super(source, id);
207        this.opposite = opposite;
208        this.oldState = oldState;
209        this.newState = newState;
210    }
211
212    /**
213     * Constructs a {@code WindowEvent} object with the
214     * specified opposite {@code Window}. The opposite
215     * {@code Window} is the other {@code Window}
216     * involved in this focus or activation change.
217     * For a {@code WINDOW_ACTIVATED} or
218     * {@code WINDOW_GAINED_FOCUS} event, this is the
219     * {@code Window} that lost activation or focus.
220     * For a {@code WINDOW_DEACTIVATED} or
221     * {@code WINDOW_LOST_FOCUS} event, this is the
222     * {@code Window} that gained activation or focus.
223     * If this focus change occurs with a native application, with a
224     * Java application in a different VM, or with no other
225     * {@code Window}, then the opposite Window is {@code null}.
226     * <p>This method throws an
227     * {@code IllegalArgumentException} if {@code source}
228     * is {@code null}.
229     *
230     * @param source     The {@code Window} object that
231     *                   originated the event
232     * @param id        An integer indicating the type of event.
233     *                     For information on allowable values, see
234     *                     the class description for {@link WindowEvent}.
235     *                  It is expected that this constructor will not
236     *                  be used for other then
237     *                  {@code WINDOW_ACTIVATED},{@code WINDOW_DEACTIVATED},
238     *                  {@code WINDOW_GAINED_FOCUS}, or {@code WINDOW_LOST_FOCUS}.
239     *                  {@code WindowEvent} types,
240     *                  because the opposite {@code Window} of other event types
241     *                  will always be {@code null}.
242     * @param opposite   The other {@code Window} involved in the
243     *                   focus or activation change, or {@code null}
244     * @throws IllegalArgumentException if {@code source} is null
245     * @see #getWindow()
246     * @see #getID()
247     * @see #getOppositeWindow()
248     * @since 1.4
249     */
250    public WindowEvent(Window source, int id, Window opposite) {
251        this(source, id, opposite, 0, 0);
252    }
253
254    /**
255     * Constructs a {@code WindowEvent} object with the specified
256     * previous and new window states.
257     * <p>This method throws an
258     * {@code IllegalArgumentException} if {@code source}
259     * is {@code null}.
260     *
261     * @param source    The {@code Window} object
262     *                  that originated the event
263     * @param id        An integer indicating the type of event.
264     *                     For information on allowable values, see
265     *                     the class description for {@link WindowEvent}.
266     *                  It is expected that this constructor will not
267     *                  be used for other then
268     *                  {@code WINDOW_STATE_CHANGED}
269     *                  {@code WindowEvent}
270     *                  types, because the previous and new window
271     *                  states are meaningless for other event types.
272     * @param oldState  An integer representing the previous window state.
273     *                  See {@code #getOldState()} for allowable values
274     * @param newState  An integer representing the new window state.
275     *                  See {@code #getNewState()} for allowable values
276     * @throws IllegalArgumentException if {@code source} is null
277     * @see #getWindow()
278     * @see #getID()
279     * @see #getOldState()
280     * @see #getNewState()
281     * @since 1.4
282     */
283    public WindowEvent(Window source, int id, int oldState, int newState) {
284        this(source, id, null, oldState, newState);
285    }
286
287    /**
288     * Constructs a {@code WindowEvent} object.
289     * <p>This method throws an
290     * {@code IllegalArgumentException} if {@code source}
291     * is {@code null}.
292     *
293     * @param source The {@code Window} object that originated the event
294     * @param id     An integer indicating the type of event.
295     *                     For information on allowable values, see
296     *                     the class description for {@link WindowEvent}.
297     * @throws IllegalArgumentException if {@code source} is null
298     * @see #getWindow()
299     * @see #getID()
300     */
301    public WindowEvent(Window source, int id) {
302        this(source, id, null, 0, 0);
303    }
304
305    /**
306     * Returns the originator of the event.
307     *
308     * @return the Window object that originated the event
309     */
310    public Window getWindow() {
311        return (source instanceof Window) ? (Window)source : null;
312    }
313
314    /**
315     * Returns the other Window involved in this focus or activation change.
316     * For a WINDOW_ACTIVATED or WINDOW_GAINED_FOCUS event, this is the Window
317     * that lost activation or focus. For a WINDOW_DEACTIVATED or
318     * WINDOW_LOST_FOCUS event, this is the Window that gained activation or
319     * focus. For any other type of WindowEvent, or if the focus or activation
320     * change occurs with a native application, with a Java application in a
321     * different VM or context, or with no other Window, null is returned.
322     *
323     * @return the other Window involved in the focus or activation change, or
324     *         null
325     * @since 1.4
326     */
327    public Window getOppositeWindow() {
328        if (opposite == null) {
329            return null;
330        }
331
332        return (SunToolkit.targetToAppContext(opposite) ==
333                AppContext.getAppContext())
334            ? opposite
335            : null;
336    }
337
338    /**
339     * For {@code WINDOW_STATE_CHANGED} events returns the
340     * previous state of the window. The state is
341     * represented as a bitwise mask.
342     * <ul>
343     * <li>{@code NORMAL}
344     * <br>Indicates that no state bits are set.
345     * <li>{@code ICONIFIED}
346     * <li>{@code MAXIMIZED_HORIZ}
347     * <li>{@code MAXIMIZED_VERT}
348     * <li>{@code MAXIMIZED_BOTH}
349     * <br>Concatenates {@code MAXIMIZED_HORIZ}
350     * and {@code MAXIMIZED_VERT}.
351     * </ul>
352     *
353     * @return a bitwise mask of the previous window state
354     * @see java.awt.Frame#getExtendedState()
355     * @since 1.4
356     */
357    public int getOldState() {
358        return oldState;
359    }
360
361    /**
362     * For {@code WINDOW_STATE_CHANGED} events returns the
363     * new state of the window. The state is
364     * represented as a bitwise mask.
365     * <ul>
366     * <li>{@code NORMAL}
367     * <br>Indicates that no state bits are set.
368     * <li>{@code ICONIFIED}
369     * <li>{@code MAXIMIZED_HORIZ}
370     * <li>{@code MAXIMIZED_VERT}
371     * <li>{@code MAXIMIZED_BOTH}
372     * <br>Concatenates {@code MAXIMIZED_HORIZ}
373     * and {@code MAXIMIZED_VERT}.
374     * </ul>
375     *
376     * @return a bitwise mask of the new window state
377     * @see java.awt.Frame#getExtendedState()
378     * @since 1.4
379     */
380    public int getNewState() {
381        return newState;
382    }
383
384    /**
385     * Returns a parameter string identifying this event.
386     * This method is useful for event-logging and for debugging.
387     *
388     * @return a string identifying the event and its attributes
389     */
390    public String paramString() {
391        String typeStr;
392        switch(id) {
393          case WINDOW_OPENED:
394              typeStr = "WINDOW_OPENED";
395              break;
396          case WINDOW_CLOSING:
397              typeStr = "WINDOW_CLOSING";
398              break;
399          case WINDOW_CLOSED:
400              typeStr = "WINDOW_CLOSED";
401              break;
402          case WINDOW_ICONIFIED:
403              typeStr = "WINDOW_ICONIFIED";
404              break;
405          case WINDOW_DEICONIFIED:
406              typeStr = "WINDOW_DEICONIFIED";
407              break;
408          case WINDOW_ACTIVATED:
409              typeStr = "WINDOW_ACTIVATED";
410              break;
411          case WINDOW_DEACTIVATED:
412              typeStr = "WINDOW_DEACTIVATED";
413              break;
414          case WINDOW_GAINED_FOCUS:
415              typeStr = "WINDOW_GAINED_FOCUS";
416              break;
417          case WINDOW_LOST_FOCUS:
418              typeStr = "WINDOW_LOST_FOCUS";
419              break;
420          case WINDOW_STATE_CHANGED:
421              typeStr = "WINDOW_STATE_CHANGED";
422              break;
423          default:
424              typeStr = "unknown type";
425        }
426        typeStr += ",opposite=" + getOppositeWindow()
427            + ",oldState=" + oldState + ",newState=" + newState;
428
429        return typeStr;
430    }
431}
432