ponents, but extending all of them by inheritance is not really an option. Vaadin includes a component plug-in mechanism for these purposes. Such plug-ins are simply called extensions.
Also a UI can be extended in a similar fashion. In fact, some Vaadin features such as the JavaScript execution are UI extensions.
Implementing an extension requires defining a server-side extension class and a client-side connector. An extension can have a shared state with the connector and use RPC, just like a component could.
16.7.1. Server-Side Extension API
The server-side API for an extension consists of class that extends (in the Java sense) the AbstractExtension class. It typically has an extend() method, a constructor, or a static helper method that takes the extended component or UI as a parameter and passes it to super.extend().
For example, let us have a trivial example with an extension that takes no special parameters:
public class CapsLockWarning extends AbstractExtension { public void extend(PasswordField field) {
super.extend(field);
}
}
The extension can then be added to a component as follows:
PasswordField password = new PasswordField("Give it"); new CapsLockWarning().extend(password); layout.addComponent(password);
Adding a feature in such a "reverse" way is a bit unusual in the Vaadin API, but allows type safety for extensions, as the method can limit the target type to which the extension can be applied, and whether it is a regular component or a UI.
16.7.2. Extension Connectors
An extension does not have a corresponding widget on the client-side, but only an extension connector that extends the AbstractExtensionConnector class.The server-side extension class is specified with a @Connect annotation, just like in component connectors.
An extension connector needs to implement the extend() method, which allows hooking to the extended component. The normal extension mechanism is to modify the extended component as needed and add event handlers to it to handle user interaction. An extension connector can share a state with the server-side extension as well as make RPC calls, just like with components.
In the following example, we implement a "Caps Lock warning" extension. It listens for changes in Caps Lock state and displays a floating warning element over the extended component if the Caps Lock is on.
@Connect(CapsLockWarning.class) public class CapsLockWarningConnector
extends AbstractExtensionConnector {
@Override
protected void extend(ServerConnector target) { // Get the extended widget
final Widget passwordWidget = ((ComponentConnector) target).getWidget();