001: /*
002: #IFNDEF ALT_LICENSE
003: ThinWire(R) RIA Ajax Framework
004: Copyright (C) 2003-2007 Custom Credit Systems
005:
006: This library is free software; you can redistribute it and/or modify it under
007: the terms of the GNU Lesser General Public License as published by the Free
008: Software Foundation; either version 2.1 of the License, or (at your option) any
009: later version.
010:
011: This library is distributed in the hope that it will be useful, but WITHOUT ANY
012: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
013: PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
014:
015: You should have received a copy of the GNU Lesser General Public License along
016: with this library; if not, write to the Free Software Foundation, Inc., 59
017: Temple Place, Suite 330, Boston, MA 02111-1307 USA
018:
019: Users who would rather have a commercial license, warranty or support should
020: contact the following company who invented, built and supports the technology:
021:
022: Custom Credit Systems, Richardson, TX 75081, USA.
023: email: info@thinwire.com ph: +1 (888) 644-6405
024: http://www.thinwire.com
025: #ENDIF
026: [ v1.2_RC2 ]
027: */
028: package thinwire.ui;
029:
030: import thinwire.ui.event.ActionEvent;
031: import thinwire.ui.event.ActionListener;
032: import thinwire.ui.event.DropEvent;
033: import thinwire.ui.event.DropListener;
034: import thinwire.ui.event.KeyPressEvent;
035: import thinwire.ui.event.KeyPressListener;
036: import thinwire.ui.event.PropertyChangeListener;
037: import thinwire.ui.style.Style;
038:
039: /**
040: * <code>Component</code> is the foundation of all visual objects in the framework. A visual object is one that
041: * offers a user interface that can be displayed and interacted with by a user. The common
042: * capabilities of all visual objects are defined by this object. This includes methods for setting
043: * and getting common spatial and focus properites as well as support for adding event listeners
044: * that receive notification of property and keypress state changes.
045: * <p>
046: * Since Component is an interface, you do not actually create an instance of it directly, instead you create an instance of
047: * one of its sub-classes, such as <code>Button</code>, <code>TextField</code> or <code>Label</code>.
048: * </p>
049: * <p>
050: * <b>Keyboard Navigation:</b><br>
051: * <table border="1">
052: * <tr><td>KEY</td><td>RESPONSE</td><td>NOTE</td></tr>
053: * <tr><td>Tab</td><td>Transitions to the next focus capable <code>Component</code></td><td>See {@link #setFocus(boolean)} for details.</td></tr>
054: * <tr><td>Shift-Tab</td><td>Transitions to the prior focus capable <code>Component</code></td><td>See {@link #setFocus(boolean)} for details.</td></tr>
055: * </table>
056: * </p>
057: * @author Joshua J. Gertzen
058: */
059: public interface Component {
060: /**
061: * Contains the formal property name for the 'X' coordinate of a <code>Component</code>.
062: * @see #setX(int)
063: * @see #getX()
064: */
065: public static final String PROPERTY_X = "x";
066:
067: /**
068: * Contains the formal property name for the 'Y' coordinate of a <code>Component</code>.
069: * @see #setY(int)
070: * @see #getY()
071: */
072: public static final String PROPERTY_Y = "y";
073:
074: /**
075: * Contains the formal property name for the width of a <code>Component</code>.
076: * @see #setWidth(int)
077: * @see #getWidth()
078: */
079: public static final String PROPERTY_WIDTH = "width";
080:
081: /**
082: * Contains the formal property name for the height of a <code>Component</code>.
083: * @see #setHeight(int)
084: * @see #getHeight()
085: */
086: public static final String PROPERTY_HEIGHT = "height";
087:
088: /**
089: * Contains the formal property name for the layout manager limit of a component.
090: * @see #setLimit(Object)
091: * @see #getLimit()
092: */
093: public static final String PROPERTY_LIMIT = "limit";
094:
095: /**
096: * Contains the formal property name for the visible state of a <code>Component</code>.
097: * @see #setVisible(boolean)
098: * @see #isVisible()
099: */
100: public static final String PROPERTY_VISIBLE = "visible";
101:
102: /**
103: * Contains the formal property name for the enabled state of a <code>Component</code>.
104: * @see #setEnabled(boolean)
105: * @see #isEnabled()
106: */
107: public static final String PROPERTY_ENABLED = "enabled";
108:
109: /**
110: * Contains the formal property name for the focus capability of a <code>Component</code>.
111: * @see #setFocusCapable(boolean)
112: * @see #isFocusCapable()
113: */
114: public static final String PROPERTY_FOCUS_CAPABLE = "focusCapable";
115:
116: /**
117: * Contains the formal property name for the focus state of a <code>Component</code>.
118: * @see #setFocus(boolean)
119: * @see #isFocus()
120: */
121: public static final String PROPERTY_FOCUS = "focus";
122:
123: /**
124: * Contains the formal property name for the user object of a <code>Component</code>.
125: * @see #setUserObject(Object)
126: * @see #getUserObject()
127: */
128: public static final String PROPERTY_USER_OBJECT = "userObject";
129:
130: /**
131: * Contains the formal action name for a click performed on a <code>Component</code>.
132: * @see #addActionListener(String, ActionListener)
133: * @see #addActionListener(String[], ActionListener)
134: * @see #removeActionListener(ActionListener)
135: * @see #fireAction(ActionEvent)
136: */
137: public static final String ACTION_CLICK = "click";
138:
139: /**
140: * Contains the formal action name for a double click performed on a <code>Component</code>.
141: * @see #addActionListener(String, ActionListener)
142: * @see #addActionListener(String[], ActionListener)
143: * @see #removeActionListener(ActionListener)
144: * @see #fireAction(ActionEvent)
145: */
146: public static final String ACTION_DOUBLE_CLICK = "doubleClick";
147:
148: /**
149: * Adds a <code>PropertyChangeListener</code> to this componetn that will be notified when the specified property changes.
150: * Adding a property listener to a component allows your code to react to a state change within the component. <br>
151: * <b>Example:</b>
152: *
153: * <pre>
154: * final TextField tf = new TextField();
155: * tf.setEnabled(false);
156: *
157: * CheckBox cb = new CheckBox("Check me to enable the TextField.");
158: * cb.addPropertyChangeListener(CheckBox.PROPERTY_CHECKED, new PropertyChangeListener() {
159: * public void propertyChange(PropertyChangeEvent pce) {
160: * if (pce.getNewValue() == Boolean.TRUE) {
161: * tf.setEnabled(true);
162: * } else {
163: * tf.setEnabled(false);
164: * }
165: * }
166: * });
167: * </pre>
168: *
169: * @param propertyName the name of the property that the listener will receive change events for.
170: * @param listener the listener that will receive <code>PropertyChangeEvent</code> objects upon the property changing.
171: * @throws IllegalArgumentException if <code>listener</code> or <code>propertyName</code> is null or if
172: * <code>propertyName</code> is an empty string.
173: * @see thinwire.ui.event.PropertyChangeListener
174: * @see thinwire.ui.event.PropertyChangeEvent
175: */
176: void addPropertyChangeListener(String propertyName,
177: PropertyChangeListener listener);
178:
179: /**
180: * Adds a <code>PropertyChangeListener</code> to this component that will be notified when any of the specified properties
181: * change. This method is equivalent to calling {@link #addPropertyChangeListener(String, PropertyChangeListener)} once
182: * for each property you want to listen to.
183: * @param propertyNames a string array of property names that the listener will receive change events for.
184: * @param listener the listerner that will receive <code>PropertyChangeEvent</code> objects anytime one of the specified
185: * propertyNames of this component change.
186: * @throws IllegalArgumentException if <code>listener</code>, <code>propertyNames</code> or any property name is the array
187: * is null or if any property name is an empty string.
188: * @see #addPropertyChangeListener(String, PropertyChangeListener)
189: * @see thinwire.ui.event.PropertyChangeListener
190: * @see thinwire.ui.event.PropertyChangeEvent
191: */
192: void addPropertyChangeListener(String[] propertyNames,
193: PropertyChangeListener listener);
194:
195: /**
196: * Removes the specified <code>PropertyChangeListener</code> from the component. If the listener was added for multiple
197: * properties, it will be removed for all of them. NOTE: An exception is NOT thrown if you attempt to remove a listener that
198: * does not exist on this component.
199: * @param listener the listener to remove from the component.
200: * @throws IllegalArgumentException if <code>listener</code> is null.
201: * @see thinwire.ui.event.PropertyChangeListener
202: */
203: void removePropertyChangeListener(PropertyChangeListener listener);
204:
205: /**
206: * Adds a <code>ActionListener</code> to this component that will be notified when the specified action occurs.
207: * @param action the action to specficially be notified of.
208: * @param listener the event listener that will receive notification.
209: */
210: void addActionListener(String action, ActionListener listener);
211:
212: /**
213: * Adds a <code>ActionListener</code> to this component that will be notified when any of the specified actions occur.
214: * @param actions the actions to specficially be notified of.
215: * @param listener the event listener that will receive notification.
216: */
217: void addActionListener(String[] actions, ActionListener listener);
218:
219: /**
220: * Unregister an <code>ActionListener</code> from all action event notifications from this component.
221: * @param listener the listener that should no longer receive action event notifications.
222: */
223: void removeActionListener(ActionListener listener);
224:
225: /**
226: * Programmatically signals an action which triggers the appropriate listener which calls
227: * the desired method.
228: * @param ev the event to signal
229: */
230: void fireAction(ActionEvent ev);
231:
232: /**
233: * A convenience method that is equal to this.fireAction(new ActionEvent(this, action));
234: * @param action the action to perform on the component.
235: */
236: void fireAction(String action);
237:
238: /**
239: * A convenience method that is equal to this.fireAction(new ActionEvent(this, action));
240: * @param action the action to perform on the component.
241: */
242: void fireAction(String action, Object source);
243:
244: void addDropListener(Component dragSource, DropListener listener);
245:
246: void addDropListener(Component[] dragSources, DropListener listener);
247:
248: void removeDropListener(DropListener listener);
249:
250: void fireDrop(DropEvent ev);
251:
252: void fireDrop(Component dragComponent);
253:
254: void fireDrop(Component dragComponent, Object dragObject);
255:
256: /**
257: * Adds a <code>KeyPressListener</code> that will be notified when the specified key press combination occurs.
258: * <p>
259: * For a description and list of valid <code>keyPressCombo</code> strings, see the documentation for
260: * {@link thinwire.ui.event.KeyPressEvent#encodeKeyPressCombo(boolean, boolean, boolean, String)}.
261: * </p>
262: * <p>
263: * Establishing keyboard shortcuts for certain features can be a highly effective way to improve the efficiency of your
264: * application. If your application has a <code>Menu</code>, then typically the best way to establish such shortcuts is to
265: * simply set the <code>keyPressCombo</code> property for each <code>Menu.Item</code>. Second to that, using this method to
266: * establish shortcuts on the <code>Frame</code> or a <code>Dialog</code> will have a similar wide reaching effect.
267: * Occasionally, based on the requirements of your application, you may also use this method to establish shortcuts that are
268: * only valid when a given component has focus.
269: * </p>
270: * <b>Details:</b>
271: * <p>
272: * When a user presses a key and/or combination, the event bubbles up the component hierarchy from the component that currently
273: * has focus and is absorbed by the first <code>Component</code> that has a listener asking to be notified of that event.
274: * Therefore, if both a <code>Component</code> and a <code>Container</code> up the hierarchy are listening for the same
275: * event, only the <code>Component</code> will receive notification. There is currently no way to cause the event to continue
276: * bubbling.
277: * </p>
278: * <p>
279: * Additionally, the keyboard navigation of each <code>Component</code> cannot be overridden and you cannot receive
280: * notification of such events. As an example, establishing a <code>KeyPressListener</code> for "Space" key on the
281: * <code>CheckBox</code>, will have no effect because the "Space" key toggles the checked state of that component.
282: * </p>
283: * <p>
284: * NOTE ON WEBBROWSERS: If no <code>Component</code> is listening for a given key press, then the default behavior that the
285: * browser has associated with that key press will occur. Additionally, certain key press events in certain browsers cannot be
286: * entirely circumvented. In such a case, both the action defined by a listener and the browser's default behavior will occur.
287: * An example of this is the F1 key in Internet Explorer. If you establish a listener for the F1 key, the IE help file will open
288: * in addition to whatever action you may have defined.
289: * </p>
290: * <b>Example:</b>
291: *
292: * <pre>
293: * Application.current().getFrame().addKeyPressListener("Ctrl-Alt-M", new KeyPressListener() {
294: * public void keyPress(KeyPressEvent kpe) {
295: * MessageBox.confirm("You pressed the following key combination: " + kpe.getKeyPressCombo());
296: * }
297: * });
298: * </pre>
299: *
300: * @param keyPressCombo a key press combo in any dash separated format supported by
301: * {@link thinwire.ui.event.KeyPressEvent#normalizeKeyPressCombo(String)}.
302: * @param listener the listener that will receive <code>KeyPressEvent</code> objects upon the key press occurring.
303: * @throws IllegalArgumentException if <code>listener</code> or <code>keyPressCombo</code> is null, or if
304: * <code>keyPressCombo</code> is an empty string, or if <code>keyPressCombo</code> represents an invalid key combo.
305: * @see thinwire.ui.event.KeyPressListener
306: * @see thinwire.ui.event.KeyPressEvent
307: * @see thinwire.ui.event.KeyPressEvent#encodeKeyPressCombo(boolean, boolean, boolean, String)
308: * @see thinwire.ui.event.KeyPressEvent#normalizeKeyPressCombo(String)
309: */
310: void addKeyPressListener(String keyPressCombo,
311: KeyPressListener listener);
312:
313: /**
314: * Adds a <code>KeyPressListener</code> that will be notified when any of the specified key press combinations occur.
315: * <p>
316: * For a description and list of valid <code>keyPressCombo</code> strings, see the documentation for
317: * {@link thinwire.ui.event.KeyPressEvent#encodeKeyPressCombo(boolean, boolean, boolean, String)}.
318: * </p>
319: * <p>
320: * See {@link #addKeyPressListener(String, KeyPressListener)} for a full semantic description.
321: * </p>
322: * @param keyPressCombos a string array of key press combos, each in any dash separated format supported by
323: * {@link thinwire.ui.event.KeyPressEvent#normalizeKeyPressCombo(String)}.
324: * @param listener the listener that will receive <code>KeyPressEvent</code> objects when any of the key presses occur.
325: * @throws IllegalArgumentException if <code>listener</code> or any key press combo in <code>keyPressCombos</code> is null,
326: * or if any key press combo in <code>keyPressCombos</code> is an empty string, or if any key press combo in
327: * <code>keyPressCombos</code> represents an invalid key combo.
328: * @see #addKeyPressListener(String, KeyPressListener)
329: * @see thinwire.ui.event.KeyPressListener
330: * @see thinwire.ui.event.KeyPressEvent
331: * @see thinwire.ui.event.KeyPressEvent#encodeKeyPressCombo(boolean, boolean, boolean, String)
332: * @see thinwire.ui.event.KeyPressEvent#normalizeKeyPressCombo(String)
333: */
334: void addKeyPressListener(String[] keyPressCombos,
335: KeyPressListener listener);
336:
337: /**
338: * Removes the specified <code>KeyPressListener</code> from the component. If the listener was added for multiple
339: * key press combinations, it will be removed for all of them. NOTE: An exception is NOT thrown if you attempt to remove a listener that
340: * does not exist on this component.
341: * @param listener the listener to remove from the component.
342: * @throws IllegalArgumentException if <code>listener</code> is null.
343: * @see thinwire.ui.event.KeyPressListener
344: */
345: void removeKeyPressListener(KeyPressListener listener);
346:
347: /**
348: * Allows you to programmatically trigger a key press combination. Passing this method a valid key press combination will result
349: * in a <code>KeyPressEvent</code> being generated. As a result, all <code>KeyPressListener</code>'s that are registered on
350: * the specified <code>keyPressCombo</code> will be notified. <br>
351: * <p>
352: * For a description and list of valid <code>keyPressCombo</code> strings, see the documentation for
353: * {@link thinwire.ui.event.KeyPressEvent#encodeKeyPressCombo(boolean, boolean, boolean, String)}.
354: * </p>
355: * <b>Details:</b>
356: * <p>
357: * A <code>KeyPressEvent</code> that is generated programmatically via this mechansim may, under some circumstances, have a
358: * slightly different behavior than one generated by user activity. The reason for this is that the event is only propagated
359: * within the framework itself and does not actually occur in the client. In general, this should never be an issue because the
360: * desired response to a keypress will be expressly defined by a given <code>KeyPressListener</code> and therefore there would be
361: * no dependence on any such side-effect. However, an example of one such
362: * difference, is in terms of a browser's default behavior for a specific key press combination. If you use this mechanism
363: * to trigger an F1 keypress, the browser's default behavior (typically bringing up a help window), will not occur.
364: * </p>
365: * @throws IllegalArgumentException if <code>keyPressCombo</code> is null, or if <code>keyPressCombo</code> is an empty
366: * string, or if <code>keyPressCombo</code> represents an invalid key combo.
367: * @param ev a KeyPressEvent that represents the key press combo you want to signal has occured.
368: */
369: void fireKeyPress(KeyPressEvent ev);
370:
371: /**
372: * A convenience method that is equal to this.fireKeyPress(new KeyPressEvent(keyPressCombo, this));
373: * @param keyPressCombo a key press combo in any dash separated format supported by
374: * {@link thinwire.ui.event.KeyPressEvent#normalizeKeyPressCombo(String)}.
375: * @see thinwire.ui.event.KeyPressEvent#encodeKeyPressCombo(boolean, boolean, boolean, String)
376: * @see thinwire.ui.event.KeyPressEvent#normalizeKeyPressCombo(String)
377: */
378: void fireKeyPress(String keyPressCombo);
379:
380: /**
381: * Returns the parent <code>Object</code> of this <code>Component</code>. If you specifically need the parent
382: * <code>Container</code> of this <code>Component</code> use {@link #getContainer()} instead.
383: * <br>
384: * <b>Details:</b>
385: * <p>
386: * Under the majority of situations, the returned value is either a <code>Container</code> or <code>null</code> since a
387: * <code>Component</code> will either be a child of a <code>Container</code> or not attached to any object. However, in some
388: * cases the parent of the <code>Component</code> may be another <code>Component</code>, or a completely different kind of
389: * <code>Object</code>. For example, in the case of the <code>DropDownGridBox</code>, there is an actual
390: * <code>GridBox</code> that is a child of the drop down. Therefore, the parent of that <code>GridBox</code> would be the
391: * <code>DropDownGridBox</code>. Another situation exists when you use a multi-tiered <code>GridBox</code>, meaning a
392: * <code>GridBox</code> that has one or more "pop-up" child <code>GridBox</code>'s. Under that scenario, the parent of the
393: * child's <code>GridBox</code> is actually an instance of <code>GridBox.Row</code> and the parent of the row is the
394: * <code>GridBox</code>.
395: * </p>
396: * @return the parent <code>Object</code> of this <code>Component</code>, or <code>null</code> if no parent exists.
397: * @see #getContainer()
398: */
399: Object getParent();
400:
401: /**
402: * Returns the parent <code>Container</code> of this <code>Component</code>. Unlike <code>getParent()</code>, this
403: * method guarantees that if a non-null value is returned, it will be a <code>Contaienr</code>.
404: * @return the parent <code>Container</code> of this <code>Component</code>, or <code>null</code> if no parent exists.
405: * @throws IllegalStateException if in the process of walking up the parent hierarchy, an unrecognized parent type is found.
406: * @see #getParent()
407: */
408: Container getContainer();
409:
410: /**
411: * Returns the <code>Label</code> assigned to this <code>Component</code>. This property is part of a two-way relationship
412: * that is established by the {@link thinwire.ui.Label#setLabelFor(Component)} property. There is no <code>setLabel</code>
413: * method, instead use {@link thinwire.ui.Label#setLabelFor(Component)}.
414: * @return the <code>Label</code> assigned to this <code>Component</code>.
415: */
416: Label getLabel();
417:
418: /**
419: * Returns the user defined <code>Object</code> for this <code>Component</code>.
420: * <br>
421: * <b>Default:</b> null
422: * @return the user defined <code>Object</code> for this <code>Component</code>, or null if no value has been specified.
423: * @see #setUserObject(Object)
424: */
425: Object getUserObject();
426:
427: /**
428: * Assigns a user defined <code>Object</code> to this <code>Component</code>. This property has no direct effect
429: * on the state of the <code>Component</code>. Instead, it provides a general purpose storage
430: * mechanism to the developer that allows any kind of data to be associated to this <code>Component</code>.
431: * For complex applications, alternate methods of associating state to a <code>Component</code> will likely
432: * serve your design more thoroughly. However, there are a number of cases where this flexibility could be useful
433: * and therefore the framework supports the concept.
434: * <br>
435: * <b>Default:</b> null
436: * <p>
437: * Refer to the documenation on {@link Application#addGlobalPropertyChangeListener(String, PropertyChangeListener)} for an
438: * example of a potential use of this property.
439: * </p>
440: * <b>Events:</b>
441: * <p>
442: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_USER_OBJECT ) to be generated.
443: * </p>
444: * @param userObject an <code>Object</code> of any type that is to be associated with this <code>Component</code>.
445: * @see #getUserObject()
446: * @see Application#addGlobalPropertyChangeListener(String, PropertyChangeListener)
447: * @see #PROPERTY_USER_OBJECT
448: * @see thinwire.ui.event.PropertyChangeEvent
449: */
450: void setUserObject(Object userObject);
451:
452: /**
453: * Returns whether this <code>Component</code> is enabled and therefore supports user interaction.
454: * <br>
455: * <b>Default:</b> true
456: * @return true if the <code>Component</code> supports user interaction, false otherwise.
457: * @see #setEnabled(boolean)
458: */
459: boolean isEnabled();
460:
461: /**
462: * Assigns whether this <code>Component</code> is enabled and therefore supports user interaction.
463: * The form of user iteraction this property controls, depends on the specific kind of <code>Component</code>
464: * itself. However, in general, all keyboard interaction and mouse interaction is disabled by
465: * setting this property to false.
466: * <br>
467: * <b>Default:</b> true
468: * <br>
469: * <b>Events:</b>
470: * <p>
471: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_ENABLED ) to be generated.
472: * </p>
473: * @param enabled true to allow user interaction, false to disallow it.
474: * @see #isEnabled()
475: * @see #PROPERTY_ENABLED
476: * @see thinwire.ui.event.PropertyChangeEvent
477: */
478: void setEnabled(boolean enabled);
479:
480: /**
481: * Returns whether this <code>Component</code> supports gaining focus. <br>
482: * <b>Default:</b> true, except for <code>Divider</code>, <code>Image</code> and <code>Label</code>.
483: * @return true if this <code>Component</code> supports gaining focus, false otherwise.
484: * @see #setFocusCapable(boolean)
485: * @see #setFocus(boolean)
486: */
487: boolean isFocusCapable();
488:
489: /**
490: * Assigns whether this <code>Component</code> supports gaining focus. <br>
491: * <b>Default:</b> true, except for <code>Divider</code>, <code>Image</code> and <code>Label</code>. <br>
492: * <b>Events:</b>
493: * <p>
494: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_FOCUS_CAPABLE ) to be generated.
495: * </p>
496: * @param focusCapable true to allow this component to receive focus, false to disallow it.
497: * @see #isFocusCapable()
498: * @see #PROPERTY_FOCUS_CAPABLE
499: * @see #setFocus(boolean)
500: * @see thinwire.ui.event.PropertyChangeEvent
501: */
502: void setFocusCapable(boolean focusCapable);
503:
504: /**
505: * Returns whether this <code>Component</code> has the input focus. If this is a <code>Container</code>, then this method
506: * will return true if a child <code>Component</code> has the focus. In such a case, you can use the
507: * {@link thinwire.ui.Container#getChildWithFocus()} method to get a reference to that child. Similarly, if you want to find the
508: * child <code>Component</code> that has the focus anywhere in the current <code>Frame</code> or <code>Dialog</code>, you
509: * can use the {@link thinwire.ui.Container#getComponentWithFocus()} method.
510: * <p>
511: * <b>Default:</b> false. However, at rendering time, if no component in the window has focus, the first focus capable
512: * component is given focus.
513: * </p>
514: * <p>
515: * See the {@link #setFocus(boolean)} method for a full description of focus details.
516: * </p>
517: * @return true if this <code>Component</code> has the input focus, false otherwise.
518: * @see #setFocus(boolean)
519: * @see thinwire.ui.Container#getComponentWithFocus()
520: * @see thinwire.ui.Container#getChildWithFocus()
521: */
522: boolean isFocus();
523:
524: /**
525: * Assigns whether this <code>Component</code> has the input focus. When this <code>Component</code>
526: * has the input focus, it will receive all keyboard events generated by the user. Therefore,
527: * if this <code>Component</code> supports text editing and it has focus, the user can type a value
528: * into it's field. Additionally, any keyboard navigation supported by this <code>Component</code>
529: * or keyboard shortcuts added by a developer become available upon gaining focus. Conversely, when this <code>Component</code> no longer has
530: * focus, it will receive no keyboard events.
531: * <p>
532: * <b>Default:</b> false. However, at rendering time, if no component in the window has focus, the first focus capable
533: * component is given focus.
534: * </p>
535: * <b>Details:</b>
536: * <p>
537: * The simplest of all cases, is when this <code>Component</code> has not yet been added to a <code>Container</code>.
538: * In that scenario, the focus property is simply set to true and no other effect occurs. Later, when this
539: * <code>Component</code> is added to a <code>Container</code> it will be given the focus according to the guidelines
540: * that follow.
541: * </p>
542: * <p>
543: * As a general rule,
544: * only a single <code>Component</code> can have the focus per <code>Frame</code> or <code>Dialog</code>
545: * container hierarchy. In terms of the user interface, only a single <code>Component</code> will actually
546: * have the focus regardless of whether a <code>Dialog</code> and the <code>Frame</code> have components with focus.
547: * In such a case, the actual focus is determined based on which window is currently active.
548: * </p>
549: * <p>
550: * Since only one <code>Component</code> per window can have focus, giving this <code>Component</code> focus
551: * will cause the prior <code>Component</code> of the window to lose focus. In the most common case, both this
552: * <code>Component</code> and the <code>Component</code> losing focus will be siblings in the same <code>Container</code>.
553: * In that case, the focus property of the <code>Component</code> losing focus is simply set to false whereas the
554: * focus property of this <code>Component</code> is set to true.
555: * </p>
556: * <p>
557: * More complex scenarios arise when the <code>Component</code> losing focus and this <code>Component</code> are
558: * not siblings in the same <code>Container</code>. In those cases, the order in which focus is lost and gained
559: * occurs as follows:
560: * </p>
561: * <ul>
562: * <li>1. The highest level shared parent <code>Container</code> between both the <code>Component</code> losing focus
563: * and this <code>Component</code> is found. This shared parent and any <code>Container</code> above it in the hierarchy will be left alone.</li>
564: * <li>2. The focus property is set to <code>false</code> for each <code>Container</code> in the hierarchy that contains the <code>Component</code> losing focus, as well as the
565: * component itself. This is done in top down order, so that the top most <code>Container</code> loses focus first, followed
566: * by every container between it and the <code>Component</code> losing focus next, and with the component itself losing focus last.</li>
567: * <li>3. The focus property is set to <coded>true<code> for each <code>Container</code> in the hierarchy that contains this <code>Component</code>, as well as the
568: * component itself. This is done in top down order, so that the top most <code>Container</code> gains focus first, followed
569: * by every container between it and the <code>Component</code> gaining focus next, and with this component gaining focus last.</li>
570: * </ul>
571: * <p>
572: * The final case to be aware of is if you directly set this <code>Component</code>'s focus to false. In that case,
573: * the same loss of focus rules outlined above apply. There is simply no gaining of focus that occurs by any component.
574: * Therefore you cause the window to have no <code>Component</code> with focus, with the except of the parent <code>Container</code>
575: * of this <code>Component</code>.
576: * </p>
577: * <b>Events:</b>
578: * <p>
579: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_FOCUS ) to be generated. Additionally,
580: * similar event generation may occur for other components according to the details outlined above.
581: * </p>
582: * @param focus true to give this <code>Component</code> and it's parent containers focus, false otherwise.
583: * @see #isFocus()
584: * @see thinwire.ui.Container#getComponentWithFocus()
585: * @see thinwire.ui.Container#getChildWithFocus()
586: * @throws IllegalStateException if this <code>Component</code> is not focus capable
587: * @throws UnsupportedOperationException if the parent of this <code>Component</code> is not null and is not a <code>Container</code>
588: */
589: void setFocus(boolean focus);
590:
591: /**
592: * Returns a <code>Style</code> object representing this <code>Component</code>'s current style settings. NOTE: This method
593: * will never return null.
594: * @return a <code>Style</code> object representing this <code>Component</code>'s current style settings.
595: * @see thinwire.ui.style.Style
596: */
597: Style getStyle();
598:
599: /**
600: * Returns the X coordinate of this <code>Component</code>.
601: * @return the X coordinate (in pixels) of this <code>Component</code>
602: * @see #setX(int)
603: */
604: int getX();
605:
606: /**
607: * Assigns the specified X coordinate to this <code>Component</code>.<br>
608: * <b>Default:</b> 0
609: * <b>Events:</b>
610: * <p>
611: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_X ) to be generated.
612: * </p>
613: * @param x the x coordinate (in pixels) to assign to this <code>Component</code>
614: * @throws IllegalArgumentException if the x value is < -32768 or >= 32767
615: * @see #getX()
616: * @see #setPosition(int, int)
617: * @see #setBounds(int, int, int, int)
618: * @see #PROPERTY_X
619: * @see thinwire.ui.event.PropertyChangeEvent
620: */
621: void setX(int x);
622:
623: /**
624: * Returns the Y coordinate of this <code>Component</code>.
625: * @return the Y coordinate (in pixels) of this <code>Component</code>
626: * @see #setY(int)
627: */
628: int getY();
629:
630: /**
631: * Assigns the specified Y coordinate to this <code>Component</code>.<br>
632: * <b>Default:</b> 0
633: * <b>Events:</b>
634: * <p>
635: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_Y ) to be generated.
636: * </p>
637: * @param y the y coordinate (in pixels) to assign to this <code>Component</code>
638: * @throws IllegalArgumentException if the y value is < -32768 or >= 32767
639: * @see #getY()
640: * @see #setPosition(int, int)
641: * @see #setBounds(int, int, int, int)
642: * @see #PROPERTY_Y
643: * @see thinwire.ui.event.PropertyChangeEvent
644: */
645: void setY(int y);
646:
647: /**
648: * Assigns the specified X and Y coordinates to this <code>Component</code> atomically, in one operation.
649: * Aside from the convienence provided by this method, it also guarantees that both of the provided
650: * X and Y coordinates are legal values before the values are committed. The primary benefit of this
651: * is that no <code>PropertyChangeEvent</code>'s will be generated until both values have been set.
652: * <b>Events:</b>
653: * <p>
654: * This method may generate <code>PropertyChangeEvent</code>'s. See the documenation of <code>setX</code> and <code>setY</code> for more details.
655: * </p>
656: * @param x the x coordinate (in pixels) to assign to this <code>Component</code>
657: * @param y the y coordinate (in pixels) to assign to this <code>Component</code>
658: * @return this <code>Component</code> so that you can perform operations like container.getChildren().add(new Button().setPosition(x, y))
659: * @throws IllegalArgumentException if the x or y value is < -32768 or >= 32767
660: * @see #setX
661: * @see #setY
662: * @see #setBounds(int, int, int, int)
663: * @see #PROPERTY_X
664: * @see #PROPERTY_Y
665: * @see thinwire.ui.event.PropertyChangeEvent
666: */
667: Component setPosition(int x, int y);
668:
669: /**
670: * Returns the width of this <code>Component</code>.
671: * @return the width (in pixels) of this <code>Component</code>
672: * @see #setWidth(int)
673: */
674: int getWidth();
675:
676: /**
677: * Assigns the specified width to this <code>Component</code>.<br>
678: * <b>Default:</b> 0<br>
679: * <b>Events:</b>
680: * <p>
681: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_WIDTH ) to be generated.
682: * </p>
683: * @param width the width (in pixels) to assign to this <code>Component</code>
684: * @throws IllegalArgumentException if the width value is < 0 or >= 32767
685: * @see #getWidth()
686: * @see #setSize(int, int)
687: * @see #setBounds(int, int, int, int)
688: * @see #PROPERTY_WIDTH
689: * @see thinwire.ui.event.PropertyChangeEvent
690: */
691: void setWidth(int width);
692:
693: /**
694: * Returns the height of this <code>Component</code>.
695: * @return the height (in pixels) of this <code>Component</code>
696: * @see #setHeight(int)
697: */
698: int getHeight();
699:
700: /**
701: * Assigns the specified height to this <code>Component</code>.<br>
702: * <b>Default:</b> 0<br>
703: * <b>Events:</b>
704: * <p>
705: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_HEIGHT ) to be generated.
706: * </p>
707: * @param height the height (in pixels) to assign to this <code>Component</code>
708: * @throws IllegalArgumentException if the height value is < 0 or >= 32767
709: * @see #getHeight()
710: * @see #setSize(int, int)
711: * @see #setBounds(int, int, int, int)
712: * @see #PROPERTY_HEIGHT
713: * @see thinwire.ui.event.PropertyChangeEvent
714: */
715: void setHeight(int height);
716:
717: /**
718: * Assigns the specified width and height to this <code>Component</code> atomically, in one operation.
719: * Aside from the convienence provided by this method, it also guarantees that both of the provided
720: * width and height are legal values before the values are committed. The primary benefit of this
721: * is that no <code>PropertyChangeEvent</code>'s will be generated until both values have been set.
722: * <b>Events:</b>
723: * <p>
724: * This method may generate <code>PropertyChangeEvent</code>'s. See the documenation of <code>setWidth</code> and <code>setHeight</code> for more details.
725: * </p>
726: * @param width the width (in pixels) to assign to this <code>Component</code>
727: * @param height the height (in pixels) to assign to this <code>Component</code>
728: * @return this <code>Component</code> so that you can perform operations like container.getChildren().add(new Button().setSize(width, height))
729: * @throws IllegalArgumentException if the width or height value is < 0 or >= 32767
730: * @see #setWidth
731: * @see #setHeight
732: * @see #setBounds(int, int, int, int)
733: * @see #PROPERTY_WIDTH
734: * @see #PROPERTY_HEIGHT
735: * @see thinwire.ui.event.PropertyChangeEvent
736: */
737: Component setSize(int width, int height);
738:
739: /**
740: * Assigns the specified width, height, X and Y values to this <code>Component</code> atomically, in one operation.
741: * Aside from the convienence provided by this method, it also guarantees that all of the provided
742: * values are legal before they are committed. The primary benefit of this
743: * is that no <code>PropertyChangeEvent</code>'s will be generated until all values have been set.
744: * <b>Events:</b>
745: * <p>
746: * This method may generate <code>PropertyChangeEvent</code>'s. See the documenation of <code>setX</code>, <code>setY</code>, <code>setWidth</code> and <code>setHeight</code> for more details.
747: * </p>
748: * @param x the x coordinate (in pixels) to assign to this <code>Component</code>
749: * @param y the y coordinate (in pixels) to assign to this <code>Component</code>
750: * @param width the width (in pixels) to assign to this <code>Component</code>
751: * @param height the height (in pixels) to assign to this <code>Component</code>
752: * @return this <code>Component</code> so that you can perform operations like container.getChildren().add(new Button().setBounds(x, y, width, height))
753: * @throws IllegalArgumentException if the width or height value is < 0 or >= 32767, or if the x or y value is < -32768 or >= 32767
754: * @see #setX
755: * @see #setY
756: * @see #setWidth
757: * @see #setHeight
758: * @see #setBounds(int, int, int, int)
759: * @see #PROPERTY_X
760: * @see #PROPERTY_Y
761: * @see #PROPERTY_WIDTH
762: * @see #PROPERTY_HEIGHT
763: * @see thinwire.ui.event.PropertyChangeEvent
764: */
765: Component setBounds(int x, int y, int width, int height);
766:
767: /**
768: * Gets the layout limit that controls the bounds of this component within the context of the parent <code>Container</code>'s layout.
769: * @return the layout limit that is in use by the <code>Container</code>'s layout, or null if no limit is specified.
770: * @see #setLimit(Object)
771: * @see Container#getLayout
772: * @see Container#setLayout(thinwire.ui.layout.Layout)
773: * @see thinwire.ui.layout.Layout
774: */
775: Object getLimit();
776:
777: /**
778: * Sets a layout limit that controls the bounds of this component within the context of the parent <code>Container</code>'s layout.
779: * The type of limit object that is acceptable depends on the <code>Layout</code> that is specified for the parent <code>Container</code>.
780: * <b>Default:</b> null
781: * @param limit a layout limit to use for the <code>Container</code>'s layout, or null to clear the limit.
782: * @return this <code>Component</code> so that you can perform operations like container.getChildren().add(new Button().setLimit(...))
783: * @see #PROPERTY_LIMIT
784: * @see #getLimit()
785: * @see Container#getLayout
786: * @see Container#setLayout(thinwire.ui.layout.Layout)
787: * @see thinwire.ui.layout.Layout
788: * @see thinwire.ui.event.PropertyChangeEvent
789: */
790: Component setLimit(Object limit);
791:
792: /**
793: * Returns a boolean value indicating whether this <code>Component</code> may be displayed in a window. See
794: * the documentation of {@link #setVisible(boolean)} for further details about this property.<br>
795: * <b>Default:</b> true, except for the <code>Dialog</code> and <code>Frame</code> containers.
796: * @return true if this <code>Component</code> may be displayed, fasle otherwise
797: * @see #setVisible(boolean)
798: */
799: boolean isVisible();
800:
801: /**
802: * Assigns a boolean value indicating whether this <code>Component</code> may be displayed in a window. <br>
803: * <b>Default:</b> true, except for the <code>Dialog</code> and <code>Frame</code> containers. <br>
804: * <b>Details:</b>
805: * <p>
806: * This <code>Component</code> will not actually be displayed unless it is visible and added to a <code>Container</code>
807: * hierarchy in which all of the containers are also visible and the top-level <code>Container</code> is a visible
808: * <code>Frame</code> or <code>Dialog</code>. Once a <code>Component</code> has been displayed, toggling this property
809: * results in a light-weight operation that simply hides/shows this <code>Component</code>. This may sound trivial, but the
810: * difference is important when you need to maximize the performance of your application. For instance, it is a faster to toggle
811: * the visibility of components then it is to add/remove the components from a displayed <code>Container</code>. This is
812: * because the first time a <code>Component</code> is displayed, the entire state must be rendered. In contrast, when you
813: * toggle visibility, the <code>Component</code> remains in memory in a fully rendered form, it is just not visible to the
814: * user.
815: * </p>
816: * <b>Events:</b>
817: * <p>
818: * If the prior value and new value differ, setting this property causes a <code>PropertyChangeEvent</code> ( propertyName = PROPERTY_VISIBLE ) to be generated.
819: * </p>
820: * @param visible true to indicate this <code>Component</code> may be displayed, false otherwise
821: * @see #isVisible()
822: * @see #PROPERTY_VISIBLE
823: * @see thinwire.ui.Container#getChildren()
824: * @see thinwire.ui.event.PropertyChangeEvent
825: */
826: void setVisible(boolean visible);
827: }
|