001: /* Component.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Mon May 30 21:03:47 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2005 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zk.ui;
020:
021: import java.util.List;
022: import java.util.Map;
023: import java.util.Iterator;
024: import java.io.Writer;
025: import java.io.IOException;
026:
027: import org.zkoss.zk.ui.metainfo.ComponentDefinition;
028: import org.zkoss.zk.ui.event.EventListener;
029: import org.zkoss.zk.ui.util.DeferredValue;
030: import org.zkoss.zk.scripting.Namespace;
031: import org.zkoss.zk.au.AuResponse;
032:
033: /**
034: * A UI component.
035: *
036: * <p>There are two kind of lifecycles: one is page creations and the other
037: * is asynchronous updates.
038: *
039: * <h3>The Page Creation</h3>
040: * <p>The page creation occurs when a page is about to render at the first
041: * time. The detailed phases can be found in the devloper's guide.
042: *
043: * <h3>The Asynchronous Update</h3>
044: * <p>The asynchronous update occurs when users does something on the browser,
045: * such as changing the content of input, clicking buttons and so on.
046: * Such behaviors are packed as requests, queue in the browser, and then
047: * send to the server at the proper time. The detailed phases
048: * can be found in the developer's guide.
049: *
050: * <h3>No Synchronization Required</h3>
051: * <p>To simplify the development of components and applications,
052: * invocations of methods of components and event listener are all serialized.
053: * In other words, application and component developers need not worry
054: * synchronization and other thread issues (unless you are developing
055: * background thread to handle long operations).
056: *
057: * <p>It also implies a limitation that you cannot access components
058: * belonging to other desktops when processing an event.
059: *
060: * @author tomyeh
061: */
062: public interface Component extends java.io.Serializable, Cloneable {
063: /** Returns the component definition of this component (never null).
064: */
065: public ComponentDefinition getDefinition();
066:
067: /** Returns the owner of the ID space that this component belongs to.
068: * The returned value could be a component, a page or null.
069: * If this component itself implements {@link IdSpace}, this method
070: * returns itself.
071: * If it has an ancestor that implements {@link IdSpace},
072: * the ancestor is returned.
073: * Otherwise, the page it belongs to is returned
074: *
075: * <p>Each ID space defines an independent set of IDs. No component
076: * in the same ID space could have the same ID.
077: * To get any component in the same ID space, you could use
078: * {@link #getFellow}.
079: * See {@link IdSpace} for more details.
080: *
081: * <p>The ID space relevant methods include {@link #getFellow},
082: * {@link #getAttribute} and {@link #getVariable}.
083: *
084: * @see #getNamespace
085: */
086: public IdSpace getSpaceOwner();
087:
088: /** Returns the ID. If it is a root component (i.e., without parent),
089: * its ID must be unquie among root components of the same page.
090: *
091: * <p>If a component belongs to an ID space (see {@link IdSpace}),
092: * the ID must also be unique in the ID space it belongs.
093: * any its parent and ancestor implements {@link IdSpace}.
094: *
095: * <p>A page itself is also an ID space, so you could retrieve
096: * compnents in a page by use of {@link Page#getFellow}, unless
097: * the component is a descendant of another component that implements
098: * {@link IdSpace}. In this case, you have to retrieve the parent
099: * first (by use of {@link Page#getFellow} and then use {@link #getFellow}
100: * against the owner of the ID space.
101: *
102: * <p>In zscript and EL, a component with explicit ID can be accessed
103: * directly by the ID. In other word, a variable named by the ID is
104: * created automatically.
105: *
106: * @see Page
107: */
108: public String getId();
109:
110: /** Sets the ID. The scope of uniqunes depends on whether this component
111: * is a root component. Refer to {@link #getId} for more details.
112: *
113: * <p>When a component is constructed, an ID is generated automatically.
114: * Thus, calling this method only you need to identify a component.
115: *
116: * @see Page
117: */
118: public void setId(String id);
119:
120: /** Returns the desktop of this component,
121: * or null if this component doesn't belong to any desktop.
122: *
123: * <p>When a component is created in an event listener, it
124: * is assigned to the current desktop automatically.
125: * If a component is created not in any event listener, it doesn't
126: * belong to any desktop and this method returns null.
127: * Once a component is attached to a desktop (thru {@link #setPage}
128: * or {@link #setParent}), it belongs to the desktop.
129: *
130: * <p>Notice: there is no way to detach a component from a desktop,
131: * once it is attached as described above.
132: * In other words, you cannot move a component (or page) from
133: * one desktop to another.
134: *
135: * <p>In summary, there are only two ways to handle components.
136: * <ol>
137: * <li>Handle them all in event listeners and don't access any components
138: * from other desktops. This is simplest and clearest.</li>
139: * <li>Creates components in another thread (other than event listener)
140: * and attach them to a page (and then desktop) upon an event is received.</li>
141: * </ol>
142: */
143: public Desktop getDesktop();
144:
145: /** Returns the page that this component belongs to, or null if
146: * it doesn't belong to any page.
147: *
148: * <p>When a component is created (aka., constructed), it doesn't
149: * belong to any page. And, if a component doesn't belong to
150: * any page, they won't be displayed at the client.
151: *
152: * <p>When changing parent ({@link #setParent}), the child component's
153: * page will become the same as parent's. In other words, a component
154: * is added to a page automatically if it becomes a child of
155: * another component (who belongs to a page).
156: *
157: * <p>For root components, you have to invoke {@link #setPage}
158: * explicityly.
159: *
160: * @see #setParent
161: * @see #setPage
162: */
163: public Page getPage();
164:
165: /** Sets what page this component belongs to.
166: * If this component already belongs to the same page, nothing
167: * is changed.
168: *
169: * <p>For child components, the page they belong is maintained
170: * automatically. You need to invoke this method only for root
171: * components.
172: */
173: public void setPage(Page page);
174:
175: /** Sets what page this component belongs to, and insert
176: * this component right before the reference component.
177: *
178: * <p>For child components, the page they belong is maintained
179: * automatically. You need to invoke this method only for root
180: * components.
181: *
182: * <p>It is similar to {@link #setPage}, except this component
183: * will be placed before the reference component.
184: * If the reference component is null, this component is placed
185: * at the end of all root components.
186: *
187: * @param refRoot another root component used as a reference
188: * which this component will be placed before.
189: * If null, this component will be placed at the end of all
190: * root components (no matter whether it already belongs to the same page).
191: * @since 3.0.0
192: */
193: public void setPageBefore(Page page, Component refRoot);
194:
195: /** Returns UUID (universal unique ID) which is unquie in the whole
196: * session. The UUID is generated automatically and immutable, unless
197: * {@link org.zkoss.zk.ui.ext.RawId} is also implemented.
198: *
199: * <p>It is mainly used for communication between client and server
200: * and you rarely need to access it.
201: *
202: * <p>If {@link org.zkoss.zk.ui.ext.RawId} is implemented as part of
203: * a component, UUID is the same as {@link #getId} if {@link #setId}
204: * is ever called. It is designed to migrate HTML pages to ZK, such
205: * that the element ID could remain the same.
206: */
207: public String getUuid();
208:
209: /** Returns a component of the specified ID in the same ID space.
210: * Components in the same ID space are called fellows.
211: *
212: * <p>Unlike {@link #getFellowIfAny}, it throws an exception if not found.
213: *
214: * @exception ComponentNotFoundException is thrown if fellow not found
215: */
216: public Component getFellow(String id);
217:
218: /** Returns a component of the specified ID in the same ID space, or null
219: * if not found.
220: * <p>Unlike {@link #getFellow}, it returns null if not found.
221: */
222: public Component getFellowIfAny(String id);
223:
224: /** Returns the next sibling, or null if it is the last child.
225: * @since 3.0.0
226: */
227: public Component getNextSibling();
228:
229: /** Returns the previous sibling, or null if it is the first child.
230: * @since 3.0.0
231: */
232: public Component getPreviousSibling();
233:
234: /** Returns the first child component, or null if no child at all.
235: * @since 3.0.0
236: */
237: public Component getFirstChild();
238:
239: /** Returns the last child component, or null if no child at all.
240: * @since 3.0.0
241: */
242: public Component getLastChild();
243:
244: /** Used with {@link #getAttribute} and relevants to denote
245: * custom attributes private to a component is searched.
246: * <p>It is also known as the component attributes.
247: * <p>It is the same as {@link Component#getAttributes}.
248: */
249: public static final int COMPONENT_SCOPE = 0;
250: /** Used with {@link #getAttribute} and relevants to denote
251: * custom attributes shared by the same ID space.
252: * <p>It is also known as the ID space attributes.
253: */
254: public static final int SPACE_SCOPE = 1;
255: /** Used with {@link #getAttribute} and relevants to denote
256: * custom attributes shared by the same page.
257: * <p>It is also known as the page attributes.
258: * <p>It is the same as {@link Page#getAttributes}.
259: */
260: public static final int PAGE_SCOPE = 2;
261: /** Used with {@link #getAttribute} and relevants to denote
262: * custom attributes shared by the same desktop.
263: * <p>It is also known as the desktop attributes.
264: * <p>It is the same as {@link Desktop#getAttributes}.
265: */
266: public static final int DESKTOP_SCOPE = 3;
267: /** Used with {@link #getAttribute} and relevants to denote
268: * custom attributes shared by the same session.
269: * <p>It is also known as the session attributes.
270: * <p>It is the same as {@link Session#getAttributes}.
271: */
272: public static final int SESSION_SCOPE = 4;
273: /** Used with {@link #getAttribute} and relevants to denote
274: * custom attributes shared by the whole application.
275: * <p>It is also known as the application attributes.
276: * <p>It is the same as {@link WebApp#getAttributes}.
277: */
278: public static final int APPLICATION_SCOPE = 5;
279: /** Used with {@link #getAttribute} and relevants to denote
280: * custom attributes shared by the same request.
281: * <p>It is also known as the request attributes.
282: * <p>It is the same as {@link Execution#getAttributes}.
283: */
284: public static final int REQUEST_SCOPE = 6;
285:
286: /** Returns all custom attributes of the specified scope.
287: * You could reference them thru componentScope, spaceScope, pageScope,
288: * requestScope and desktopScope in zscript and EL.
289: *
290: * <p>If scope is {@link #COMPONENT_SCOPE}, it means custom attributes private
291: * to this component.
292: * <p>If scope is {@link #SPACE_SCOPE}, it means custom attributes shared
293: * by components from the same ID space as this one's.
294: * <p>If scope is {@link #PAGE_SCOPE}, it means custom attributes shared
295: * by components from the same page as this one's.
296: * <p>If scope is {@link #DESKTOP_SCOPE}, it means custom attributes shared
297: * by components from the same desktopas this one's.
298: *
299: * @param scope {@link #COMPONENT_SCOPE}, {@link #SPACE_SCOPE},
300: * {@link #PAGE_SCOPE}, {@link #DESKTOP_SCOPE}, {@link #SESSION_SCOPE},
301: * {@link #REQUEST_SCOPE} or {@link #APPLICATION_SCOPE},
302: */
303: public Map getAttributes(int scope);
304:
305: /** Returns the value of the specified custom attribute in the specified scope,
306: * or null if not defined.
307: *
308: * <p>If scope is {@link #COMPONENT_SCOPE}, it means attributes private
309: * to this component.
310: * <p>If scope is {@link #SPACE_SCOPE}, it means custom attributes shared
311: * by components from the same ID space as this one's.
312: * <p>If scope is {@link #PAGE_SCOPE}, it means custom attributes shared
313: * by components from the same page as this one's.
314: * <p>If scope is {@link #DESKTOP_SCOPE}, it means custom attributes shared
315: * by components from the same desktopas this one's.
316: *
317: * @param scope {@link #COMPONENT_SCOPE}, {@link #SPACE_SCOPE},
318: * {@link #PAGE_SCOPE}, {@link #DESKTOP_SCOPE}, {@link #SESSION_SCOPE},
319: * {@link #REQUEST_SCOPE} or {@link #APPLICATION_SCOPE},
320: */
321: public Object getAttribute(String name, int scope);
322:
323: /** Sets the value of the specified custom attribute in the specified scope.
324: *
325: * <p>Note: The attribute is removed (by {@link #removeAttribute}
326: * if value is null, while {@link #setVariable} considers null as a legal value.
327: *
328: * <p>If scope is {@link #COMPONENT_SCOPE}, it means custom attributes private
329: * to this component.
330: * <p>If scope is {@link #SPACE_SCOPE}, it means custom attributes shared
331: * by components from the same ID space as this one's.
332: * <p>If scope is {@link #PAGE_SCOPE}, it means custom attributes shared
333: * by components from the same page as this one's.
334: * <p>If scope is {@link #DESKTOP_SCOPE}, it means custom attributes shared
335: * by components from the same desktopas this one's.
336: *
337: * @param scope {@link #COMPONENT_SCOPE}, {@link #SPACE_SCOPE},
338: * {@link #PAGE_SCOPE}, {@link #DESKTOP_SCOPE}, {@link #SESSION_SCOPE},
339: * {@link #REQUEST_SCOPE} or {@link #APPLICATION_SCOPE},
340: * @param value the value. If null, the attribute is removed.
341: */
342: public Object setAttribute(String name, Object value, int scope);
343:
344: /** Removes the specified custom attribute in the specified scope.
345: * <p>If scope is {@link #COMPONENT_SCOPE}, it means attributes private
346: * to this component.
347: * <p>If scope is {@link #SPACE_SCOPE}, it means custom attributes shared
348: * by components from the same ID space as this one's.
349: * <p>If scope is {@link #PAGE_SCOPE}, it means custom attributes shared
350: * by components from the same page as this one's.
351: * <p>If scope is {@link #DESKTOP_SCOPE}, it means custom attributes shared
352: * by components from the same desktopas this one's.
353: *
354: * @param scope {@link #COMPONENT_SCOPE}, {@link #SPACE_SCOPE},
355: * {@link #PAGE_SCOPE}, {@link #DESKTOP_SCOPE}, {@link #SESSION_SCOPE},
356: * {@link #REQUEST_SCOPE} or {@link #APPLICATION_SCOPE},
357: */
358: public Object removeAttribute(String name, int scope);
359:
360: /** Returns all custom attributes associated with this component, i.e.,
361: * {@link #COMPONENT_SCOPE}.
362: */
363: public Map getAttributes();
364:
365: /** Returns the custom attribute associated with this component, i.e.,
366: * {@link #COMPONENT_SCOPE}.
367: */
368: public Object getAttribute(String name);
369:
370: /** Sets the custom attribute associated with this component, i.e.,
371: * {@link #COMPONENT_SCOPE}.
372: */
373: public Object setAttribute(String name, Object value);
374:
375: /** Removes the custom attribute associated with this component, i.e.,
376: * {@link #COMPONENT_SCOPE}.
377: */
378: public Object removeAttribute(String name);
379:
380: /** Sets a variable to the namespace.
381: *
382: * <p>This method is the same as
383: * getNamespace().setVariable(name, value, local).
384: *
385: * <p>Once a variable is set thru this method, it is visible to
386: * both the interpreter and EL.
387: *
388: * <p>Note: Exactly one namespace is allocated for each ID space.
389: * For example, if the space owner of this component is the page, then
390: * the returned namespace is the same as {@link Page#getNamespace}.
391: * Otherwise, it is the same as the namspace returned by the component
392: * owning this ID space.
393: *
394: * <h3>When to use setVariable and setAttribute?</h3>
395: *
396: * <p>First, only the ID space support {@link #setVariable} and so.
397: * Second, the variables can be referenced directly in zscript and EL
398: * expressions, while attributes are referenced thru the scope,
399: * such as spaceScope.
400: * On the other hand, using attributes causes less name popultion.
401: * In general, if you could use attributes, don't use variable.
402: *
403: * @param local whether not to search any of the ancestor namespace defines
404: * the variable. If local is false and an ancesotor has defined a variable
405: * with the same name, the variable in the ancestor is changed directly.
406: * Otherwise, a new variable is created in the namespace containing
407: * this component.
408: * @see #getSpaceOwner
409: * @see #getNamespace
410: */
411: public void setVariable(String name, Object val, boolean local);
412:
413: /** Returns whether the specified variable is defined.
414: *
415: * <p>Note: null is a valid value for variable, so this method is used
416: * to know whether a variable is defined.
417: * On the other hand, {@link #setAttribute} actually remove
418: * an attribute (by {@link #removeAttribute} if value is null.
419: *
420: * @param local whether not to search its ancestor.
421: * If false and the current namespace doen't define the variable,
422: * it searches up its ancestor (via {@link #getParent}) to see
423: * any of them has defined the specified variable.
424: */
425: public boolean containsVariable(String name, boolean local);
426:
427: /** Returns the value of a variable defined in the namespace,
428: * or null if not defined or the value is null.
429: *
430: * <p>This method is the same as getNamespace().getVariable(name, local).
431: *
432: * <h3>Differences between {@link #getVariable} and {@link Page#getZScriptVariable}</h3>
433: *
434: * <p>{@link #getVariable} returns only variables defined by
435: * {@link #setVariable} (i.e., a shortcut of {@link Namespace#setVariable}).
436: * On the other hand, {@link Page#getZScriptVariable} returns these variables
437: * and those defined when executing zscripts.
438: *
439: * @param local whether not to search its ancestor.
440: * If false and the current namespace doen't define the variable,
441: * it searches up its ancestor (via {@link #getParent}) to see
442: * any of them has defined the specified variable.
443: * @see #getSpaceOwner
444: * @see #getNamespace
445: */
446: public Object getVariable(String name, boolean local);
447:
448: /** Unsets a variable defined in the namespace.
449: *
450: * <p>This method is the same as getNamespace().getVariable(name, local).
451: *
452: * @param local whether not to search its ancestor.
453: * If false and the current namespace doen't define the variable,
454: * it searches up its ancestor (via {@link #getParent}) to see
455: * any of them has defined the specified variable.
456: * @see #getSpaceOwner
457: * @see #getNamespace
458: */
459: public void unsetVariable(String name, boolean local);
460:
461: /** Returns the parent component, or null if this is the root component.
462: */
463: public Component getParent();
464:
465: /** Sets the parent component.
466: *
467: * <p>Note: {@link #setParent} always calls back {@link #insertBefore}
468: * and/or {@link #removeChild},
469: * while {@link #insertBefore} and {@link #removeChild}
470: * always calls back {@link #setParent},
471: * if the parent is changed. Thus, you don't need to override
472: * both {@link #insertBefore} and {@link #setParent}, if you want
473: * to customize the behavior.
474: */
475: public void setParent(Component parent);
476:
477: /** Returns a live list of children.
478: * You could add or remove a child by manipulating the returned list directly.
479: */
480: public List getChildren();
481:
482: /** Returns the root of this component.
483: */
484: public Component getRoot();
485:
486: /** Returns whether this component is visible.
487: * @see Components#isRealVisible
488: */
489: public boolean isVisible();
490:
491: /** Sets whether this component is visible.
492: *
493: * @return the previous visibility
494: */
495: public boolean setVisible(boolean visible);
496:
497: /** Inserts a child before the reference child.
498: *
499: * <p>You could use {@link #setParent} or {@link #appendChild}
500: * instead of this method, unless
501: * you want to control where to put the child.
502: *
503: *
504: * <p>Note: {@link #setParent} always calls back {@link #insertBefore}
505: * and/or {@link #removeChild},
506: * while {@link #insertBefore} and {@link #removeChild}
507: * always calls back {@link #setParent},
508: * if the parent is changed. Thus, you don't need to override
509: * both {@link #insertBefore} and {@link #setParent}, if you want
510: * to customize the behavior.
511: *
512: * @param newChild the new child to be inserted.
513: * @param refChild the child before which you want the new child
514: * being inserted. If null, the new child is append to the end.
515: * @return true if newChild is added successfully or moved;
516: * false if it already has the specified child and the order doesn't
517: * change.
518: */
519: public boolean insertBefore(Component newChild, Component refChild);
520:
521: /** Appends a child.
522: * A shortcut to insertBefore(child, null).
523: *
524: * @see #insertBefore
525: */
526: public boolean appendChild(Component child);
527:
528: /** Removes a child. The child is not actually removed.
529: * Rather, it is detached (see {@link #detach}) and it will be removed
530: * if it is no longer used.
531: *
532: * <p>You could use {@link #setParent} with null instead of this method.
533: *
534: * <p>Note: {@link #setParent} always calls back {@link #insertBefore}
535: * and/or {@link #removeChild},
536: * while {@link #insertBefore} and {@link #removeChild}
537: * always calls back {@link #setParent},
538: * if the parent is changed. Thus, you don't need to override
539: * both {@link #insertBefore} and {@link #setParent}, if you want
540: * to customize the behavior.
541: *
542: * @return true if child is removed successfully; false if it doesn't
543: * have the specified child
544: */
545: public boolean removeChild(Component child);
546:
547: /** Detaches this component such that it won't belong to any page.
548: * If you don't call {@link #setParent} or {@link #setPage} to
549: * attach it to any page, it will be removed automatically
550: * (from the client) after the current event is processed.
551: */
552: public void detach();
553:
554: /** Called when a child is added.
555: * If a component want to optimize the update, it might do something
556: * different. Otherwise, it does nothing.
557: *
558: * <p>Note: {@link #onChildAdded} is called in the request-processing
559: * phase, while {@link #onDrawNewChild} is called in the redrawing phase.
560: * See {@link #onDrawNewChild} for more details.
561: *
562: * <p>It is not a good idea to throw an exception in this method, since
563: * it is in the middle of modifying the component tree.
564: */
565: public void onChildAdded(Component child);
566:
567: /** Called when a child is removed.
568: * If a component want to optimize the update, it might do something
569: * different. Otherwise, it simply does nothing.
570: *
571: * <p>It is not a good idea to throw an exception in this method, since
572: * it is in the middle of modifying the component tree.
573: */
574: public void onChildRemoved(Component child);
575:
576: /** Called when this component is attached to a page.
577: *
578: * <p>If a component is moved from one page to another,
579: * {@link #onPageAttached} is called with both pages.
580: * Note: {@link #onPageDetached} is not called in this case.
581: *
582: * <p>Note: this method is called even if the component is attached
583: * to a page implicitly thru, say, {@link #setParent}.
584: *
585: * <p>It is not a good idea to throw an exception in this method, since
586: * it is in the middle of modifying the component tree.
587: *
588: * @param newpage the new page (never null).
589: * @param oldpage the previous page, if any, or null if it didn't
590: * belong to any page.
591: * @since 3.0.0
592: */
593: public void onPageAttached(Page newpage, Page oldpage);
594:
595: /** Called when this component is detached from a page.
596: *
597: * <p>If a component is moved from one page to another,
598: * {@link #onPageAttached} is called with both pages.
599: * Note: {@link #onPageDetached} is not called in this case.
600: * In other words, {@link #onPageDetached} is called only if a component
601: * is detached from a page (not belong to any other page).
602: *
603: * <p>Note: this method is called even if the component is detached
604: * to a page implicitly thru, say, {@link #setParent}.
605: *
606: * <p>It is not a good idea to throw an exception in this method, since
607: * it is in the middle of modifying the component tree.
608: *
609: * @param page the previous page (never null)
610: * @since 3.0.0
611: */
612: public void onPageDetached(Page page);
613:
614: /** Returns the mold for this component.
615: * <p>Default: "default"
616: *
617: * @see org.zkoss.zk.ui.metainfo.ComponentDefinition
618: */
619: public String getMold();
620:
621: /** Sets the mold for this component.
622: *
623: * @param mold the mold. If null or empty, "default" is assumed.
624: * @see org.zkoss.zk.ui.metainfo.ComponentDefinition
625: */
626: public void setMold(String mold);
627:
628: //-- event listener --//
629: /** Adds an event listener to specified event for this component.
630: * The second registration is ignored and false is returned.
631: *
632: * <p>You could register listener to all components in the same page
633: * by use of {@link Page#addEventListener}.
634: *
635: * @param evtnm what event to listen (never null)
636: * @return whether the listener is added; false if it was added before
637: * @see Page#addEventListener
638: */
639: public boolean addEventListener(String evtnm, EventListener listener);
640:
641: /** Removes an event listener.
642: * @return whether the listener is removed; false if it was never added.
643: */
644: public boolean removeEventListener(String evtnm,
645: EventListener listener);
646:
647: /** Returns whether the event listener is available.
648: *
649: * <p>Unlike {@link org.zkoss.zk.ui.event.Events#isListened},
650: * this method checks only the event listener registered by
651: * {@link #addEventListener}.
652: *
653: * @param asap whether to check only non-deferrable listener,
654: * i.e., not implementing {@link org.zkoss.zk.ui.event.Deferrable},
655: * or {@link org.zkoss.zk.ui.event.Deferrable#isDeferrable} is false.
656: * @see org.zkoss.zk.ui.event.Deferrable
657: * @see org.zkoss.zk.ui.event.Events#isListened
658: * @see Component#addEventListener
659: */
660: public boolean isListenerAvailable(String evtnm, boolean asap);
661:
662: /** Returns an iterator for iterating listener for the specified event.
663: */
664: public Iterator getListenerIterator(String evtnm);
665:
666: /** Adds a forward condition to forward the event received
667: * by this component to another component.
668: *
669: * <p>Default: no forward condition at all.
670: *
671: * <p>Once the condition is added, a event called <code>targetEvent</code>
672: * is posted to the <code>target</code> compoennt,
673: * when this component receives the <code>orginalEvent</code> event.
674: *
675: * @param originalEvent the original event that was received
676: * by this component. If null, "onClick" is assumed.
677: * @param target the target component to receive the event.
678: * If null, the space owner {@link #getSpaceOwner} is assumed.
679: * If null and the space owner is the page, the root component is assumed.
680: * @param targetEvent the target event that the target component
681: * will receive.
682: * If null, it is the same as the original event.
683: * @return whether it is added successfully.
684: * It returns false if the conditioin was always added before.
685: * @since 3.0.0
686: * @see #removeForward(String, Component, String)
687: */
688: public boolean addForward(String originalEvent, Component target,
689: String targetEvent);
690:
691: /** Adds a forward condition to forward the event received
692: * by this component to another component, specified with a path.
693: *
694: * <p>Note: the target component is retrieved from the path, each time
695: * the event is received. Thus, you can reference to a component
696: * that is created later.
697: *
698: * @param originalEvent the original event that was received
699: * by this component. If null, "onClick" is assumed.
700: * @param targetPath the target component's path related to this component.
701: * If ".", this component is assumed.
702: * If null, the space owner is assumed.
703: * If null and the space owner is the page, the root component is assumed.
704: * @param targetEvent the target event that the target component
705: * will receive.
706: * If null, it is the same as the original event.
707: * @return whether it is added successfully.
708: * It returns false if the conditioin was always added before.
709: * @see #addForward(String, Component, String)
710: * @see #removeForward(String, String, String)
711: * @since 3.0.0
712: */
713: public boolean addForward(String originalEvent, String targetPath,
714: String targetEvent);
715:
716: /** Removes a forward condition that was added by
717: * {@link #addForward(String, Component, String)}.
718: * If no such forward condition exists, nothing happens but return false.
719: *
720: * @param originalEvent the oringal event that was received
721: * by this component.
722: * It must be the same as the one passed to {@link #addForward(String, Component, String)}.
723: * @param target the target component to receive the event.
724: * It must be the same as the one passed to {@link #addForward(String, Component, String)}.
725: * @param targetEvent the target event that the target component will receive.
726: * It must be the same as the one passed to {@link #addForward(String, Component, String)}.
727: * @return whether the forward is removed successfully.
728: * It returns false if the forward condition is not found
729: * @see #addForward(String, Component, String)
730: * @since 3.0.0
731: */
732: public boolean removeForward(String originalEvent,
733: Component target, String targetEvent);
734:
735: /** Removes a forward condition that was added by
736: * {@link #addForward(String, String, String)}.
737: * If no such forward condition exists, nothing happens but return false.
738: *
739: * @param originalEvent the oringal event that was received
740: * by this component.
741: * It must be the same as the one passed to {@link #addForward(String, Component, String)}.
742: * @param targetPath the target component's path related to this component.
743: * If ".", this component is assumed.
744: * If null, the space owner is assumed.
745: * If null and the space owner is the page, the root component is assumed.
746: * @param targetEvent the target event that the target component will receive.
747: * It must be the same as the one passed to {@link #addForward(String, Component, String)}.
748: * @return whether the forward is removed successfully.
749: * It returns false if the forward condition is not found
750: * @see #addForward(String, String, String)
751: * @since 3.0.0
752: */
753: public boolean removeForward(String originalEvent,
754: String targetPath, String targetEvent);
755:
756: //-- drawing --//
757: /** Invalidates this component by setting the dirty flag
758: * such that it will be redraw the whole content later.
759: *
760: * <p>It can be called only in the request-processing and event-processing
761: * phases; excluding the redrawing phase.
762: *
763: * <p>There are two ways to draw a component, one is to invoke
764: * {@link #invalidate()}, and the other is {@link #smartUpdate}.
765: * While {@link #invalidate()} causes the whole content to redraw,
766: * {@link #smartUpdate} let component developer control which part
767: * to redraw.
768: *
769: * <p>Once this method is called, all invocations to {@link #smartUpdate}
770: * will then be ignored, and {@link Component#redraw} will be invoked later.
771: */
772: public void invalidate();
773:
774: /** Smart-updates a property with the specified value.
775: * Called by component developers to do precise-update.
776: *
777: * <p>The second invocation with the same property will replace the previous
778: * call. In other words, the same property will be set only once in
779: * each execution.
780: *
781: * <p>This method has no effect if {@link #invalidate()} is ever invoked
782: * (during this execution).
783: *
784: * <p>It can be called only in the request-processing and event-processing
785: * phases; excluding the redrawing phase.
786: *
787: * <p>There are two ways to draw a component, one is to invoke
788: * {@link #invalidate()}, and the other is {@link #smartUpdate}.
789: * While {@link #invalidate()} causes the whole content to redraw,
790: * {@link #smartUpdate} let component developer control which part
791: * to redraw.
792: *
793: * @param value the new value. If null, it means removing the property.
794: */
795: public void smartUpdate(String attr, String value);
796:
797: /** Smart-updates a property with a deferred value.
798: * A deferred value is used to encapsulate a value that shall be retrieved
799: * only in the rendering phase.
800: * In other words, {@link DeferredValue#getValue} won't be called until
801: * the rendering phase. On the other hand, this method is usually called
802: * in the event processing phase.
803: *
804: * <p>For some old application servers (example, Webshpere 5.1),
805: * {@link Execution#encodeURL} cannot be called in the event processing
806: * thread. So, the developers have to use {@link DeferredValue}
807: * or disable the use of the event processing thread
808: * (by use of <code>disable-event-thread</code> in zk.xml).
809: *
810: * @since 3.0.1
811: */
812: public void smartUpdateDeferred(String attr, DeferredValue value);
813:
814: /** Causes a response (aka., a command) to be sent to the client.
815: *
816: * <p>If {@link AuResponse#getDepends} is not null, the response
817: * depends on the existence of the returned componet.
818: * In other words, the response is removed if the component is removed.
819: * If it is null, the response is component-independent and it is
820: * always sent to the client.
821: *
822: * <p>Unlike {@link #smartUpdate}, responses are sent to client if
823: * it is component independent or it is not removed.
824: * In other words, it is sent even if {@link #invalidate()} was called.
825: * Typical examples include setting the focus, selecting the text and so on.
826: *
827: * <p>It can be called only in the request-processing and event-processing
828: * phases; excluding the redrawing phase.
829: *
830: * @param key could be anything.
831: * The second invocation of this method
832: * in the same execution with the same key will override the previous one.
833: * However, if key is null, it won't override any other. All responses
834: * with key == null will be sent.
835: */
836: public void response(String key, AuResponse response);
837:
838: /** AuRequest this component to render (aka., redraw) itself
839: * and its children.
840: *
841: * <p>It is called in the redrawing phase by the kernel, so it is too late
842: * to call {@link #invalidate()} or {@link #smartUpdate} in this method.
843: */
844: public void redraw(Writer out) throws IOException;
845:
846: /** Called when a new-created child is about to render.
847: * It gives the parent a chance to fine-tune the output.
848: * Note: it won't be called if the parent is rendered, too.
849: * In other words, it is called only if the child is attached dynamically.
850: *
851: * <p>It is called in the redrawing phase by the kernel, so it is too late
852: * to call {@link #invalidate()} or {@link #smartUpdate} in this method.
853: *
854: * <p>Note: {@link #onChildAdded} is called in the request-processing
855: * phase, while {@link #onDrawNewChild} is called in the redrawing phase.
856: * Component developer might do one of the follows:
857: * <ul>
858: * <li>Nothing, if new child can be inserted directly.</li>
859: * <li>Overwrite {@link #onDrawNewChild} to add special tags, if
860: * new child needs to be added an exterior with some tags before
861: * insertion.<br>
862: * Morever, if you shall add id="${child.uuid}!chdextr" to the added
863: * exterior.</li>
864: * <li>Redraw the parent, if it is too complicated.
865: * How: overwrite {@link #onChildAdded} and calls {@link #invalidate()}</li>
866: * </ul>
867: *
868: * @param child the child being rendered
869: * @param out the rendered result of the child.
870: */
871: public void onDrawNewChild(Component child, StringBuffer out)
872: throws IOException;
873:
874: /** Returns whether this component allows to have any child.
875: */
876: public boolean isChildable();
877:
878: /** Returns the namespace to store variables and functions belonging
879: * to the ID space of this component.
880: *
881: * <p>Exactly one namespace is allocated for each ID space.
882: * For example, if the space owner of this component is the page, then
883: * the returned namespace is the same as {@link Page#getNamespace}.
884: * Otherwise, it is the same as the namspace returned by the component
885: * owning this ID space.
886: *
887: * <p>Namspace is another part of an ID space. It holds only variables
888: * defined thru {@link #setVariable} (and {@link Namespace#setVariable}.
889: *
890: * <p>Note: The namespace doesn't include any variable defined by
891: * executing zscripts. To retrieve them, use {@link Page#getZScriptVariable}.
892: *
893: * @see #getSpaceOwner
894: */
895: public Namespace getNamespace();
896:
897: /** Initializes the properties (aka. members) and custom-attributes
898: * based on what are defined in the component definition.
899: *
900: * <p>This method is invoked automatically if a component is created
901: * by evaluating a ZUML page, i.e., if it is specified as an elemnt
902: * of a ZUML page.
903: *
904: * <p>On the other hand, if it is created manually (by program),
905: * developer might choose to invoke this method or not,
906: * depending whether he wants to
907: * initializes the component with the properties and custom-attributes
908: * defined in the ZUML page ({@link org.zkoss.zk.ui.metainfo.PageDefinition})
909: * and the language definition ({@link org.zkoss.zk.ui.metainfo.LanguageDefinition}).
910: */
911: public void applyProperties();
912:
913: /** Clones the component.
914: * All of its children is cloned.
915: * Notice that the cloned component doesn't belong to any page, nor
916: * desktop. It doesn't have parent, either.
917: */
918: public Object clone();
919: }
|