/* * Copyright 2011 Vaadin Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.vaadin.ui; import java.io.Serializable; import java.util.EventListener; import java.util.EventObject; import java.util.Locale; import com.vaadin.Application; import com.vaadin.event.FieldEvents; import com.vaadin.server.ClientConnector; import com.vaadin.server.ErrorMessage; import com.vaadin.server.Resource; import com.vaadin.server.Sizeable; import com.vaadin.server.VariableOwner; /** * {@code Component} is the top-level interface that is and must be implemented * by all Vaadin components. {@code Component} is paired with * {@link AbstractComponent}, which provides a default implementation for all * the methods defined in this interface. * *

* Components are laid out in the user interface hierarchically. The layout is * managed by layout components, or more generally by components that implement * the {@link ComponentContainer} interface. Such a container is the * parent of the contained components. *

* *

* The {@link #getParent()} method allows retrieving the parent component of a * component. While there is a {@link #setParent(Component) setParent()}, you * rarely need it as you normally add components with the * {@link ComponentContainer#addComponent(Component) addComponent()} method of * the layout or other {@code ComponentContainer}, which automatically sets the * parent. *

* *

* A component becomes attached to an application (and the * {@link #attach()} is called) when it or one of its parents is attached to the * main window of the application through its containment hierarchy. *

* * @author Vaadin Ltd. * @since 3.0 */ public interface Component extends ClientConnector, Sizeable, Serializable { /** * Gets all user-defined CSS style names of a component. If the component * has multiple style names defined, the return string is a space-separated * list of style names. Built-in style names defined in Vaadin or GWT are * not returned. * *

* The style names are returned only in the basic form in which they were * added; each user-defined style name shows as two CSS style class names in * the rendered HTML: one as it was given and one prefixed with the * component-specific style name. Only the former is returned. *

* * @return the style name or a space-separated list of user-defined style * names of the component * @see #setStyleName(String) * @see #addStyleName(String) * @see #removeStyleName(String) */ public String getStyleName(); /** * Sets one or more user-defined style names of the component, replacing any * previous user-defined styles. Multiple styles can be specified as a * space-separated list of style names. The style names must be valid CSS * class names and should not conflict with any built-in style names in * Vaadin or GWT. * *
     * Label label = new Label("This text has a lot of style");
     * label.setStyleName("myonestyle myotherstyle");
     * 
* *

* Each style name will occur in two versions: one as specified and one that * is prefixed with the style name of the component. For example, if you * have a {@code Button} component and give it "{@code mystyle}" style, the * component will have both "{@code mystyle}" and "{@code v-button-mystyle}" * styles. You could then style the component either with: *

* *
     * .myonestyle {background: blue;}
     * 
* *

* or *

* *
     * .v-button-myonestyle {background: blue;}
     * 
* *

* It is normally a good practice to use {@link #addStyleName(String) * addStyleName()} rather than this setter, as different software * abstraction layers can then add their own styles without accidentally * removing those defined in other layers. *

* *

* This method will trigger a {@link RepaintRequestEvent}. *

* * @param style * the new style or styles of the component as a space-separated * list * @see #getStyleName() * @see #addStyleName(String) * @see #removeStyleName(String) */ public void setStyleName(String style); /** * Adds one or more style names to this component. Multiple styles can be * specified as a space-separated list of style names. The style name will * be rendered as a HTML class name, which can be used in a CSS definition. * *
     * Label label = new Label("This text has style");
     * label.addStyleName("mystyle");
     * 
* *

* Each style name will occur in two versions: one as specified and one that * is prefixed wil the style name of the component. For example, if you have * a {@code Button} component and give it "{@code mystyle}" style, the * component will have both "{@code mystyle}" and "{@code v-button-mystyle}" * styles. You could then style the component either with: *

* *
     * .mystyle {font-style: italic;}
     * 
* *

* or *

* *
     * .v-button-mystyle {font-style: italic;}
     * 
* *

* This method will trigger a {@link RepaintRequestEvent}. *

* * @param style * the new style to be added to the component * @see #getStyleName() * @see #setStyleName(String) * @see #removeStyleName(String) */ public void addStyleName(String style); /** * Removes one or more style names from component. Multiple styles can be * specified as a space-separated list of style names. * *

* The parameter must be a valid CSS style name. Only user-defined style * names added with {@link #addStyleName(String) addStyleName()} or * {@link #setStyleName(String) setStyleName()} can be removed; built-in * style names defined in Vaadin or GWT can not be removed. *

* * * This method will trigger a {@link RepaintRequestEvent}. * * @param style * the style name or style names to be removed * @see #getStyleName() * @see #setStyleName(String) * @see #addStyleName(String) */ public void removeStyleName(String style); /** * Tests whether the component is enabled or not. A user can not interact * with disabled components. Disabled components are rendered in a style * that indicates the status, usually in gray color. Children of a disabled * component are also disabled. Components are enabled by default. * *

* As a security feature, all updates for disabled components are blocked on * the server-side. *

* *

* Note that this method only returns the status of the component and does * not take parents into account. Even though this method returns true the * component can be disabled to the user if a parent is disabled. *

* * @return true if the component and its parent are enabled, * false otherwise. * @see VariableOwner#isEnabled() */ public boolean isEnabled(); /** * Enables or disables the component. The user can not interact disabled * components, which are shown with a style that indicates the status, * usually shaded in light gray color. Components are enabled by default. * *
     * Button enabled = new Button("Enabled");
     * enabled.setEnabled(true); // The default
     * layout.addComponent(enabled);
     * 
     * Button disabled = new Button("Disabled");
     * disabled.setEnabled(false);
     * layout.addComponent(disabled);
     * 
* *

* This method will trigger a {@link RepaintRequestEvent} for the component * and, if it is a {@link ComponentContainer}, for all its children * recursively. *

* * @param enabled * a boolean value specifying if the component should be enabled * or not */ public void setEnabled(boolean enabled); /** * Tests the visibility property of the component. * *

* Visible components are drawn in the user interface, while invisible ones * are not. The effect is not merely a cosmetic CSS change - no information * about an invisible component will be sent to the client. The effect is * thus the same as removing the component from its parent. Making a * component invisible through this property can alter the positioning of * other components. *

* *

* A component is visible only if all its parents are also visible. This is * not checked by this method though, so even if this method returns true, * the component can be hidden from the user because a parent is set to * invisible. *

* * @return true if the component has been set to be visible in * the user interface, false if not * @see #setVisible(boolean) * @see #attach() */ public boolean isVisible(); /** * Sets the visibility of the component. * *

* Visible components are drawn in the user interface, while invisible ones * are not. The effect is not merely a cosmetic CSS change - no information * about an invisible component will be sent to the client. The effect is * thus the same as removing the component from its parent. *

* *
     * TextField readonly = new TextField("Read-Only");
     * readonly.setValue("You can't see this!");
     * readonly.setVisible(false);
     * layout.addComponent(readonly);
     * 
* *

* A component is visible only if all of its parents are also visible. If a * component is explicitly set to be invisible, changes in the visibility of * its parents will not change the visibility of the component. *

* * @param visible * the boolean value specifying if the component should be * visible after the call or not. * @see #isVisible() */ public void setVisible(boolean visible); /** * Gets the parent component of the component. * *

* Components can be nested but a component can have only one parent. A * component that contains other components, that is, can be a parent, * should usually inherit the {@link ComponentContainer} interface. *

* * @return the parent component */ @Override public HasComponents getParent(); /** * Tests whether the component is in the read-only mode. The user can not * change the value of a read-only component. As only {@link Field} * components normally have a value that can be input or changed by the * user, this is mostly relevant only to field components, though not * restricted to them. * *

* Notice that the read-only mode only affects whether the user can change * the value of the component; it is possible to, for example, scroll * a read-only table. *

* *

* The method will return {@code true} if the component or any of its * parents is in the read-only mode. *

* * @return true if the component or any of its parents is in * read-only mode, false if not. * @see #setReadOnly(boolean) */ public boolean isReadOnly(); /** * Sets the read-only mode of the component to the specified mode. The user * can not change the value of a read-only component. * *

* As only {@link Field} components normally have a value that can be input * or changed by the user, this is mostly relevant only to field components, * though not restricted to them. *

* *

* Notice that the read-only mode only affects whether the user can change * the value of the component; it is possible to, for example, scroll * a read-only table. *

* *

* This method will trigger a {@link RepaintRequestEvent}. *

* * @param readOnly * a boolean value specifying whether the component is put * read-only mode or not */ public void setReadOnly(boolean readOnly); /** * Gets the caption of the component. * *

* See {@link #setCaption(String)} for a detailed description of the * caption. *

* * @return the caption of the component or {@code null} if the caption is * not set. * @see #setCaption(String) */ public String getCaption(); /** * Sets the caption of the component. * *

* A caption is an explanatory textual label accompanying a user * interface component, usually shown above, left of, or inside the * component. Icon (see {@link #setIcon(Resource) setIcon()} is * closely related to caption and is usually displayed horizontally before * or after it, depending on the component and the containing layout. *

* *

* The caption can usually also be given as the first parameter to a * constructor, though some components do not support it. *

* *
     * RichTextArea area = new RichTextArea();
     * area.setCaption("You can edit stuff here");
     * area.setValue("<h1>Helpful Heading</h1>"
     *         + "<p>All this is for you to edit.</p>");
     * 
* *

* The contents of a caption are automatically quoted, so no raw XHTML can * be rendered in a caption. The validity of the used character encoding, * usually UTF-8, is not checked. *

* *

* The caption of a component is, by default, managed and displayed by the * layout component or component container in which the component is placed. * For example, the {@link VerticalLayout} component shows the captions * left-aligned above the contained components, while the {@link FormLayout} * component shows the captions on the left side of the vertically laid * components, with the captions and their associated components * left-aligned in their own columns. The {@link CustomComponent} does not * manage the caption of its composition root, so if the root component has * a caption, it will not be rendered. Some components, such as * {@link Button} and {@link Panel}, manage the caption themselves and * display it inside the component. *

* *

* This method will trigger a {@link RepaintRequestEvent}. A * reimplementation should call the superclass implementation. *

* * @param caption * the new caption for the component. If the caption is * {@code null}, no caption is shown and it does not normally * take any space */ public void setCaption(String caption); /** * Gets the icon resource of the component. * *

* See {@link #setIcon(Resource)} for a detailed description of the icon. *

* * @return the icon resource of the component or {@code null} if the * component has no icon * @see #setIcon(Resource) */ public Resource getIcon(); /** * Sets the icon of the component. * *

* An icon is an explanatory graphical label accompanying a user interface * component, usually shown above, left of, or inside the component. Icon is * closely related to caption (see {@link #setCaption(String) setCaption()}) * and is usually displayed horizontally before or after it, depending on * the component and the containing layout. *

* *

* The image is loaded by the browser from a resource, typically a * {@link com.vaadin.server.ThemeResource}. *

* *
     * // Component with an icon from a custom theme
     * TextField name = new TextField("Name");
     * name.setIcon(new ThemeResource("icons/user.png"));
     * layout.addComponent(name);
     * 
     * // Component with an icon from another theme ('runo')
     * Button ok = new Button("OK");
     * ok.setIcon(new ThemeResource("../runo/icons/16/ok.png"));
     * layout.addComponent(ok);
     * 
* *

* The icon of a component is, by default, managed and displayed by the * layout component or component container in which the component is placed. * For example, the {@link VerticalLayout} component shows the icons * left-aligned above the contained components, while the {@link FormLayout} * component shows the icons on the left side of the vertically laid * components, with the icons and their associated components left-aligned * in their own columns. The {@link CustomComponent} does not manage the * icon of its composition root, so if the root component has an icon, it * will not be rendered. *

* *

* An icon will be rendered inside an HTML element that has the * {@code v-icon} CSS style class. The containing layout may enclose an icon * and a caption inside elements related to the caption, such as * {@code v-caption} . *

* * This method will trigger a {@link RepaintRequestEvent}. * * @param icon * the icon of the component. If null, no icon is shown and it * does not normally take any space. * @see #getIcon() * @see #setCaption(String) */ public void setIcon(Resource icon); /** * Gets the UI the component is attached to. * *

* If the component is not attached to a UI through a component containment * hierarchy, null is returned. *

* * @return the UI of the component or null if it is not * attached to a UI */ @Override public UI getUI(); /** * Gets the application object to which the component is attached. * *

* The method will return {@code null} if the component is not currently * attached to an application. *

* *

* Getting a null value is often a problem in constructors of regular * components and in the initializers of custom composite components. A * standard workaround is to use {@link Application#getCurrent()} to * retrieve the application instance that the current request relates to. * Another way is to move the problematic initialization to * {@link #attach()}, as described in the documentation of the method. *

* * @return the parent application of the component or null. * @see #attach() */ public Application getApplication(); /** * {@inheritDoc} * *

* Reimplementing the {@code attach()} method is useful for tasks that need * to get a reference to the parent, window, or application object with the * {@link #getParent()}, {@link #getUI()}, and {@link #getApplication()} * methods. A component does not yet know these objects in the constructor, * so in such case, the methods will return {@code null}. For example, the * following is invalid: *

* *
     * public class AttachExample extends CustomComponent {
     *     public AttachExample() {
     *         // ERROR: We can't access the application object yet.
     *         ClassResource r = new ClassResource("smiley.jpg", getApplication());
     *         Embedded image = new Embedded("Image:", r);
     *         setCompositionRoot(image);
     *     }
     * }
     * 
* *

* Adding a component to an application triggers calling the * {@link #attach()} method for the component. Correspondingly, removing a * component from a container triggers calling the {@link #detach()} method. * If the parent of an added component is already connected to the * application, the {@code attach()} is called immediately from * {@link #setParent(Component)}. *

*

* This method must call {@link UI#componentAttached(Component)} to let the * UI know that a new Component has been attached. *

* * *
     * public class AttachExample extends CustomComponent {
     *     public AttachExample() {
     *     }
     * 
     *     @Override
     *     public void attach() {
     *         super.attach(); // Must call.
     * 
     *         // Now we know who ultimately owns us.
     *         ClassResource r = new ClassResource("smiley.jpg", getApplication());
     *         Embedded image = new Embedded("Image:", r);
     *         setCompositionRoot(image);
     *     }
     * }
     * 
*/ @Override public void attach(); /** * Gets the locale of the component. * *

* If a component does not have a locale set, the locale of its parent is * returned, and so on. Eventually, if no parent has locale set, the locale * of the application is returned. If the application does not have a locale * set, it is determined by Locale.getDefault(). *

* *

* As the component must be attached before its locale can be acquired, * using this method in the internationalization of component captions, etc. * is generally not feasible. For such use case, we recommend using an * otherwise acquired reference to the application locale. *

* * @return Locale of this component or {@code null} if the component and * none of its parents has a locale set and the component is not yet * attached to an application. */ public Locale getLocale(); /** * Adds an unique id for component that get's transferred to terminal for * testing purposes. Keeping identifiers unique is the responsibility of the * programmer. * * @param id * An alphanumeric id */ public void setId(String id); /** * Get's currently set debug identifier * * @return current id, null if not set */ public String getId(); /* Component event framework */ /** * Superclass of all component originated events. * *

* Events are the basis of all user interaction handling in Vaadin. To * handle events, you provide a listener object that receives the events of * the particular event type. *

* *
     * Button button = new Button("Click Me!");
     * button.addListener(new Button.ClickListener() {
     *     public void buttonClick(ClickEvent event) {
     *         getWindow().showNotification("Thank You!");
     *     }
     * });
     * layout.addComponent(button);
     * 
* *

* Notice that while each of the event types have their corresponding * listener types; the listener interfaces are not required to inherit the * {@code Component.Listener} interface. *

* * @see Component.Listener */ @SuppressWarnings("serial") public class Event extends EventObject { /** * Constructs a new event with the specified source component. * * @param source * the source component of the event */ public Event(Component source) { super(source); } /** * Gets the component where the event occurred. * * @return the source component of the event */ public Component getComponent() { return (Component) getSource(); } } /** * Listener interface for receiving Component.Events. * *

* Listener interfaces are the basis of all user interaction handling in * Vaadin. You have or create a listener object that receives the events. * All event types have their corresponding listener types; they are not, * however, required to inherit the {@code Component.Listener} interface, * and they rarely do so. *

* *

* This generic listener interface is useful typically when you wish to * handle events from different component types in a single listener method * ({@code componentEvent()}. If you handle component events in an anonymous * listener class, you normally use the component specific listener class, * such as {@link com.vaadin.ui.Button.ClickEvent}. *

* *
     * class Listening extends CustomComponent implements Listener {
     *     Button ok; // Stored for determining the source of an event
     * 
     *     Label status; // For displaying info about the event
     * 
     *     public Listening() {
     *         VerticalLayout layout = new VerticalLayout();
     * 
     *         // Some miscellaneous component
     *         TextField name = new TextField("Say it all here");
     *         name.addListener(this);
     *         name.setImmediate(true);
     *         layout.addComponent(name);
     * 
     *         // Handle button clicks as generic events instead
     *         // of Button.ClickEvent events
     *         ok = new Button("OK");
     *         ok.addListener(this);
     *         layout.addComponent(ok);
     * 
     *         // For displaying information about an event
     *         status = new Label("");
     *         layout.addComponent(status);
     * 
     *         setCompositionRoot(layout);
     *     }
     * 
     *     public void componentEvent(Event event) {
     *         // Act according to the source of the event
     *         if (event.getSource() == ok
     *                 && event.getClass() == Button.ClickEvent.class)
     *             getWindow().showNotification("Click!");
     * 
     *         // Display source component and event class names
     *         status.setValue("Event from " + event.getSource().getClass().getName()
     *                 + ": " + event.getClass().getName());
     *     }
     * }
     * 
     * Listening listening = new Listening();
     * layout.addComponent(listening);
     * 
* * @see Component#addListener(Listener) */ public interface Listener extends EventListener, Serializable { /** * Notifies the listener of a component event. * *

* As the event can typically come from one of many source components, * you may need to differentiate between the event source by component * reference, class, etc. *

* *
         * public void componentEvent(Event event) {
         *     // Act according to the source of the event
         *     if (event.getSource() == ok && event.getClass() == Button.ClickEvent.class)
         *         getWindow().showNotification("Click!");
         * 
         *     // Display source component and event class names
         *     status.setValue("Event from " + event.getSource().getClass().getName()
         *             + ": " + event.getClass().getName());
         * }
         * 
* * @param event * the event that has occured. */ public void componentEvent(Component.Event event); } /** * Registers a new (generic) component event listener for the component. * *
     * class Listening extends CustomComponent implements Listener {
     *     // Stored for determining the source of an event
     *     Button ok;
     * 
     *     Label status; // For displaying info about the event
     * 
     *     public Listening() {
     *         VerticalLayout layout = new VerticalLayout();
     * 
     *         // Some miscellaneous component
     *         TextField name = new TextField("Say it all here");
     *         name.addListener(this);
     *         name.setImmediate(true);
     *         layout.addComponent(name);
     * 
     *         // Handle button clicks as generic events instead
     *         // of Button.ClickEvent events
     *         ok = new Button("OK");
     *         ok.addListener(this);
     *         layout.addComponent(ok);
     * 
     *         // For displaying information about an event
     *         status = new Label("");
     *         layout.addComponent(status);
     * 
     *         setCompositionRoot(layout);
     *     }
     * 
     *     public void componentEvent(Event event) {
     *         // Act according to the source of the event
     *         if (event.getSource() == ok)
     *             getWindow().showNotification("Click!");
     * 
     *         status.setValue("Event from " + event.getSource().getClass().getName()
     *                 + ": " + event.getClass().getName());
     *     }
     * }
     * 
     * Listening listening = new Listening();
     * layout.addComponent(listening);
     * 
* * @param listener * the new Listener to be registered. * @see Component.Event * @see #removeListener(Listener) */ public void addListener(Component.Listener listener); /** * Removes a previously registered component event listener from this * component. * * @param listener * the listener to be removed. * @see #addListener(Listener) */ public void removeListener(Component.Listener listener); /** * Class of all component originated error events. * *

* The component error event is normally fired by * {@link AbstractComponent#setComponentError(ErrorMessage)}. The component * errors are set by the framework in some situations and can be set by user * code. They are indicated in a component with an error indicator. *

*/ @SuppressWarnings("serial") public class ErrorEvent extends Event { private final ErrorMessage message; /** * Constructs a new event with a specified source component. * * @param message * the error message. * @param component * the source component. */ public ErrorEvent(ErrorMessage message, Component component) { super(component); this.message = message; } /** * Gets the error message. * * @return the error message. */ public ErrorMessage getErrorMessage() { return message; } } /** * Listener interface for receiving Component.Errorss. */ public interface ErrorListener extends EventListener, Serializable { /** * Notifies the listener of a component error. * * @param event * the event that has occured. */ public void componentError(Component.ErrorEvent event); } /** * A sub-interface implemented by components that can obtain input focus. * This includes all {@link Field} components as well as some other * components, such as {@link Upload}. * *

* Focus can be set with {@link #focus()}. This interface does not provide * an accessor that would allow finding out the currently focused component; * focus information can be acquired for some (but not all) {@link Field} * components through the {@link com.vaadin.event.FieldEvents.FocusListener} * and {@link com.vaadin.event.FieldEvents.BlurListener} interfaces. *

* * @see FieldEvents */ public interface Focusable extends Component { /** * Sets the focus to this component. * *
         * Form loginBox = new Form();
         * loginBox.setCaption("Login");
         * layout.addComponent(loginBox);
         * 
         * // Create the first field which will be focused
         * TextField username = new TextField("User name");
         * loginBox.addField("username", username);
         * 
         * // Set focus to the user name
         * username.focus();
         * 
         * TextField password = new TextField("Password");
         * loginBox.addField("password", password);
         * 
         * Button login = new Button("Login");
         * loginBox.getFooter().addComponent(login);
         * 
* *

* Notice that this interface does not provide an accessor that would * allow finding out the currently focused component. Focus information * can be acquired for some (but not all) {@link Field} components * through the {@link com.vaadin.event.FieldEvents.FocusListener} and * {@link com.vaadin.event.FieldEvents.BlurListener} interfaces. *

* * @see com.vaadin.event.FieldEvents * @see com.vaadin.event.FieldEvents.FocusEvent * @see com.vaadin.event.FieldEvents.FocusListener * @see com.vaadin.event.FieldEvents.BlurEvent * @see com.vaadin.event.FieldEvents.BlurListener */ public void focus(); /** * Gets the tabulator index of the {@code Focusable} component. * * @return tab index set for the {@code Focusable} component * @see #setTabIndex(int) */ public int getTabIndex(); /** * Sets the tabulator index of the {@code Focusable} component. * The tab index property is used to specify the order in which the * fields are focused when the user presses the Tab key. Components with * a defined tab index are focused sequentially first, and then the * components with no tab index. * *
         * Form loginBox = new Form();
         * loginBox.setCaption("Login");
         * layout.addComponent(loginBox);
         * 
         * // Create the first field which will be focused
         * TextField username = new TextField("User name");
         * loginBox.addField("username", username);
         * 
         * // Set focus to the user name
         * username.focus();
         * 
         * TextField password = new TextField("Password");
         * loginBox.addField("password", password);
         * 
         * Button login = new Button("Login");
         * loginBox.getFooter().addComponent(login);
         * 
         * // An additional component which natural focus order would
         * // be after the button.
         * CheckBox remember = new CheckBox("Remember me");
         * loginBox.getFooter().addComponent(remember);
         * 
         * username.setTabIndex(1);
         * password.setTabIndex(2);
         * remember.setTabIndex(3); // Different than natural place
         * login.setTabIndex(4);
         * 
* *

* After all focusable user interface components are done, the browser * can begin again from the component with the smallest tab index, or it * can take the focus out of the page, for example, to the location bar. *

* *

* If the tab index is not set (is set to zero), the default tab order * is used. The order is somewhat browser-dependent, but generally * follows the HTML structure of the page. *

* *

* A negative value means that the component is completely removed from * the tabulation order and can not be reached by pressing the Tab key * at all. *

* * @param tabIndex * the tab order of this component. Indexes usually start * from 1. Zero means that default tab order should be used. * A negative value means that the field should not be * included in the tabbing sequence. * @see #getTabIndex() */ public void setTabIndex(int tabIndex); } }