001: /*
002: * Copyright 2005 Joe Walker
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of 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,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package jsx3.gui;
017:
018: import org.directwebremoting.ScriptBuffer;
019: import org.directwebremoting.proxy.ScriptProxy;
020: import org.directwebremoting.proxy.io.Context;
021:
022: /**
023: * Allows for rendering a branch of the DOM of an application in a separate browser window.
024:
025: Access instances of this class with the following methods in the jsx3.app.Server class:
026:
027: createAppWindow()
028: getAppWindow()
029: loadAppWindow()
030: * @author Joe Walker [joe at getahead dot org]
031: * @author DRAPGEN - Dwr Reverse Ajax Proxy GENerator
032: */
033: public class Window extends jsx3.app.Model {
034: /**
035: * All reverse ajax proxies need context to work from
036: * @param scriptProxy The place we are writing scripts to
037: * @param context The script that got us to where we are now
038: */
039: public Window(Context context, String extension,
040: ScriptProxy scriptProxy) {
041: super (context, extension, scriptProxy);
042: }
043:
044: /**
045: * The instance initializer.
046: * @param strName a unique name for this window.
047: */
048: public Window(String strName) {
049: super ((Context) null, (String) null, (ScriptProxy) null);
050: ScriptBuffer script = new ScriptBuffer();
051: script.appendCall("new Window", strName);
052: setInitScript(script);
053: }
054:
055: /**
056: * Event subject: published after this window has successfully opened.
057: */
058: public static final String DID_OPEN = "open";
059:
060: /**
061: * Event subject: published just before this window will close.
062: */
063: public static final String WILL_CLOSE = "close";
064:
065: /**
066: * Event subject: published after this window has received focus.
067: */
068: public static final String DID_FOCUS = "focus";
069:
070: /**
071: * Event subject: published after this window has been resized via user interaction.
072: */
073: public static final String DID_RESIZE = "resize";
074:
075: /**
076: * Event subject: published after this window's parent has closed.
077: */
078: public static final String PARENT_DID_CLOSE = "pclose";
079:
080: /**
081: * Opens the browser window of this window instance. Depending on security settings and popup blockers,
082: this method may or may not actually open a window. The only safe way to determine whether the window
083: successfully opened is to register for the DID_OPEN event.
084: * @param callback <code>true</code> if the window successfully opened (probably).
085: */
086: @SuppressWarnings("unchecked")
087: public void open(
088: org.directwebremoting.proxy.Callback<Boolean> callback) {
089: ScriptBuffer script = new ScriptBuffer();
090: String callbackPrefix = "";
091:
092: if (callback != null) {
093: callbackPrefix = "var reply = ";
094: }
095:
096: script.appendCall(callbackPrefix + getContextPath() + "open");
097:
098: if (callback != null) {
099: String key = org.directwebremoting.extend.CallbackHelper
100: .saveCallback(callback, Boolean.class);
101: script
102: .appendCall("__System.activateCallback", key,
103: "reply");
104: }
105:
106: getScriptProxy().addScript(script);
107: }
108:
109: /**
110: * Closes the browser window of this window instance.
111: * @param callback <code>true</code> if the window successfully closed or <code>false</code> if it didn't close
112: because of JavaScript security constraints or user interaction.
113: */
114: @SuppressWarnings("unchecked")
115: public void close(
116: org.directwebremoting.proxy.Callback<Boolean> callback) {
117: ScriptBuffer script = new ScriptBuffer();
118: String callbackPrefix = "";
119:
120: if (callback != null) {
121: callbackPrefix = "var reply = ";
122: }
123:
124: script.appendCall(callbackPrefix + getContextPath() + "close");
125:
126: if (callback != null) {
127: String key = org.directwebremoting.extend.CallbackHelper
128: .saveCallback(callback, Boolean.class);
129: script
130: .appendCall("__System.activateCallback", key,
131: "reply");
132: }
133:
134: getScriptProxy().addScript(script);
135: }
136:
137: /**
138: * Focuses the browser window of this window instance.
139: */
140: public void focus() {
141: ScriptBuffer script = new ScriptBuffer();
142: script.appendCall(getContextPath() + "focus");
143: getScriptProxy().addScript(script);
144: }
145:
146: /**
147: * Returns whether the browser window of this window instance is open.
148: * @param callback <code>true</code> if the window is open.
149: */
150: @SuppressWarnings("unchecked")
151: public void isOpen(
152: org.directwebremoting.proxy.Callback<Boolean> callback) {
153: ScriptBuffer script = new ScriptBuffer();
154: String callbackPrefix = "";
155:
156: if (callback != null) {
157: callbackPrefix = "var reply = ";
158: }
159:
160: script.appendCall(callbackPrefix + getContextPath() + "isOpen");
161:
162: if (callback != null) {
163: String key = org.directwebremoting.extend.CallbackHelper
164: .saveCallback(callback, Boolean.class);
165: script
166: .appendCall("__System.activateCallback", key,
167: "reply");
168: }
169:
170: getScriptProxy().addScript(script);
171: }
172:
173: /**
174: * Returns whether the parent application window of this window instance is open.
175: * @param callback <code>true</code> if the parent window is open.
176: */
177: @SuppressWarnings("unchecked")
178: public void isParentOpen(
179: org.directwebremoting.proxy.Callback<Boolean> callback) {
180: ScriptBuffer script = new ScriptBuffer();
181: String callbackPrefix = "";
182:
183: if (callback != null) {
184: callbackPrefix = "var reply = ";
185: }
186:
187: script.appendCall(callbackPrefix + getContextPath()
188: + "isParentOpen");
189:
190: if (callback != null) {
191: String key = org.directwebremoting.extend.CallbackHelper
192: .saveCallback(callback, Boolean.class);
193: script
194: .appendCall("__System.activateCallback", key,
195: "reply");
196: }
197:
198: getScriptProxy().addScript(script);
199: }
200:
201: /**
202: * Moves the browser window of this window instance to a position on the screen. The arguments specify the
203: offset from the parent application window. If the parent window is no longer open, this window will be moved
204: relative to the upper-left corner of the screen.
205: * @param intOffsetLeft the left offset from the parent window.
206: * @param intOffsetTop the top offset from the parent window.
207: */
208: public void moveTo(int intOffsetLeft, int intOffsetTop) {
209: ScriptBuffer script = new ScriptBuffer();
210: script.appendCall(getContextPath() + "moveTo", intOffsetLeft,
211: intOffsetTop);
212: getScriptProxy().addScript(script);
213: }
214:
215: /**
216: * Ensures that this window is at least partially visible on the computer screen.
217: */
218: public void constrainToScreen() {
219: ScriptBuffer script = new ScriptBuffer();
220: script.appendCall(getContextPath() + "constrainToScreen");
221: getScriptProxy().addScript(script);
222: }
223:
224: /**
225: * Returns the current x-coordinate screen position of this browser window relative to the parent application window.
226: If the parent window is no longer open, this method returns the position relative to the upper-left
227: corner of the screen.
228: */
229: @SuppressWarnings("unchecked")
230: public void getOffsetLeft(
231: org.directwebremoting.proxy.Callback<Integer> callback) {
232: ScriptBuffer script = new ScriptBuffer();
233: String callbackPrefix = "";
234:
235: if (callback != null) {
236: callbackPrefix = "var reply = ";
237: }
238:
239: script.appendCall(callbackPrefix + getContextPath()
240: + "getOffsetLeft");
241:
242: if (callback != null) {
243: String key = org.directwebremoting.extend.CallbackHelper
244: .saveCallback(callback, Integer.class);
245: script
246: .appendCall("__System.activateCallback", key,
247: "reply");
248: }
249:
250: getScriptProxy().addScript(script);
251: }
252:
253: /**
254: * Returns the current y-coordinate screen position of this browser window relative to the parent application window.
255: If the parent window is no longer open, this method returns the position relative to the upper-left
256: corner of the screen.
257: */
258: @SuppressWarnings("unchecked")
259: public void getOffsetTop(
260: org.directwebremoting.proxy.Callback<Integer> callback) {
261: ScriptBuffer script = new ScriptBuffer();
262: String callbackPrefix = "";
263:
264: if (callback != null) {
265: callbackPrefix = "var reply = ";
266: }
267:
268: script.appendCall(callbackPrefix + getContextPath()
269: + "getOffsetTop");
270:
271: if (callback != null) {
272: String key = org.directwebremoting.extend.CallbackHelper
273: .saveCallback(callback, Integer.class);
274: script
275: .appendCall("__System.activateCallback", key,
276: "reply");
277: }
278:
279: getScriptProxy().addScript(script);
280: }
281:
282: /**
283: * Returns the first DOM child of this window object. If no child exists, this method creates a root block, adds it
284: to the DOM, and returns it. A window will only render its first DOM child.
285: */
286: @SuppressWarnings("unchecked")
287: public jsx3.gui.Block getRootBlock() {
288: String extension = "getRootBlock().";
289: try {
290: java.lang.reflect.Constructor<jsx3.gui.Block> ctor = jsx3.gui.Block.class
291: .getConstructor(Context.class, String.class,
292: ScriptProxy.class);
293: return ctor.newInstance(this , extension, getScriptProxy());
294: } catch (Exception ex) {
295: throw new IllegalArgumentException("Unsupported type: "
296: + jsx3.gui.Block.class.getName());
297: }
298: }
299:
300: /**
301: * Returns the first DOM child of this window object. If no child exists, this method creates a root block, adds it
302: to the DOM, and returns it. A window will only render its first DOM child.
303: * @param returnType The expected return type
304: */
305: @SuppressWarnings("unchecked")
306: public <T> T getRootBlock(Class<T> returnType) {
307: String extension = "getRootBlock().";
308: try {
309: java.lang.reflect.Constructor<T> ctor = returnType
310: .getConstructor(Context.class, String.class,
311: ScriptProxy.class);
312: return ctor.newInstance(this , extension, getScriptProxy());
313: } catch (Exception ex) {
314: throw new IllegalArgumentException(
315: "Unsupported return type: " + returnType.getName());
316: }
317: }
318:
319: /**
320: * Repaints the root block of this window.
321: */
322: @SuppressWarnings("unchecked")
323: public void repaint(
324: org.directwebremoting.proxy.Callback<String> callback) {
325: ScriptBuffer script = new ScriptBuffer();
326: String callbackPrefix = "";
327:
328: if (callback != null) {
329: callbackPrefix = "var reply = ";
330: }
331:
332: script
333: .appendCall(callbackPrefix + getContextPath()
334: + "repaint");
335:
336: if (callback != null) {
337: String key = org.directwebremoting.extend.CallbackHelper
338: .saveCallback(callback, String.class);
339: script
340: .appendCall("__System.activateCallback", key,
341: "reply");
342: }
343:
344: getScriptProxy().addScript(script);
345: }
346:
347: /**
348: * Returns the inner (visible) width of this window. This does not include the border and padding that the
349: browser may render around the window content.
350: */
351: @SuppressWarnings("unchecked")
352: public void getWidth(
353: org.directwebremoting.proxy.Callback<Integer> callback) {
354: ScriptBuffer script = new ScriptBuffer();
355: String callbackPrefix = "";
356:
357: if (callback != null) {
358: callbackPrefix = "var reply = ";
359: }
360:
361: script.appendCall(callbackPrefix + getContextPath()
362: + "getWidth");
363:
364: if (callback != null) {
365: String key = org.directwebremoting.extend.CallbackHelper
366: .saveCallback(callback, Integer.class);
367: script
368: .appendCall("__System.activateCallback", key,
369: "reply");
370: }
371:
372: getScriptProxy().addScript(script);
373: }
374:
375: /**
376: * Sets the inner (visible) width of this window. If the window is currently open, the window will be resized
377: immediately.
378: * @param intWidth the inner width of the window in pixels.
379: */
380: public void setWidth(int intWidth) {
381: ScriptBuffer script = new ScriptBuffer();
382: script.appendCall(getContextPath() + "setWidth", intWidth);
383: getScriptProxy().addScript(script);
384: }
385:
386: /**
387: * Returns the inner (visible) height of this window. This does not include the border and padding that the
388: browser may render around the window content.
389: */
390: @SuppressWarnings("unchecked")
391: public void getHeight(
392: org.directwebremoting.proxy.Callback<Integer> callback) {
393: ScriptBuffer script = new ScriptBuffer();
394: String callbackPrefix = "";
395:
396: if (callback != null) {
397: callbackPrefix = "var reply = ";
398: }
399:
400: script.appendCall(callbackPrefix + getContextPath()
401: + "getHeight");
402:
403: if (callback != null) {
404: String key = org.directwebremoting.extend.CallbackHelper
405: .saveCallback(callback, Integer.class);
406: script
407: .appendCall("__System.activateCallback", key,
408: "reply");
409: }
410:
411: getScriptProxy().addScript(script);
412: }
413:
414: /**
415: * Sets the inner (visible) height of this window. If the window is currently open, the window will be resized
416: immediately.
417: * @param intHeight the inner height of the window in pixels.
418: */
419: public void setHeight(int intHeight) {
420: ScriptBuffer script = new ScriptBuffer();
421: script.appendCall(getContextPath() + "setHeight", intHeight);
422: getScriptProxy().addScript(script);
423: }
424:
425: /**
426: * Returns whether this window is resizable via user interaction. The value returned by this method will reflect
427: the last value passed to setResizable() and therefore may not truly reflect the current state of the
428: browser window.
429: * @param callback <code>jsx3.Boolean.TRUE</code> or <code>jsx3.Boolean.FALSE</code>.
430: */
431: @SuppressWarnings("unchecked")
432: public void isResizable(
433: org.directwebremoting.proxy.Callback<Integer> callback) {
434: ScriptBuffer script = new ScriptBuffer();
435: String callbackPrefix = "";
436:
437: if (callback != null) {
438: callbackPrefix = "var reply = ";
439: }
440:
441: script.appendCall(callbackPrefix + getContextPath()
442: + "isResizable");
443:
444: if (callback != null) {
445: String key = org.directwebremoting.extend.CallbackHelper
446: .saveCallback(callback, Integer.class);
447: script
448: .appendCall("__System.activateCallback", key,
449: "reply");
450: }
451:
452: getScriptProxy().addScript(script);
453: }
454:
455: /**
456: * Sets whether this window is resizable via user interaction. This method will not affect a currently-open window.
457: * @param bResizable
458: */
459: public void setResizable(boolean bResizable) {
460: ScriptBuffer script = new ScriptBuffer();
461: script
462: .appendCall(getContextPath() + "setResizable",
463: bResizable);
464: getScriptProxy().addScript(script);
465: }
466:
467: /**
468: * Returns whether this window will show scroll bars if the content outgrows the window. The value returned by
469: this method will reflect the last value passed to setScrollable() and therefore may not truly
470: reflect the current state of the browser window.
471: * @param callback <code>jsx3.Boolean.TRUE</code> or <code>jsx3.Boolean.FALSE</code>.
472: */
473: @SuppressWarnings("unchecked")
474: public void isScrollable(
475: org.directwebremoting.proxy.Callback<Integer> callback) {
476: ScriptBuffer script = new ScriptBuffer();
477: String callbackPrefix = "";
478:
479: if (callback != null) {
480: callbackPrefix = "var reply = ";
481: }
482:
483: script.appendCall(callbackPrefix + getContextPath()
484: + "isScrollable");
485:
486: if (callback != null) {
487: String key = org.directwebremoting.extend.CallbackHelper
488: .saveCallback(callback, Integer.class);
489: script
490: .appendCall("__System.activateCallback", key,
491: "reply");
492: }
493:
494: getScriptProxy().addScript(script);
495: }
496:
497: /**
498: * Sets whether this window will show scroll bars if the content outgrows the window. This method will not affect a
499: currently-open window.
500: * @param bScrollable
501: */
502: public void setScrollable(boolean bScrollable) {
503: ScriptBuffer script = new ScriptBuffer();
504: script.appendCall(getContextPath() + "setScrollable",
505: bScrollable);
506: getScriptProxy().addScript(script);
507: }
508:
509: /**
510: * Returns whether this window is "dependent." Dependent windows close automatically when their parents close. If
511: a window is not dependent, it will stay open after the parent window closes. Note that the parent window contains
512: all the JavaScript code and so it is very likely that interacting with a window after the parent has closed
513: will raise errors.
514: * @param callback <code>jsx3.Boolean.TRUE</code> or <code>jsx3.Boolean.FALSE</code>.
515: */
516: @SuppressWarnings("unchecked")
517: public void isDependent(
518: org.directwebremoting.proxy.Callback<Integer> callback) {
519: ScriptBuffer script = new ScriptBuffer();
520: String callbackPrefix = "";
521:
522: if (callback != null) {
523: callbackPrefix = "var reply = ";
524: }
525:
526: script.appendCall(callbackPrefix + getContextPath()
527: + "isDependent");
528:
529: if (callback != null) {
530: String key = org.directwebremoting.extend.CallbackHelper
531: .saveCallback(callback, Integer.class);
532: script
533: .appendCall("__System.activateCallback", key,
534: "reply");
535: }
536:
537: getScriptProxy().addScript(script);
538: }
539:
540: /**
541: * Sets whether this window is "dependent." This method not affect a currently-open window.
542: * @param bDependent
543: */
544: public void setDependent(boolean bDependent) {
545: ScriptBuffer script = new ScriptBuffer();
546: script
547: .appendCall(getContextPath() + "setDependent",
548: bDependent);
549: getScriptProxy().addScript(script);
550: }
551:
552: /**
553: * Returns the title of this window.
554: */
555: @SuppressWarnings("unchecked")
556: public void getTitle(
557: org.directwebremoting.proxy.Callback<String> callback) {
558: ScriptBuffer script = new ScriptBuffer();
559: String callbackPrefix = "";
560:
561: if (callback != null) {
562: callbackPrefix = "var reply = ";
563: }
564:
565: script.appendCall(callbackPrefix + getContextPath()
566: + "getTitle");
567:
568: if (callback != null) {
569: String key = org.directwebremoting.extend.CallbackHelper
570: .saveCallback(callback, String.class);
571: script
572: .appendCall("__System.activateCallback", key,
573: "reply");
574: }
575:
576: getScriptProxy().addScript(script);
577: }
578:
579: /**
580: * Sets the title of the window. The title is displayed in the title bar of the browser window. If the window is
581: currently open, the title will be updated immediately.
582: * @param strTitle the title of the window.
583: */
584: public void setTitle(String strTitle) {
585: ScriptBuffer script = new ScriptBuffer();
586: script.appendCall(getContextPath() + "setTitle", strTitle);
587: getScriptProxy().addScript(script);
588: }
589:
590: }
|