001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.user.client;
017:
018: import com.google.gwt.core.client.GWT;
019: import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
020:
021: import java.util.ArrayList;
022:
023: /**
024: * This class provides access to the browser window's methods, properties, and
025: * events.
026: */
027: public class Window {
028:
029: private static boolean handlersAreInitialized;
030: private static ArrayList<WindowCloseListener> closingListeners;
031: private static ArrayList<WindowResizeListener> resizeListeners;
032:
033: /**
034: * Adds a listener to receive window closing events.
035: *
036: * @param listener the listener to be informed when the window is closing
037: */
038: public static void addWindowCloseListener(
039: WindowCloseListener listener) {
040: maybeInitializeHandlers();
041: if (closingListeners == null) {
042: closingListeners = new ArrayList<WindowCloseListener>();
043: }
044: closingListeners.add(listener);
045: }
046:
047: /**
048: * Adds a listener to receive window resize events.
049: *
050: * @param listener the listener to be informed when the window is resized
051: */
052: public static void addWindowResizeListener(
053: WindowResizeListener listener) {
054: maybeInitializeHandlers();
055: if (resizeListeners == null) {
056: resizeListeners = new ArrayList<WindowResizeListener>();
057: }
058: resizeListeners.add(listener);
059: }
060:
061: /**
062: * Displays a message in a modal dialog box.
063: *
064: * @param msg the message to be displayed.
065: */
066: public static native void alert(String msg) /*-{
067: $wnd.alert(msg);
068: }-*/;
069:
070: /**
071: * Displays a message in a modal dialog box, along with the standard 'OK' and
072: * 'Cancel' buttons.
073: *
074: * @param msg the message to be displayed.
075: * @return <code>true</code> if 'OK' is clicked, <code>false</code> if
076: * 'Cancel' is clicked.
077: */
078: public static native boolean confirm(String msg) /*-{
079: return $wnd.confirm(msg);
080: }-*/;
081:
082: /**
083: * Use this method to explicitly disable the window's scrollbars. Applications
084: * that choose to resize their user-interfaces to fit within the window's
085: * client area will normally want to disable window scrolling.
086: *
087: * @param enable <code>false</code> to disable window scrolling
088: */
089: public static native void enableScrolling(boolean enable) /*-{
090: $doc.body.style.overflow = enable ? 'auto' : 'hidden';
091: }-*/;
092:
093: /**
094: * Gets the height of the browser window's client area excluding the
095: * scroll bar.
096: *
097: * @return the window's client height
098: */
099: public static int getClientHeight() {
100: return DOM.windowGetClientHeight();
101: }
102:
103: /**
104: * Gets the width of the browser window's client area excluding the
105: * vertical scroll bar.
106: *
107: * @return the window's client width
108: */
109: public static int getClientWidth() {
110: return DOM.windowGetClientWidth();
111: }
112:
113: /**
114: * Gets the window's scroll left.
115: *
116: * @return window's scroll left
117: */
118: public static native int getScrollLeft() /*-{
119: // Standard mode || Quirks mode.
120: return $doc.documentElement.scrollLeft || $doc.body.scrollLeft
121: }-*/;
122:
123: /**
124: * Get the window's scroll top.
125: *
126: * @return the window's scroll top
127: */
128: public static native int getScrollTop() /*-{
129: // Standard mode || Quirks mode.
130: return $doc.documentElement.scrollTop || $doc.body.scrollTop;
131: }-*/;
132:
133: /**
134: * Gets the browser window's current title.
135: *
136: * @return the window's title.
137: */
138: public static native String getTitle() /*-{
139: return $doc.title;
140: }-*/;
141:
142: /**
143: * Opens a new browser window. The "name" and "features" arguments are
144: * specified <a href=
145: * 'http://www.mozilla.org/docs/dom/domref/dom_window_ref76.html'>here</a>.
146: *
147: * @param url the URL that the new window will display
148: * @param name the name of the window (e.g. "_blank")
149: * @param features the features to be enabled/disabled on this window
150: */
151: public static native void open(String url, String name,
152: String features) /*-{
153: $wnd.open(url, name, features);
154: }-*/;
155:
156: /**
157: * Prints the document in the window, as if the user had issued a "Print"
158: * command.
159: */
160: public static native void print() /*-{
161: $wnd.print();
162: }-*/;
163:
164: /**
165: * Displays a request for information in a modal dialog box, along with the
166: * standard 'OK' and 'Cancel' buttons.
167: *
168: * @param msg the message to be displayed
169: * @param initialValue the initial value in the dialog's text field
170: * @return the value entered by the user if 'OK' was pressed, or
171: * <code>null</code> if 'Cancel' was pressed
172: */
173: public static native String prompt(String msg, String initialValue) /*-{
174: return $wnd.prompt(msg, initialValue);
175: }-*/;
176:
177: /**
178: * Removes a window closing listener.
179: *
180: * @param listener the listener to be removed
181: */
182: public static void removeWindowCloseListener(
183: WindowCloseListener listener) {
184: if (closingListeners != null) {
185: closingListeners.remove(listener);
186: }
187: }
188:
189: /**
190: * Removes a window resize listener.
191: *
192: * @param listener the listener to be removed
193: */
194: public static void removeWindowResizeListener(
195: WindowResizeListener listener) {
196: if (resizeListeners != null) {
197: resizeListeners.remove(listener);
198: }
199: }
200:
201: /**
202: * Sets the size of the margins used within the window's client area. It is
203: * sometimes necessary to do this because some browsers, such as Internet
204: * Explorer, add margins by default, which can confound attempts to resize
205: * panels to fit exactly within the window.
206: *
207: * @param size the window's new margin size, in CSS units.
208: */
209: public static native void setMargin(String size) /*-{
210: $doc.body.style.margin = size;
211: }-*/;
212:
213: /**
214: * Sets the status text for the window. Calling this method in Firefox
215: * has no effect.
216: *
217: * @param status the new message to display.
218: */
219: public static native void setStatus(String status) /*-{
220: $wnd.status = status;
221: }-*/;
222:
223: /**
224: * Sets the browser window's title.
225: *
226: * @param title the new window title.
227: */
228: public static native void setTitle(String title) /*-{
229: $doc.title = title;
230: }-*/;
231:
232: static void onClosed() {
233: UncaughtExceptionHandler handler = GWT
234: .getUncaughtExceptionHandler();
235: if (handler != null) {
236: fireClosedAndCatch(handler);
237: } else {
238: fireClosedImpl();
239: }
240: }
241:
242: static String onClosing() {
243: UncaughtExceptionHandler handler = GWT
244: .getUncaughtExceptionHandler();
245: if (handler != null) {
246: return fireClosingAndCatch(handler);
247: } else {
248: return fireClosingImpl();
249: }
250: }
251:
252: static void onResize() {
253: UncaughtExceptionHandler handler = GWT
254: .getUncaughtExceptionHandler();
255: if (handler != null) {
256: fireResizedAndCatch(handler);
257: } else {
258: fireResizedImpl();
259: }
260: }
261:
262: private static void fireClosedAndCatch(
263: UncaughtExceptionHandler handler) {
264: try {
265: fireClosedImpl();
266: } catch (Throwable e) {
267: handler.onUncaughtException(e);
268: }
269: }
270:
271: private static void fireClosedImpl() {
272: if (closingListeners != null) {
273: for (WindowCloseListener listener : closingListeners) {
274: listener.onWindowClosed();
275: }
276: }
277: }
278:
279: private static String fireClosingAndCatch(
280: UncaughtExceptionHandler handler) {
281: try {
282: return fireClosingImpl();
283: } catch (Throwable e) {
284: handler.onUncaughtException(e);
285: return null;
286: }
287: }
288:
289: private static String fireClosingImpl() {
290: String ret = null;
291: if (closingListeners != null) {
292: for (WindowCloseListener listener : closingListeners) {
293: // If any listener wants to suppress the window closing event, then do so.
294: String msg = listener.onWindowClosing();
295: if (ret == null) {
296: ret = msg;
297: }
298: }
299: }
300:
301: return ret;
302: }
303:
304: private static void fireResizedAndCatch(
305: UncaughtExceptionHandler handler) {
306: try {
307: fireResizedImpl();
308: } catch (Throwable e) {
309: handler.onUncaughtException(e);
310: }
311: }
312:
313: private static void fireResizedImpl() {
314: if (resizeListeners != null) {
315: for (WindowResizeListener listener : resizeListeners) {
316: listener.onWindowResized(getClientWidth(),
317: getClientHeight());
318: }
319: }
320: }
321:
322: private static native void init() /*-{
323: // Magic function defined by the selection script.
324: __gwt_initHandlers(
325: function() {
326: @com.google.gwt.user.client.Window::onResize()();
327: },
328: function() {
329: return @com.google.gwt.user.client.Window::onClosing()();
330: },
331: function() {
332: @com.google.gwt.user.client.Window::onClosed()();
333: $wnd.onresize = null;
334: $wnd.onbeforeclose = null;
335: $wnd.onclose = null;
336: }
337: );
338: }-*/;
339:
340: private static void maybeInitializeHandlers() {
341: if (!handlersAreInitialized) {
342: init();
343: handlersAreInitialized = true;
344: }
345: }
346:
347: private Window() {
348: }
349: }
|