Source Code Cross Referenced for Window.java in  » Ajax » zk » org » zkoss » zul » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » zk » org.zkoss.zul 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* Window.java
0002:
0003:        {{IS_NOTE
0004:        	Purpose:
0005:        		
0006:        	Description:
0007:        		
0008:        	History:
0009:        		Tue May 31 19:29:13     2005, Created by tomyeh
0010:        }}IS_NOTE
0011:
0012:        Copyright (C) 2005 Potix Corporation. All Rights Reserved.
0013:
0014:        {{IS_RIGHT
0015:        	This program is distributed under GPL Version 2.0 in the hope that
0016:        	it will be useful, but WITHOUT ANY WARRANTY.
0017:        }}IS_RIGHT
0018:         */
0019:        package org.zkoss.zul;
0020:
0021:        import java.util.Collections;
0022:        import java.util.Map;
0023:        import java.util.HashMap;
0024:        import java.util.Iterator;
0025:        import java.util.Set;
0026:        import java.util.LinkedHashSet;
0027:
0028:        import org.zkoss.mesg.MCommon;
0029:        import org.zkoss.lang.D;
0030:        import org.zkoss.lang.Objects;
0031:        import org.zkoss.util.logging.Log;
0032:        import org.zkoss.xml.HTMLs;
0033:
0034:        import org.zkoss.zk.ui.Desktop;
0035:        import org.zkoss.zk.ui.Component;
0036:        import org.zkoss.zk.ui.Page;
0037:        import org.zkoss.zk.ui.Executions;
0038:        import org.zkoss.zk.ui.UiException;
0039:        import org.zkoss.zk.ui.WrongValueException;
0040:        import org.zkoss.zk.ui.SuspendNotAllowedException;
0041:        import org.zkoss.zk.ui.IdSpace;
0042:        import org.zkoss.zk.ui.ext.render.MultiBranch;
0043:        import org.zkoss.zk.ui.ext.client.Openable;
0044:        import org.zkoss.zk.ui.ext.render.Floating;
0045:        import org.zkoss.zk.ui.event.Events;
0046:
0047:        import org.zkoss.zul.impl.XulElement;
0048:
0049:        /**
0050:         * A generic window.
0051:         *
0052:         * <p>Unlike other elements, each {@link Window} is an independent ID space
0053:         * (by implementing {@link IdSpace}).
0054:         * It means a window and all its descendants forms a ID space and
0055:         * the ID of each of them is unique in this space.
0056:         * You could retrieve any of them in this space by calling {@link #getFellow}.
0057:         *
0058:         * <p>If a window X is a descendant of another window Y, X's descendants
0059:         * are not visible in Y's space. To retrieve a descendant, say Z, of X, 
0060:         * you have to invoke Y.getFellow('X').getFellow('Z').
0061:         *
0062:         * <p>Events:<br/>
0063:         * onMove, onOpen, onClose, onOK, onCacnel and onCtrlKey.<br/>
0064:         * Note: to have better performance, onOpen is sent only if a
0065:         * non-deferrable event listener is registered
0066:         * (see {@link org.zkoss.zk.ui.event.Deferrable}).
0067:         *
0068:         * <p><code>onClose</code> is sent when the close button is pressed
0069:         * (if {@link #isClosable} is true). The window has to detach or hide
0070:         * the window. By default, {@link #onClose} detaches the window. To prevent
0071:         * it from detached, you have to call {@link org.zkoss.zk.ui.event.Event#stopPropagation}
0072:         * to prevent {@link #onClose} is called.
0073:         *
0074:         * <p>On the other hand, <code>onOpen</code> is sent when a popup
0075:         * window (i.e., {@link #getMode} is popup) is closed due to user's activity
0076:         * (such as press ESC). This event is only a notification.
0077:         * In other words, the popup is hidden before the event is sent to the server.
0078:         * The application cannot prevent the window from being hidden.
0079:         *
0080:         * @author tomyeh
0081:         */
0082:        public class Window extends XulElement implements  IdSpace {
0083:            private static final Log log = Log.lookup(Window.class);
0084:            private static String _onshow = null;
0085:            private transient Caption _caption;
0086:
0087:            private String _border = "none";
0088:            private String _title = "";
0089:            /** What control and function keys to intercepts. */
0090:            private String _ctrlKeys;
0091:            /** The value passed to the client; parsed from _ctrlKeys. */
0092:            private String _ctkeys;
0093:            /** One of MODAL, EMBEDDED, OVERLAPPED, HIGHLIGHTED, POPUP. */
0094:            private int _mode = EMBEDDED;
0095:            /** Used for doModal. */
0096:            private transient Object _mutex;
0097:            /** The style used for the content block. */
0098:            private String _cntStyle;
0099:            /** The style class used for the content block. */
0100:            private String _cntscls;
0101:            /** How to position the window. */
0102:            private String _pos;
0103:            /** Whether to show a close button. */
0104:            private boolean _closable;
0105:            /** Whether the window is sizable. */
0106:            private boolean _sizable;
0107:
0108:            /** Embeds the window as normal component. */
0109:            private static final int EMBEDDED = 0;
0110:            /** Makes the window as a modal dialog. once {@link #doModal}
0111:             * is called, the execution of the event processing thread
0112:             * is suspended until one of the following occurs.
0113:             * <ol>
0114:             * <li>{@link #setMode} is called with a mode other than MODAL.</li>
0115:             * <li>Either {@link #doOverlapped}, {@link #doPopup},
0116:             * {@link #doEmbedded}, or {@link #doHighlighted} is called.</li>
0117:             * <li>{@link #setVisible} is called with false.</li>
0118:             * <li>The window is detached from the window.</li>
0119:             * </ol>
0120:             *
0121:             * <p>Note: In the last two cases, the mode becomes {@link #OVERLAPPED}.
0122:             * In other words, one might say a modal window is a special overlapped window.
0123:             *
0124:             * @see #HIGHLIGHTED
0125:             */
0126:            private static final int MODAL = 1;
0127:            /** Makes the window as overlapped other components.
0128:             */
0129:            private static final int OVERLAPPED = 2;
0130:            /** Makes the window as popup.
0131:             * It is similar to {@link #OVERLAPPED}, except it is auto hidden
0132:             * when user clicks outside of the window.
0133:             */
0134:            private static final int POPUP = 3;
0135:            /** Makes the window as hilighted.
0136:             * Its visual effect is the same as {@link #MODAL}.
0137:             * However, from the server side's viewpoint, it is similar to
0138:             * {@link #OVERLAPPED}. The execution won't be suspended when
0139:             * {@link #doHighlighted} is called.
0140:             *
0141:             * @see #MODAL
0142:             * @see #OVERLAPPED
0143:             */
0144:            private static final int HIGHLIGHTED = 4;
0145:
0146:            public Window() {
0147:                init();
0148:            }
0149:
0150:            /**
0151:             * @param title the window title (see {@link #setTitle}).
0152:             * @param border the border (see {@link #setBorder}).
0153:             * @param closable whether it is closable (see {@link #setClosable}).
0154:             */
0155:            public Window(String title, String border, boolean closable) {
0156:                this ();
0157:                setTitle(title);
0158:                setBorder(border);
0159:                setClosable(closable);
0160:            }
0161:
0162:            private void init() {
0163:                _mutex = new Object();
0164:            }
0165:
0166:            /**
0167:             * Sets the action of window component to show the animating effect by default.
0168:             * 
0169:             * <p>Default: null. In other words, if the property is null, it will refer to
0170:             * the configuration of zk.xml to find the preference with 
0171:             * "org.zkoss.zul.Window.defaultActionOnShow", if any. For example,
0172:             * <pre>&lt;preference&gt;
0173:             *   &lt;name&gt;org.zkoss.zul.Window.defaultActionOnShow&lt;/name&gt;
0174:             *   &lt;value&gt;moveDown&lt;/value&gt;
0175:             * &lt;/preference&gt;</pre>
0176:             *  Otherwise, the animating 
0177:             * effect is depended on component itself.</p>
0178:             * <p>In JavaScript, the property will match the same function name with the
0179:             * prefix "anima.". For example, if the property is "moveDown", the function name
0180:             * should be "anima.moveDown" accordingly.</p>
0181:             * <p><strong>Node:</strong> The method is available in modal mode only. And if 
0182:             * the onshow command of client-side action has been assigned on the 
0183:             * component, its priority is higher than this method.<br/>
0184:             * For example, 
0185:             * <pre>action="onshow:anima.appear(#{self});"</pre>
0186:             * </p>
0187:             * 
0188:             * @param onshow the function name in JavaScript. You could use the following
0189:             * animations, e.g. "moveDown", "moveRight", "moveDiagonal", "appear", 
0190:             * "slideDown", and so forth.
0191:             * @since 3.0.2
0192:             */
0193:            public static void setDefaultActionOnShow(String onshow) {
0194:                if (!Objects.equals(_onshow, onshow))
0195:                    _onshow = onshow;
0196:            }
0197:
0198:            /**
0199:             * Returns the animating name of function.
0200:             * @since 3.0.2
0201:             */
0202:            public static String getDefaultActionOnShow() {
0203:                return _onshow;
0204:            }
0205:
0206:            /** Returns the caption of this window.
0207:             */
0208:            public Caption getCaption() {
0209:                return _caption;
0210:            }
0211:
0212:            /** Returns the border.
0213:             * The border actually controls what the content style class is
0214:             * is used. In fact, the name of the border (except "normal")
0215:             * is generate as part of the style class used for the content block.
0216:             * Refer to {@link #getContentSclass} for more details.
0217:             *
0218:             * <p>Default: "none".
0219:             */
0220:            public String getBorder() {
0221:                return _border;
0222:            }
0223:
0224:            /** Sets the border (either none or normal).
0225:             *
0226:             * @param border the border. If null or "0", "none" is assumed.
0227:             * Since 2.4.1, We assume "0" to be "none".
0228:             */
0229:            public void setBorder(String border) {
0230:                if (border == null || "0".equals(border))
0231:                    border = "none";
0232:                if (!Objects.equals(_border, border)) {
0233:                    _border = border;
0234:                    smartUpdate("class", getSclass());
0235:                }
0236:            }
0237:
0238:            /** Returns the title.
0239:             * Besides this attribute, you could use {@link Caption} to define
0240:             * a more sophiscated caption (aka., title).
0241:             * <p>If a window has a caption whose label ({@link Caption#getLabel})
0242:             * is not empty, then this attribute is ignored.
0243:             * <p>Default: empty.
0244:             */
0245:            public String getTitle() {
0246:                return _title;
0247:            }
0248:
0249:            /** Sets the title.
0250:             */
0251:            public void setTitle(String title) {
0252:                if (title == null)
0253:                    title = "";
0254:                if (!Objects.equals(_title, title)) {
0255:                    _title = title;
0256:                    if (_caption != null)
0257:                        _caption.invalidate();
0258:                    else
0259:                        invalidate();
0260:                }
0261:            }
0262:
0263:            /** Returns what keystrokes to intercept.
0264:             * <p>Default: null.
0265:             */
0266:            public String getCtrlKeys() {
0267:                return _ctrlKeys;
0268:            }
0269:
0270:            /** Sets what keystrokes to intercept.
0271:             *
0272:             * <p>The string could be a combination of the following:
0273:             * <dl>
0274:             * <dt>^k</dt>
0275:             * <dd>A control key, i.e., Ctrl+k, where k could be a~z, 0~9, #n</dd>
0276:             * <dt>@k</dt>
0277:             * <dd>A alt key, i.e., Alt+k, where k could be a~z, 0~9, #n</dd>
0278:             * <dt>$k</dt>
0279:             * <dd>A shift key, i.e., Shift+k, where k could be #n</dd>
0280:             * <dt>#home</dt>
0281:             * <dd>Home</dd>
0282:             * <dt>#end</dt>
0283:             * <dd>End</dd>
0284:             * <dt>#ins</dt>
0285:             * <dd>Insert</dd>
0286:             * <dt>#del</dt>
0287:             * <dd>Delete</dd>
0288:             * <dt>#left</dt>
0289:             * <dd>Left arrow</dd>
0290:             * <dt>#right</dt>
0291:             * <dd>Right arrow</dd>
0292:             * <dt>#up</dt>
0293:             * <dd>Up arrow</dd>
0294:             * <dt>#down</dt>
0295:             * <dd>Down arrow</dd>
0296:             * <dt>#pgup</dt>
0297:             * <dd>PageUp</dd>
0298:             * <dt>#pgdn</dt>
0299:             * <dd>PageDn</dd>
0300:             * <dt>#f1 #f2 ... #f12</dt>
0301:             * <dd>Function keys representing F1, F2, ... F12</dd>
0302:             * </dl>
0303:             *
0304:             * <p>For example,
0305:             * <dl>
0306:             * <dt>^a^d@c#f10#left#right</dt>
0307:             * <dd>It means you want to intercept Ctrl+A, Ctrl+D, Alt+C, F10,
0308:             * Left and Right.</dd>
0309:             * <dt>^#left</dt>
0310:             * <dd>It means Ctrl+Left.</dd>
0311:             * <dt>^#f1</dt>
0312:             * <dd>It means Ctrl+F1.</dd>
0313:             * <dt>@#f3</dt>
0314:             * <dd>It means Alt+F3.</dd>
0315:             * </dl>
0316:             *
0317:             * <p>Note: it doesn't support Ctrl+Alt, Shift+Ctrl, Shift+Alt or Shift+Ctrl+Alt.
0318:             */
0319:            public void setCtrlKeys(String ctrlKeys) throws UiException {
0320:                if (ctrlKeys != null && ctrlKeys.length() == 0)
0321:                    ctrlKeys = null;
0322:                if (!Objects.equals(_ctrlKeys, ctrlKeys)) {
0323:                    parseCtrlKeys(ctrlKeys);
0324:                    smartUpdate("z.ctkeys", _ctkeys);
0325:                }
0326:            }
0327:
0328:            private void parseCtrlKeys(String keys) throws UiException {
0329:                if (keys == null || keys.length() == 0) {
0330:                    _ctrlKeys = _ctkeys = null;
0331:                    return;
0332:                }
0333:
0334:                final StringBuffer sbctl = new StringBuffer(), sbsft = new StringBuffer(), sbalt = new StringBuffer(), sbext = new StringBuffer();
0335:                StringBuffer sbcur = null;
0336:                for (int j = 0, len = keys.length(); j < len; ++j) {
0337:                    char cc = keys.charAt(j);
0338:                    switch (cc) {
0339:                    case '^':
0340:                    case '$':
0341:                    case '@':
0342:                        if (sbcur != null)
0343:                            throw new WrongValueException(
0344:                                    "Combination of Shift, Alt and Ctrl not supported: "
0345:                                            + keys);
0346:                        sbcur = cc == '^' ? sbctl : cc == '@' ? sbalt : sbsft;
0347:                        break;
0348:                    case '#': {
0349:                        int k = j + 1;
0350:                        for (; k < len; ++k) {
0351:                            final char c2 = (char) keys.charAt(k);
0352:                            if ((c2 > 'Z' || c2 < 'A')
0353:                                    && (c2 > 'z' || c2 < 'a')
0354:                                    && (c2 > '9' || c2 < '0'))
0355:                                break;
0356:                        }
0357:                        if (k == j + 1)
0358:                            throw new WrongValueException(
0359:                                    MCommon.UNEXPECTED_CHARACTER, new Object[] {
0360:                                            new Character(cc), keys });
0361:
0362:                        final String s = keys.substring(j + 1, k).toLowerCase();
0363:                        if ("pgup".equals(s))
0364:                            cc = 'A';
0365:                        else if ("pgdn".equals(s))
0366:                            cc = 'B';
0367:                        else if ("end".equals(s))
0368:                            cc = 'C';
0369:                        else if ("home".equals(s))
0370:                            cc = 'D';
0371:                        else if ("left".equals(s))
0372:                            cc = 'E';
0373:                        else if ("up".equals(s))
0374:                            cc = 'F';
0375:                        else if ("right".equals(s))
0376:                            cc = 'G';
0377:                        else if ("down".equals(s))
0378:                            cc = 'H';
0379:                        else if ("ins".equals(s))
0380:                            cc = 'I';
0381:                        else if ("del".equals(s))
0382:                            cc = 'J';
0383:                        else if (s.length() > 1 && s.charAt(0) == 'f') {
0384:                            final int v;
0385:                            try {
0386:                                v = Integer.parseInt(s.substring(1));
0387:                            } catch (Throwable ex) {
0388:                                throw new WrongValueException("Unknown #" + s
0389:                                        + " in " + keys);
0390:                            }
0391:                            if (v == 0 || v > 12)
0392:                                throw new WrongValueException(
0393:                                        "Unsupported function key: #f" + v);
0394:                            cc = (char) ('O' + v); //'P': F1, 'Q': F2... 'Z': F12
0395:                        } else
0396:                            throw new WrongValueException("Unknown #" + s
0397:                                    + " in " + keys);
0398:
0399:                        if (sbcur == null)
0400:                            sbext.append(cc);
0401:                        else {
0402:                            sbcur.append(cc);
0403:                            sbcur = null;
0404:                        }
0405:                        j = k - 1;
0406:                    }
0407:                        break;
0408:                    default:
0409:                        if (sbcur == null
0410:                                || ((cc > 'Z' || cc < 'A')
0411:                                        && (cc > 'z' || cc < 'a') && (cc > '9' || cc < '0')))
0412:                            throw new WrongValueException(
0413:                                    MCommon.UNEXPECTED_CHARACTER, new Object[] {
0414:                                            new Character(cc), keys });
0415:                        if (sbcur == sbsft)
0416:                            throw new WrongValueException("$" + cc
0417:                                    + " not supported: " + keys);
0418:
0419:                        if (cc <= 'Z' && cc >= 'A')
0420:                            cc = (char) (cc + ('a' - 'A')); //to lower case
0421:                        sbcur.append(cc);
0422:                        sbcur = null;
0423:                        break;
0424:                    }
0425:                }
0426:
0427:                _ctkeys = new StringBuffer().append('^').append(sbctl).append(
0428:                        ';').append('@').append(sbalt).append(';').append('$')
0429:                        .append(sbsft).append(';').append('#').append(sbext)
0430:                        .append(';').toString();
0431:                _ctrlKeys = keys;
0432:            }
0433:
0434:            /** Returns the current mode.
0435:             * One of "modal", "embedded", "overlapped", "popup", and "highlighted".
0436:             */
0437:            public String getMode() {
0438:                return modeToString(_mode);
0439:            }
0440:
0441:            private static String modeToString(int mode) {
0442:                switch (mode) {
0443:                case MODAL:
0444:                    return "modal";
0445:                case POPUP:
0446:                    return "popup";
0447:                case OVERLAPPED:
0448:                    return "overlapped";
0449:                case HIGHLIGHTED:
0450:                    return "highlighted";
0451:                default:
0452:                    return "embedded";
0453:                }
0454:            }
0455:
0456:            /** Sets the mode to overlapped, popup, modal, embedded or highlighted.
0457:             *
0458:             * <p>Notice: {@link Events#ON_MODAL} is posted if you specify
0459:             * "modal" to this method and in a thread other than an event
0460:             * listener ({@link Events#inEventListener}).
0461:             * In other words, if this method is called with modal and
0462:             * <em>not</em> in any event listener, the mode won't be changed
0463:             * immediately (until {@link Events#ON_MODAL} is processed later).
0464:             *
0465:             * @param name the mode which could be one of
0466:             * "embedded", "overlapped", "popup", "modal", "highlighted".
0467:             * Note: it cannot be "modal". Use {@link #doModal} instead.
0468:             *
0469:             * @exception InterruptedException thrown if "modal" is specified,
0470:             * and one of the following conditions occurs:
0471:             * 1) the desktop or the Web application is being destroyed, or
0472:             * 2) {@link org.zkoss.zk.ui.sys.DesktopCtrl#ceaseSuspendedThread}.
0473:             * To tell the difference, check the getMessage method of InterruptedException.
0474:             */
0475:            public void setMode(String name) throws InterruptedException {
0476:                if ("popup".equals(name))
0477:                    doPopup();
0478:                else if ("overlapped".equals(name))
0479:                    doOverlapped();
0480:                else if ("embedded".equals(name))
0481:                    doEmbedded();
0482:                else if ("modal".equals(name))
0483:                    doModal();
0484:                else if ("highlighted".equals(name))
0485:                    doHighlighted();
0486:                else
0487:                    throw new WrongValueException("Uknown mode: " + name);
0488:            }
0489:
0490:            /** Sets the mode to overlapped, popup, modal, embedded or highlighted.
0491:             *
0492:             * @see #setMode(String)
0493:             */
0494:            public void setMode(int mode) throws InterruptedException {
0495:                switch (mode) {
0496:                case POPUP:
0497:                    doPopup();
0498:                    break;
0499:                case OVERLAPPED:
0500:                    doOverlapped();
0501:                    break;
0502:                case EMBEDDED:
0503:                    doEmbedded();
0504:                    break;
0505:                case MODAL:
0506:                    doModal();
0507:                    break;
0508:                case HIGHLIGHTED:
0509:                    doHighlighted();
0510:                    break;
0511:                default:
0512:                    throw new WrongValueException("Unknown mode: " + mode);
0513:                }
0514:            }
0515:
0516:            /** Returns whether this is a modal dialog.
0517:             */
0518:            public boolean inModal() {
0519:                return _mode == MODAL;
0520:            }
0521:
0522:            /** Returns whether this is embedded with other components (Default).
0523:             * @see #doEmbedded
0524:             */
0525:            public boolean inEmbedded() {
0526:                return _mode == EMBEDDED;
0527:            }
0528:
0529:            /** Returns whether this is a overlapped window.
0530:             */
0531:            public boolean inOverlapped() {
0532:                return _mode == OVERLAPPED;
0533:            }
0534:
0535:            /** Returns whether this is a popup window.
0536:             */
0537:            public boolean inPopup() {
0538:                return _mode == POPUP;
0539:            }
0540:
0541:            /** Returns whether this is a highlighted window.
0542:             */
0543:            public boolean inHighlighted() {
0544:                return _mode == HIGHLIGHTED;
0545:            }
0546:
0547:            /** Makes this window as a modal dialog.
0548:             * It will automatically center the window (ignoring {@link #getLeft} and
0549:             * {@link #getTop}).
0550:             *
0551:             * <p>Notice: {@link Events#ON_MODAL} is posted if you specify
0552:             * "modal" to this method and in a thread other than an event
0553:             * listener ({@link Events#inEventListener}).
0554:             * In other words, if this method is called with modal and
0555:             * <em>not</em> in any event listener, the mode won't be changed
0556:             * immediately (until {@link Events#ON_MODAL} is processed later).
0557:             *
0558:             * @exception SuspendNotAllowedException if there are too many suspended
0559:             * processing thread than the deployer allows.
0560:             * By default, there is no limit of # of suspended threads.
0561:             * @exception InterruptedException thrown if the desktop or
0562:             * the Web application is being destroyed, or
0563:             * {@link org.zkoss.zk.ui.sys.DesktopCtrl#ceaseSuspendedThread}.
0564:             * To tell the difference, check the getMessage method of InterruptedException.
0565:             */
0566:            public void doModal() throws InterruptedException,
0567:                    SuspendNotAllowedException {
0568:                Desktop desktop = getDesktop();
0569:                if (desktop == null)
0570:                    desktop = Executions.getCurrent().getDesktop();
0571:                if (!desktop.getWebApp().getConfiguration()
0572:                        .isEventThreadEnabled()) {
0573:                    handleFailedModal(_mode, isVisible());
0574:                    throw new SuspendNotAllowedException(
0575:                            "Event processing thread is disabled");
0576:                }
0577:
0578:                checkOverlappable(MODAL);
0579:
0580:                if (_mode != MODAL) {
0581:                    if (!Events.inEventListener()) {
0582:                        Events.postEvent(Events.ON_MODAL, this , null);
0583:                        return; //done
0584:                    }
0585:
0586:                    int oldmode = _mode;
0587:                    boolean oldvisi = isVisible();
0588:
0589:                    invalidate();
0590:                    setVisible(true); //if MODAL, it must be visible; vice versa
0591:
0592:                    try {
0593:                        enterModal();
0594:                    } catch (SuspendNotAllowedException ex) {
0595:                        handleFailedModal(oldmode, oldvisi);
0596:                        throw ex;
0597:                    }
0598:                }
0599:            }
0600:
0601:            private void handleFailedModal(int oldmode, boolean oldvisi) {
0602:                try {
0603:                    if (Executions.getCurrent().getAttribute(
0604:                            "javax.servlet.error.exception") != null) {
0605:                        //handle it specially if it is used for dispalying err
0606:                        setMode(HIGHLIGHTED);
0607:                    } else {
0608:                        setMode(oldmode); //restore
0609:                        setVisible(oldvisi);
0610:                    }
0611:                } catch (Throwable ex) {
0612:                    log.realCauseBriefly("Causing another error", ex);
0613:                }
0614:            }
0615:
0616:            /** Makes this window as overlapped with other components.
0617:             */
0618:            public void doOverlapped() {
0619:                checkOverlappable(OVERLAPPED);
0620:                setNonModalMode(OVERLAPPED);
0621:            }
0622:
0623:            /** Makes this window as popup, which is overlapped with other component
0624:             * and auto-hiden when user clicks outside of the window.
0625:             */
0626:            public void doPopup() {
0627:                checkOverlappable(POPUP);
0628:                setNonModalMode(POPUP);
0629:            }
0630:
0631:            /** Makes this window as highlited. The visual effect is
0632:             * the similar to the modal window, but, like overlapped,
0633:             * it doesn't suspend (block) the execution at the server.
0634:             * In other words, it is more like an overlapped window from the
0635:             * server side's viewpoint.
0636:             */
0637:            public void doHighlighted() {
0638:                checkOverlappable(HIGHLIGHTED);
0639:                setNonModalMode(HIGHLIGHTED);
0640:            }
0641:
0642:            /** Makes this window as embeded with other components (Default).
0643:             */
0644:            public void doEmbedded() {
0645:                setNonModalMode(EMBEDDED);
0646:            }
0647:
0648:            /* Set non-modal mode. */
0649:            private void setNonModalMode(int mode) {
0650:                if (_mode != mode) {
0651:                    if (_mode == MODAL)
0652:                        leaveModal();
0653:                    _mode = mode;
0654:                    invalidate();
0655:                }
0656:                setVisible(true);
0657:            }
0658:
0659:            /** Set mode to MODAL and suspend this thread. */
0660:            private void enterModal() throws InterruptedException {
0661:                _mode = MODAL;
0662:                //no need to synchronized (_mutex) because no racing is possible
0663:                Executions.wait(_mutex);
0664:            }
0665:
0666:            /** Resumes the suspendded thread and set mode to OVERLAPPED. */
0667:            private void leaveModal() {
0668:                _mode = OVERLAPPED;
0669:                Executions.notifyAll(_mutex);
0670:            }
0671:
0672:            /** Makes sure it is not draggable. */
0673:            private void checkOverlappable(int mode) {
0674:                if (!"false".equals(getDraggable()))
0675:                    throw new UiException(
0676:                            "Draggable window cannot be modal, overlapped, popup, or highlighted: "
0677:                                    + this );
0678:
0679:                if (mode == MODAL || mode == HIGHLIGHTED)
0680:                    for (Component comp = this ; (comp = comp.getParent()) != null;)
0681:                        if (!comp.isVisible())
0682:                            throw new UiException(
0683:                                    "One of its ancestors, "
0684:                                            + comp
0685:                                            + ", is not visible, so unable to be modal or highlighted");
0686:            }
0687:
0688:            /** Returns whether to show a close button on the title bar.
0689:             */
0690:            public boolean isClosable() {
0691:                return _closable;
0692:            }
0693:
0694:            /** Sets whether to show a close button on the title bar.
0695:             * If closable, a button is displayed and the onClose event is sent
0696:             * if an user clicks the button.
0697:             *
0698:             * <p>Default: false.
0699:             *
0700:             * <p>You can intercept the default behavior by either overriding
0701:             * {@link #onClose}, or listening the onClose event.
0702:             *
0703:             * <p>Note: the close button won't be displayed if no title or caption at all.
0704:             */
0705:            public void setClosable(boolean closable) {
0706:                if (_closable != closable) {
0707:                    _closable = closable;
0708:                    invalidate(); //re-init is required
0709:                }
0710:            }
0711:
0712:            /** Returns whether the window is sizable.
0713:             */
0714:            public boolean isSizable() {
0715:                return _sizable;
0716:            }
0717:
0718:            /** Sets whether the window is sizable.
0719:             * If true, an user can drag the border to change the window width.
0720:             * <p>Default: false.
0721:             */
0722:            public void setSizable(boolean sizable) {
0723:                if (_sizable != sizable) {
0724:                    _sizable = sizable;
0725:                    smartUpdate("z.sizable", sizable);
0726:                }
0727:            }
0728:
0729:            /** Returns how to position the window at the client screen.
0730:             * It is meaningless if the embedded mode is used.
0731:             *
0732:             * <p>Default: null which depends on {@link #getMode}:
0733:             * If overlapped or popup, {@link #setLeft} and {@link #setTop} are
0734:             * assumed. If modal or highlighted, it is centered.
0735:             */
0736:            public String getPosition() {
0737:                return _pos;
0738:            }
0739:
0740:            /** Sets how to position the window at the client screen.
0741:             * It is meaningless if the embedded mode is used.
0742:             *
0743:             * @param pos how to position. It can be null (the default), or
0744:             * a combination of the following values (by separating with comma).
0745:             * <dl>
0746:             * <dt>center</dt>
0747:             * <dd>Position the window at the center. {@link #setTop} and {@link #setLeft}
0748:             * are both ignored.</dd>
0749:             * <dt>left</dt>
0750:             * <dd>Position the window at the left edge. {@link #setLeft} is ignored.</dd>
0751:             * <dt>right</dt>
0752:             * <dd>Position the window at the right edge. {@link #setLeft} is ignored.</dd>
0753:             * <dt>top</dt>
0754:             * <dd>Position the window at the top edge. {@link #setTop} is ignored.</dd>
0755:             * <dt>bottom</dt>
0756:             * <dd>Position the window at the bottom edge. {@link #setTop} is ignored.</dd>
0757:             * <dt>parent</dt>
0758:             * <dd>Position the window relative to its parent.
0759:             * That is, the left and top ({@link #getTop} and {@link #getLeft})
0760:             * is an offset to his parent's let-top corner. (since 3.0.2)</dd>
0761:             * </dl>
0762:             * <p>For example, "left,center" means to position it at the center of
0763:             * the left edge.
0764:             */
0765:            public void setPosition(String pos) {
0766:                //Note: we always update since the window might be dragged by an user
0767:                _pos = pos;
0768:                if (_mode != EMBEDDED)
0769:                    smartUpdate("z.pos", pos);
0770:            }
0771:
0772:            /** Process the onClose event sent when the close button is pressed.
0773:             * <p>Default: detach itself.
0774:             */
0775:            public void onClose() {
0776:                detach();
0777:            }
0778:
0779:            /** Process the onModal event by making itself a modal window.
0780:             */
0781:            public void onModal() throws InterruptedException {
0782:                doModal();
0783:            }
0784:
0785:            /** Returns the CSS style for the content block of the window.
0786:             */
0787:            public String getContentStyle() {
0788:                return _cntStyle;
0789:            }
0790:
0791:            /** Sets the CSS style for the content block of the window.
0792:             *
0793:             * <p>Default: null.
0794:             */
0795:            public void setContentStyle(String style) {
0796:                if (!Objects.equals(_cntStyle, style)) {
0797:                    _cntStyle = style;
0798:                    smartUpdate("z.cntStyle", _cntStyle);
0799:                }
0800:            }
0801:
0802:            /** Returns the style class used for the content block.
0803:             *
0804:             * <p>If {@link #setContentSclass} was called with a non-empty value,
0805:             * say, "mycnt", then
0806:             * <ol>
0807:             * <li>Case 1: If {@link #getBorder} is "normal", "mycnt" is returned.</li>
0808:             * <li>Case 2: Otherwise, "mycnt-<i>border</i>" is returned
0809:             * where <i>border</i> is the value returned by {@link #getBorder}.</li>
0810:             * </ol>
0811:             *
0812:             * <p>If {@link #setContentSclass} was not called, or called with null,
0813:             * then the content style class is decided by {@link #getSclass} as follows:
0814:             * <ol>
0815:             * <li>Case 1: If {@link #getBorder} is "normal", "wc-<i>sclass</i>" is
0816:             * returned, where <i>sclass</i> is the value returned by {@link #getSclass}.</li>
0817:             * <li>Otherwise, "wc-<i>mode</i>-<i>border</i>",
0818:             * where <i>border</i> is the value returned by {@link #getBorder}.</li>
0819:             * </li>
0820:             * @see #setContentSclass
0821:             */
0822:            public String getContentSclass() {
0823:                String cntscls = _cntscls;
0824:                if (cntscls == null) {
0825:                    cntscls = getSclass();
0826:                    cntscls = cntscls != null ? "wc-" + cntscls : "wc";
0827:                }
0828:                final String border = getBorder();
0829:                return "normal".equals(border) ? cntscls : cntscls + '-'
0830:                        + border;
0831:            }
0832:
0833:            /** Sets the style class used for the content block.
0834:             *
0835:             * @see #getContentSclass
0836:             * @since 3.0.0
0837:             */
0838:            public void setContentSclass(String scls) {
0839:                if (!Objects.equals(_cntscls, scls)) {
0840:                    _cntscls = scls;
0841:                    smartUpdate("z.cntScls", getContentSclass());
0842:                }
0843:            }
0844:
0845:            /** Returns the style class used for the title.
0846:             *
0847:             * <p>It returns "wt-<i>sclass</i>" is returned,
0848:             * where <i>sclass</i> is the value returned by {@link #getSclass}.
0849:             */
0850:            public String getTitleSclass() {
0851:                return "wt-" + getSclass();
0852:            }
0853:
0854:            //-- super --//
0855:            /** Returns the style class.
0856:             * If the style class is not defined ({@link #setSclass} is not called
0857:             * or called with null or empty), it returns {@link #getMode}.
0858:             * In other words, the style class is, by default, the same as
0859:             * the mode name.
0860:             */
0861:            public String getSclass() {
0862:                final String scls = super .getSclass();
0863:                return scls != null ? scls : getMode();
0864:            }
0865:
0866:            public void setSclass(String sclass) {
0867:                if (sclass != null && sclass.length() == 0)
0868:                    sclass = null;
0869:                if (!Objects.equals(super .getSclass(), sclass)) {
0870:                    super .setSclass(sclass);
0871:                    invalidate();
0872:                }
0873:            }
0874:
0875:            //-- Component --//
0876:            public boolean insertBefore(Component child, Component insertBefore) {
0877:                if (child instanceof  Caption) {
0878:                    if (_caption != null && _caption != child)
0879:                        throw new UiException("Only one caption is allowed: "
0880:                                + this );
0881:                    insertBefore = getFirstChild();
0882:                    //always makes caption as the first child
0883:                    _caption = (Caption) child;
0884:                    invalidate();
0885:                } else if (insertBefore instanceof  Caption) {
0886:                    throw new UiException("caption must be the first child");
0887:                }
0888:                return super .insertBefore(child, insertBefore);
0889:            }
0890:
0891:            public void onChildRemoved(Component child) {
0892:                if (child instanceof  Caption) {
0893:                    _caption = null;
0894:                    invalidate();
0895:                }
0896:                super .onChildRemoved(child);
0897:            }
0898:
0899:            public void setPage(Page page) {
0900:                super .setPage(page);
0901:
0902:                if (page == null && _mode == MODAL)
0903:                    leaveModal();
0904:            }
0905:
0906:            public void setParent(Component parent) {
0907:                super .setParent(parent);
0908:
0909:                if (_mode == MODAL && getPage() == null)
0910:                    leaveModal();
0911:            }
0912:
0913:            /** Changes the visibility of the window.
0914:             *
0915:             * <p>Note: If a modal dialog becomes invisible, the modal state
0916:             * will be ended automatically. In other words, the mode ({@link #getMode})
0917:             * will become {@link #OVERLAPPED} and the suspending thread is resumed.
0918:             */
0919:            public boolean setVisible(boolean visible) {
0920:                if (!visible && _mode == MODAL) {
0921:                    leaveModal();
0922:                    invalidate();
0923:                } else if (_mode != EMBEDDED)
0924:                    smartUpdate("z.visible", visible);
0925:                return super .setVisible(visible);
0926:            }
0927:
0928:            //-- super --//
0929:            public void setDraggable(String draggable) {
0930:                if (_mode != EMBEDDED) {
0931:                    if (draggable != null
0932:                            && (draggable.length() > 0 && !"false"
0933:                                    .equals(draggable)))
0934:                        throw new UiException(
0935:                                "Only embedded window could be draggable: "
0936:                                        + this );
0937:                }
0938:                super .setDraggable(draggable);
0939:            }
0940:
0941:            protected String getRealStyle() {
0942:                final String style = super .getRealStyle();
0943:                return _mode != EMBEDDED ? (isVisible() ? "position:absolute;display:none;"
0944:                        : "position:absolute;")
0945:                        + style
0946:                        : style;
0947:                //If no absolute, Opera ignores left and top
0948:                //
0949:                //If not embedded we always generate display:none to have
0950:                //better visual effect (the client will turn it on in zkWnd.init)
0951:            }
0952:
0953:            public String getOuterAttrs() {
0954:                final StringBuffer sb = new StringBuffer(64).append(super 
0955:                        .getOuterAttrs());
0956:                appendAsapAttr(sb, Events.ON_MOVE);
0957:                appendAsapAttr(sb, Events.ON_SIZE);
0958:                appendAsapAttr(sb, Events.ON_Z_INDEX);
0959:                appendAsapAttr(sb, Events.ON_OK);
0960:                appendAsapAttr(sb, Events.ON_CANCEL);
0961:                appendAsapAttr(sb, Events.ON_CTRL_KEY);
0962:                appendAsapAttr(sb, Events.ON_OPEN);
0963:                //no need to generate ON_CLOSE since it is always sent (as ASAP)
0964:
0965:                final String clkattrs = getAllOnClickAttrs(false);
0966:                if (clkattrs != null)
0967:                    sb.append(clkattrs);
0968:                //though widget.js handles onclick (if 3d), it is useful
0969:                //to support onClick for groupbox
0970:                final String aos = getDefaultActionOnShow() != null ? getDefaultActionOnShow()
0971:                        : getDesktop()
0972:                                .getWebApp()
0973:                                .getConfiguration()
0974:                                .getPreference(
0975:                                        "org.zkoss.zul.Window.defaultActionOnShow",
0976:                                        null);
0977:                if (aos != null)
0978:                    HTMLs.appendAttribute(sb, "z.aos",
0979:                            aos.length() == 0 ? "z_none" : aos);
0980:                if (_closable)
0981:                    sb.append(" z.closable=\"true\"");
0982:                if (_sizable)
0983:                    sb.append(" z.sizable=\"true\"");
0984:
0985:                if (_mode != EMBEDDED) {
0986:                    if (_pos != null)
0987:                        HTMLs.appendAttribute(sb, "z.pos", _pos);
0988:                    HTMLs.appendAttribute(sb, "z.mode", getMode());
0989:                    HTMLs.appendAttribute(sb, "z.visible", isVisible());
0990:                }
0991:
0992:                HTMLs.appendAttribute(sb, "z.ctkeys", _ctkeys);
0993:                return sb.toString();
0994:            }
0995:
0996:            //Cloneable//
0997:            public Object clone() {
0998:                final Window clone = (Window) super .clone();
0999:                clone.init();
1000:                if (clone._caption != null)
1001:                    clone.afterUnmarshal();
1002:                return clone;
1003:            }
1004:
1005:            private void afterUnmarshal() {
1006:                for (Iterator it = getChildren().iterator(); it.hasNext();) {
1007:                    final Object child = it.next();
1008:                    if (child instanceof  Caption) {
1009:                        _caption = (Caption) child;
1010:                        break;
1011:                    }
1012:                }
1013:            }
1014:
1015:            //Serializable//
1016:            private synchronized void readObject(java.io.ObjectInputStream s)
1017:                    throws java.io.IOException, ClassNotFoundException {
1018:                s.defaultReadObject();
1019:                init();
1020:                afterUnmarshal();
1021:            }
1022:
1023:            //-- ComponentCtrl --//
1024:            protected Object newExtraCtrl() {
1025:                return new ExtraCtrl();
1026:            }
1027:
1028:            /** A utility class to implement {@link #getExtraCtrl}.
1029:             * It is used only by component developers.
1030:             */
1031:            protected class ExtraCtrl extends XulElement.ExtraCtrl implements 
1032:                    MultiBranch, Openable, Floating {
1033:                //-- MultiBranch --//
1034:                public boolean inDifferentBranch(Component child) {
1035:                    return child instanceof  Caption; //in different branch
1036:                }
1037:
1038:                //-- Openable --//
1039:                public void setOpenByClient(boolean open) {
1040:                    setVisible(open);
1041:                }
1042:
1043:                //Floating//
1044:                public boolean isFloating() {
1045:                    return _mode != EMBEDDED;
1046:                }
1047:            }
1048:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.