From e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 13 Aug 2012 18:34:33 +0300 Subject: Moved server files to a server src folder (#9299) --- src/com/vaadin/ui/AbsoluteLayout.java | 632 --- src/com/vaadin/ui/AbstractComponent.java | 1382 ----- src/com/vaadin/ui/AbstractComponentContainer.java | 351 -- src/com/vaadin/ui/AbstractField.java | 1657 ------ src/com/vaadin/ui/AbstractJavaScriptComponent.java | 165 - src/com/vaadin/ui/AbstractLayout.java | 77 - src/com/vaadin/ui/AbstractMedia.java | 196 - src/com/vaadin/ui/AbstractOrderedLayout.java | 383 -- src/com/vaadin/ui/AbstractSelect.java | 2029 -------- src/com/vaadin/ui/AbstractSplitPanel.java | 521 -- src/com/vaadin/ui/AbstractTextField.java | 674 --- src/com/vaadin/ui/Accordion.java | 19 - src/com/vaadin/ui/Alignment.java | 158 - src/com/vaadin/ui/Audio.java | 55 - src/com/vaadin/ui/Button.java | 539 -- src/com/vaadin/ui/CheckBox.java | 141 - src/com/vaadin/ui/ComboBox.java | 116 - src/com/vaadin/ui/Component.java | 1047 ---- src/com/vaadin/ui/ComponentContainer.java | 222 - src/com/vaadin/ui/ConnectorTracker.java | 320 -- src/com/vaadin/ui/CssLayout.java | 308 -- src/com/vaadin/ui/CustomComponent.java | 189 - src/com/vaadin/ui/CustomField.java | 237 - src/com/vaadin/ui/CustomLayout.java | 329 -- src/com/vaadin/ui/DateField.java | 869 ---- src/com/vaadin/ui/DefaultFieldFactory.java | 146 - src/com/vaadin/ui/DragAndDropWrapper.java | 407 -- src/com/vaadin/ui/Embedded.java | 531 -- src/com/vaadin/ui/Field.java | 97 - src/com/vaadin/ui/Form.java | 1420 ----- src/com/vaadin/ui/FormFieldFactory.java | 41 - src/com/vaadin/ui/FormLayout.java | 31 - src/com/vaadin/ui/GridLayout.java | 1415 ----- src/com/vaadin/ui/HasComponents.java | 49 - src/com/vaadin/ui/HorizontalLayout.java | 24 - src/com/vaadin/ui/HorizontalSplitPanel.java | 34 - src/com/vaadin/ui/Html5File.java | 65 - src/com/vaadin/ui/InlineDateField.java | 46 - src/com/vaadin/ui/JavaScript.java | 157 - src/com/vaadin/ui/JavaScriptFunction.java | 41 - src/com/vaadin/ui/Label.java | 483 -- src/com/vaadin/ui/Layout.java | 229 - src/com/vaadin/ui/Link.java | 242 - src/com/vaadin/ui/ListSelect.java | 96 - src/com/vaadin/ui/LoginForm.java | 353 -- src/com/vaadin/ui/MenuBar.java | 890 ---- src/com/vaadin/ui/NativeButton.java | 21 - src/com/vaadin/ui/NativeSelect.java | 91 - src/com/vaadin/ui/Notification.java | 367 -- src/com/vaadin/ui/OptionGroup.java | 203 - src/com/vaadin/ui/Panel.java | 486 -- src/com/vaadin/ui/PasswordField.java | 67 - src/com/vaadin/ui/PopupDateField.java | 80 - src/com/vaadin/ui/PopupView.java | 453 -- src/com/vaadin/ui/ProgressIndicator.java | 257 - src/com/vaadin/ui/RichTextArea.java | 344 -- src/com/vaadin/ui/Root.java | 1227 ----- src/com/vaadin/ui/Select.java | 803 --- src/com/vaadin/ui/Slider.java | 372 -- src/com/vaadin/ui/TabSheet.java | 1328 ----- src/com/vaadin/ui/Table.java | 5449 -------------------- src/com/vaadin/ui/TableFieldFactory.java | 45 - src/com/vaadin/ui/TextArea.java | 121 - src/com/vaadin/ui/TextField.java | 92 - src/com/vaadin/ui/Tree.java | 1615 ------ src/com/vaadin/ui/TreeTable.java | 824 --- src/com/vaadin/ui/TwinColSelect.java | 180 - src/com/vaadin/ui/UniqueSerializable.java | 30 - src/com/vaadin/ui/Upload.java | 1055 ---- src/com/vaadin/ui/VerticalLayout.java | 25 - src/com/vaadin/ui/VerticalSplitPanel.java | 30 - src/com/vaadin/ui/Video.java | 81 - src/com/vaadin/ui/Window.java | 853 --- .../ui/doc-files/component_class_hierarchy.gif | Bin 11077 -> 0 bytes .../vaadin/ui/doc-files/component_interfaces.gif | Bin 2272 -> 0 bytes src/com/vaadin/ui/package.html | 76 - src/com/vaadin/ui/themes/BaseTheme.java | 59 - src/com/vaadin/ui/themes/ChameleonTheme.java | 365 -- src/com/vaadin/ui/themes/LiferayTheme.java | 31 - src/com/vaadin/ui/themes/Reindeer.java | 217 - src/com/vaadin/ui/themes/Runo.java | 183 - 81 files changed, 36843 deletions(-) delete mode 100644 src/com/vaadin/ui/AbsoluteLayout.java delete mode 100644 src/com/vaadin/ui/AbstractComponent.java delete mode 100644 src/com/vaadin/ui/AbstractComponentContainer.java delete mode 100644 src/com/vaadin/ui/AbstractField.java delete mode 100644 src/com/vaadin/ui/AbstractJavaScriptComponent.java delete mode 100644 src/com/vaadin/ui/AbstractLayout.java delete mode 100644 src/com/vaadin/ui/AbstractMedia.java delete mode 100644 src/com/vaadin/ui/AbstractOrderedLayout.java delete mode 100644 src/com/vaadin/ui/AbstractSelect.java delete mode 100644 src/com/vaadin/ui/AbstractSplitPanel.java delete mode 100644 src/com/vaadin/ui/AbstractTextField.java delete mode 100644 src/com/vaadin/ui/Accordion.java delete mode 100644 src/com/vaadin/ui/Alignment.java delete mode 100644 src/com/vaadin/ui/Audio.java delete mode 100644 src/com/vaadin/ui/Button.java delete mode 100644 src/com/vaadin/ui/CheckBox.java delete mode 100644 src/com/vaadin/ui/ComboBox.java delete mode 100644 src/com/vaadin/ui/Component.java delete mode 100644 src/com/vaadin/ui/ComponentContainer.java delete mode 100644 src/com/vaadin/ui/ConnectorTracker.java delete mode 100644 src/com/vaadin/ui/CssLayout.java delete mode 100644 src/com/vaadin/ui/CustomComponent.java delete mode 100644 src/com/vaadin/ui/CustomField.java delete mode 100644 src/com/vaadin/ui/CustomLayout.java delete mode 100644 src/com/vaadin/ui/DateField.java delete mode 100644 src/com/vaadin/ui/DefaultFieldFactory.java delete mode 100644 src/com/vaadin/ui/DragAndDropWrapper.java delete mode 100644 src/com/vaadin/ui/Embedded.java delete mode 100644 src/com/vaadin/ui/Field.java delete mode 100644 src/com/vaadin/ui/Form.java delete mode 100644 src/com/vaadin/ui/FormFieldFactory.java delete mode 100644 src/com/vaadin/ui/FormLayout.java delete mode 100644 src/com/vaadin/ui/GridLayout.java delete mode 100644 src/com/vaadin/ui/HasComponents.java delete mode 100644 src/com/vaadin/ui/HorizontalLayout.java delete mode 100644 src/com/vaadin/ui/HorizontalSplitPanel.java delete mode 100644 src/com/vaadin/ui/Html5File.java delete mode 100644 src/com/vaadin/ui/InlineDateField.java delete mode 100644 src/com/vaadin/ui/JavaScript.java delete mode 100644 src/com/vaadin/ui/JavaScriptFunction.java delete mode 100644 src/com/vaadin/ui/Label.java delete mode 100644 src/com/vaadin/ui/Layout.java delete mode 100644 src/com/vaadin/ui/Link.java delete mode 100644 src/com/vaadin/ui/ListSelect.java delete mode 100644 src/com/vaadin/ui/LoginForm.java delete mode 100644 src/com/vaadin/ui/MenuBar.java delete mode 100644 src/com/vaadin/ui/NativeButton.java delete mode 100644 src/com/vaadin/ui/NativeSelect.java delete mode 100644 src/com/vaadin/ui/Notification.java delete mode 100644 src/com/vaadin/ui/OptionGroup.java delete mode 100644 src/com/vaadin/ui/Panel.java delete mode 100644 src/com/vaadin/ui/PasswordField.java delete mode 100644 src/com/vaadin/ui/PopupDateField.java delete mode 100644 src/com/vaadin/ui/PopupView.java delete mode 100644 src/com/vaadin/ui/ProgressIndicator.java delete mode 100644 src/com/vaadin/ui/RichTextArea.java delete mode 100644 src/com/vaadin/ui/Root.java delete mode 100644 src/com/vaadin/ui/Select.java delete mode 100644 src/com/vaadin/ui/Slider.java delete mode 100644 src/com/vaadin/ui/TabSheet.java delete mode 100644 src/com/vaadin/ui/Table.java delete mode 100644 src/com/vaadin/ui/TableFieldFactory.java delete mode 100644 src/com/vaadin/ui/TextArea.java delete mode 100644 src/com/vaadin/ui/TextField.java delete mode 100644 src/com/vaadin/ui/Tree.java delete mode 100644 src/com/vaadin/ui/TreeTable.java delete mode 100644 src/com/vaadin/ui/TwinColSelect.java delete mode 100644 src/com/vaadin/ui/UniqueSerializable.java delete mode 100644 src/com/vaadin/ui/Upload.java delete mode 100644 src/com/vaadin/ui/VerticalLayout.java delete mode 100644 src/com/vaadin/ui/VerticalSplitPanel.java delete mode 100644 src/com/vaadin/ui/Video.java delete mode 100644 src/com/vaadin/ui/Window.java delete mode 100644 src/com/vaadin/ui/doc-files/component_class_hierarchy.gif delete mode 100644 src/com/vaadin/ui/doc-files/component_interfaces.gif delete mode 100644 src/com/vaadin/ui/package.html delete mode 100644 src/com/vaadin/ui/themes/BaseTheme.java delete mode 100644 src/com/vaadin/ui/themes/ChameleonTheme.java delete mode 100644 src/com/vaadin/ui/themes/LiferayTheme.java delete mode 100644 src/com/vaadin/ui/themes/Reindeer.java delete mode 100644 src/com/vaadin/ui/themes/Runo.java (limited to 'src/com/vaadin/ui') diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java deleted file mode 100644 index 1c84ca2865..0000000000 --- a/src/com/vaadin/ui/AbsoluteLayout.java +++ /dev/null @@ -1,632 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import com.vaadin.event.LayoutEvents.LayoutClickEvent; -import com.vaadin.event.LayoutEvents.LayoutClickListener; -import com.vaadin.event.LayoutEvents.LayoutClickNotifier; -import com.vaadin.shared.Connector; -import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutServerRpc; -import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutState; -import com.vaadin.terminal.Sizeable; -import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler; - -/** - * AbsoluteLayout is a layout implementation that mimics html absolute - * positioning. - * - */ -@SuppressWarnings("serial") -public class AbsoluteLayout extends AbstractLayout implements - LayoutClickNotifier { - - private AbsoluteLayoutServerRpc rpc = new AbsoluteLayoutServerRpc() { - - @Override - public void layoutClick(MouseEventDetails mouseDetails, - Connector clickedConnector) { - fireEvent(LayoutClickEvent.createEvent(AbsoluteLayout.this, - mouseDetails, clickedConnector)); - } - }; - // Maps each component to a position - private LinkedHashMap componentToCoordinates = new LinkedHashMap(); - - /** - * Creates an AbsoluteLayout with full size. - */ - public AbsoluteLayout() { - registerRpc(rpc); - setSizeFull(); - } - - @Override - public AbsoluteLayoutState getState() { - return (AbsoluteLayoutState) super.getState(); - } - - /** - * Gets an iterator for going through all components enclosed in the - * absolute layout. - */ - @Override - public Iterator getComponentIterator() { - return componentToCoordinates.keySet().iterator(); - } - - /** - * Gets the number of contained components. Consistent with the iterator - * returned by {@link #getComponentIterator()}. - * - * @return the number of contained components - */ - @Override - public int getComponentCount() { - return componentToCoordinates.size(); - } - - /** - * Replaces one component with another one. The new component inherits the - * old components position. - */ - @Override - public void replaceComponent(Component oldComponent, Component newComponent) { - ComponentPosition position = getPosition(oldComponent); - removeComponent(oldComponent); - addComponent(newComponent, position); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.ui.AbstractComponentContainer#addComponent(com.vaadin.ui.Component - * ) - */ - @Override - public void addComponent(Component c) { - addComponent(c, new ComponentPosition()); - } - - /** - * Adds a component to the layout. The component can be positioned by - * providing a string formatted in CSS-format. - *

- * For example the string "top:10px;left:10px" will position the component - * 10 pixels from the left and 10 pixels from the top. The identifiers: - * "top","left","right" and "bottom" can be used to specify the position. - *

- * - * @param c - * The component to add to the layout - * @param cssPosition - * The css position string - */ - public void addComponent(Component c, String cssPosition) { - ComponentPosition position = new ComponentPosition(); - position.setCSSString(cssPosition); - addComponent(c, position); - } - - /** - * Adds the component using the given position. Ensures the position is only - * set if the component is added correctly. - * - * @param c - * The component to add - * @param position - * The position info for the component. Must not be null. - * @throws IllegalArgumentException - * If adding the component failed - */ - private void addComponent(Component c, ComponentPosition position) - throws IllegalArgumentException { - /* - * Create position instance and add it to componentToCoordinates map. We - * need to do this before we call addComponent so the attachListeners - * can access this position. #6368 - */ - internalSetPosition(c, position); - try { - super.addComponent(c); - } catch (IllegalArgumentException e) { - internalRemoveComponent(c); - throw e; - } - requestRepaint(); - } - - /** - * Removes the component from all internal data structures. Does not - * actually remove the component from the layout (this is assumed to have - * been done by the caller). - * - * @param c - * The component to remove - */ - private void internalRemoveComponent(Component c) { - componentToCoordinates.remove(c); - } - - @Override - public void updateState() { - super.updateState(); - - // This could be in internalRemoveComponent and internalSetComponent if - // Map was supported. We cannot get the child - // connectorId unless the component is attached to the application so - // the String->String map cannot be populated in internal* either. - Map connectorToPosition = new HashMap(); - for (Iterator ci = getComponentIterator(); ci.hasNext();) { - Component c = ci.next(); - connectorToPosition.put(c.getConnectorId(), getPosition(c) - .getCSSString()); - } - getState().setConnectorToCssPosition(connectorToPosition); - - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.ui.AbstractComponentContainer#removeComponent(com.vaadin.ui - * .Component) - */ - @Override - public void removeComponent(Component c) { - internalRemoveComponent(c); - super.removeComponent(c); - requestRepaint(); - } - - /** - * Gets the position of a component in the layout. Returns null if component - * is not attached to the layout. - *

- * Note that you cannot update the position by updating this object. Call - * {@link #setPosition(Component, ComponentPosition)} with the updated - * {@link ComponentPosition} object. - *

- * - * @param component - * The component which position is needed - * @return An instance of ComponentPosition containing the position of the - * component, or null if the component is not enclosed in the - * layout. - */ - public ComponentPosition getPosition(Component component) { - return componentToCoordinates.get(component); - } - - /** - * Sets the position of a component in the layout. - * - * @param component - * @param position - */ - public void setPosition(Component component, ComponentPosition position) { - if (!componentToCoordinates.containsKey(component)) { - throw new IllegalArgumentException( - "Component must be a child of this layout"); - } - internalSetPosition(component, position); - } - - /** - * Updates the position for a component. Caller must ensure component is a - * child of this layout. - * - * @param component - * The component. Must be a child for this layout. Not enforced. - * @param position - * New position. Must not be null. - */ - private void internalSetPosition(Component component, - ComponentPosition position) { - componentToCoordinates.put(component, position); - requestRepaint(); - } - - /** - * The CompontPosition class represents a components position within the - * absolute layout. It contains the attributes for left, right, top and - * bottom and the units used to specify them. - */ - public class ComponentPosition implements Serializable { - - private int zIndex = -1; - private Float topValue = null; - private Float rightValue = null; - private Float bottomValue = null; - private Float leftValue = null; - - private Unit topUnits = Unit.PIXELS; - private Unit rightUnits = Unit.PIXELS; - private Unit bottomUnits = Unit.PIXELS; - private Unit leftUnits = Unit.PIXELS; - - /** - * Sets the position attributes using CSS syntax. Attributes not - * included in the string are reset to their unset states. - * - *
-         * setCSSString("top:10px;left:20%;z-index:16;");
-         * 
- * - * @param css - */ - public void setCSSString(String css) { - topValue = rightValue = bottomValue = leftValue = null; - topUnits = rightUnits = bottomUnits = leftUnits = Unit.PIXELS; - zIndex = -1; - if (css == null) { - return; - } - - String[] cssProperties = css.split(";"); - for (int i = 0; i < cssProperties.length; i++) { - String[] keyValuePair = cssProperties[i].split(":"); - String key = keyValuePair[0].trim(); - if (key.equals("")) { - continue; - } - if (key.equals("z-index")) { - zIndex = Integer.parseInt(keyValuePair[1].trim()); - } else { - String value; - if (keyValuePair.length > 1) { - value = keyValuePair[1].trim(); - } else { - value = ""; - } - String symbol = value.replaceAll("[0-9\\.\\-]+", ""); - if (!symbol.equals("")) { - value = value.substring(0, value.indexOf(symbol)) - .trim(); - } - float v = Float.parseFloat(value); - Unit unit = Unit.getUnitFromSymbol(symbol); - if (key.equals("top")) { - topValue = v; - topUnits = unit; - } else if (key.equals("right")) { - rightValue = v; - rightUnits = unit; - } else if (key.equals("bottom")) { - bottomValue = v; - bottomUnits = unit; - } else if (key.equals("left")) { - leftValue = v; - leftUnits = unit; - } - } - } - requestRepaint(); - } - - /** - * Converts the internal values into a valid CSS string. - * - * @return A valid CSS string - */ - public String getCSSString() { - String s = ""; - if (topValue != null) { - s += "top:" + topValue + topUnits.getSymbol() + ";"; - } - if (rightValue != null) { - s += "right:" + rightValue + rightUnits.getSymbol() + ";"; - } - if (bottomValue != null) { - s += "bottom:" + bottomValue + bottomUnits.getSymbol() + ";"; - } - if (leftValue != null) { - s += "left:" + leftValue + leftUnits.getSymbol() + ";"; - } - if (zIndex >= 0) { - s += "z-index:" + zIndex + ";"; - } - return s; - } - - /** - * Sets the 'top' attribute; distance from the top of the component to - * the top edge of the layout. - * - * @param topValue - * The value of the 'top' attribute - * @param topUnits - * The unit of the 'top' attribute. See UNIT_SYMBOLS for a - * description of the available units. - */ - public void setTop(Float topValue, Unit topUnits) { - this.topValue = topValue; - this.topUnits = topUnits; - requestRepaint(); - } - - /** - * Sets the 'right' attribute; distance from the right of the component - * to the right edge of the layout. - * - * @param rightValue - * The value of the 'right' attribute - * @param rightUnits - * The unit of the 'right' attribute. See UNIT_SYMBOLS for a - * description of the available units. - */ - public void setRight(Float rightValue, Unit rightUnits) { - this.rightValue = rightValue; - this.rightUnits = rightUnits; - requestRepaint(); - } - - /** - * Sets the 'bottom' attribute; distance from the bottom of the - * component to the bottom edge of the layout. - * - * @param bottomValue - * The value of the 'bottom' attribute - * @param units - * The unit of the 'bottom' attribute. See UNIT_SYMBOLS for a - * description of the available units. - */ - public void setBottom(Float bottomValue, Unit bottomUnits) { - this.bottomValue = bottomValue; - this.bottomUnits = bottomUnits; - requestRepaint(); - } - - /** - * Sets the 'left' attribute; distance from the left of the component to - * the left edge of the layout. - * - * @param leftValue - * The value of the 'left' attribute - * @param units - * The unit of the 'left' attribute. See UNIT_SYMBOLS for a - * description of the available units. - */ - public void setLeft(Float leftValue, Unit leftUnits) { - this.leftValue = leftValue; - this.leftUnits = leftUnits; - requestRepaint(); - } - - /** - * Sets the 'z-index' attribute; the visual stacking order - * - * @param zIndex - * The z-index for the component. - */ - public void setZIndex(int zIndex) { - this.zIndex = zIndex; - requestRepaint(); - } - - /** - * Sets the value of the 'top' attribute; distance from the top of the - * component to the top edge of the layout. - * - * @param topValue - * The value of the 'left' attribute - */ - public void setTopValue(Float topValue) { - this.topValue = topValue; - requestRepaint(); - } - - /** - * Gets the 'top' attributes value in current units. - * - * @see #getTopUnits() - * @return The value of the 'top' attribute, null if not set - */ - public Float getTopValue() { - return topValue; - } - - /** - * Gets the 'right' attributes value in current units. - * - * @return The value of the 'right' attribute, null if not set - * @see #getRightUnits() - */ - public Float getRightValue() { - return rightValue; - } - - /** - * Sets the 'right' attribute value (distance from the right of the - * component to the right edge of the layout). Currently active units - * are maintained. - * - * @param rightValue - * The value of the 'right' attribute - * @see #setRightUnits(int) - */ - public void setRightValue(Float rightValue) { - this.rightValue = rightValue; - requestRepaint(); - } - - /** - * Gets the 'bottom' attributes value using current units. - * - * @return The value of the 'bottom' attribute, null if not set - * @see #getBottomUnits() - */ - public Float getBottomValue() { - return bottomValue; - } - - /** - * Sets the 'bottom' attribute value (distance from the bottom of the - * component to the bottom edge of the layout). Currently active units - * are maintained. - * - * @param bottomValue - * The value of the 'bottom' attribute - * @see #setBottomUnits(int) - */ - public void setBottomValue(Float bottomValue) { - this.bottomValue = bottomValue; - requestRepaint(); - } - - /** - * Gets the 'left' attributes value using current units. - * - * @return The value of the 'left' attribute, null if not set - * @see #getLeftUnits() - */ - public Float getLeftValue() { - return leftValue; - } - - /** - * Sets the 'left' attribute value (distance from the left of the - * component to the left edge of the layout). Currently active units are - * maintained. - * - * @param leftValue - * The value of the 'left' CSS-attribute - * @see #setLeftUnits(int) - */ - public void setLeftValue(Float leftValue) { - this.leftValue = leftValue; - requestRepaint(); - } - - /** - * Gets the unit for the 'top' attribute - * - * @return See {@link Sizeable} UNIT_SYMBOLS for a description of the - * available units. - */ - public Unit getTopUnits() { - return topUnits; - } - - /** - * Sets the unit for the 'top' attribute - * - * @param topUnits - * See {@link Sizeable} UNIT_SYMBOLS for a description of the - * available units. - */ - public void setTopUnits(Unit topUnits) { - this.topUnits = topUnits; - requestRepaint(); - } - - /** - * Gets the unit for the 'right' attribute - * - * @return See {@link Sizeable} UNIT_SYMBOLS for a description of the - * available units. - */ - public Unit getRightUnits() { - return rightUnits; - } - - /** - * Sets the unit for the 'right' attribute - * - * @param rightUnits - * See {@link Sizeable} UNIT_SYMBOLS for a description of the - * available units. - */ - public void setRightUnits(Unit rightUnits) { - this.rightUnits = rightUnits; - requestRepaint(); - } - - /** - * Gets the unit for the 'bottom' attribute - * - * @return See {@link Sizeable} UNIT_SYMBOLS for a description of the - * available units. - */ - public Unit getBottomUnits() { - return bottomUnits; - } - - /** - * Sets the unit for the 'bottom' attribute - * - * @param bottomUnits - * See {@link Sizeable} UNIT_SYMBOLS for a description of the - * available units. - */ - public void setBottomUnits(Unit bottomUnits) { - this.bottomUnits = bottomUnits; - requestRepaint(); - } - - /** - * Gets the unit for the 'left' attribute - * - * @return See {@link Sizeable} UNIT_SYMBOLS for a description of the - * available units. - */ - public Unit getLeftUnits() { - return leftUnits; - } - - /** - * Sets the unit for the 'left' attribute - * - * @param leftUnits - * See {@link Sizeable} UNIT_SYMBOLS for a description of the - * available units. - */ - public void setLeftUnits(Unit leftUnits) { - this.leftUnits = leftUnits; - requestRepaint(); - } - - /** - * Gets the 'z-index' attribute. - * - * @return the zIndex The z-index attribute - */ - public int getZIndex() { - return zIndex; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return getCSSString(); - } - - } - - @Override - public void addListener(LayoutClickListener listener) { - addListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER, - LayoutClickEvent.class, listener, - LayoutClickListener.clickMethod); - } - - @Override - public void removeListener(LayoutClickListener listener) { - removeListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER, - LayoutClickEvent.class, listener); - } - -} diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java deleted file mode 100644 index e7cb38256c..0000000000 --- a/src/com/vaadin/ui/AbstractComponent.java +++ /dev/null @@ -1,1382 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.vaadin.Application; -import com.vaadin.event.ActionManager; -import com.vaadin.event.EventRouter; -import com.vaadin.event.MethodEventSource; -import com.vaadin.event.ShortcutListener; -import com.vaadin.shared.ComponentState; -import com.vaadin.terminal.AbstractClientConnector; -import com.vaadin.terminal.ErrorMessage; -import com.vaadin.terminal.Resource; -import com.vaadin.terminal.Terminal; -import com.vaadin.terminal.gwt.server.ClientConnector; -import com.vaadin.terminal.gwt.server.ComponentSizeValidator; -import com.vaadin.terminal.gwt.server.ResourceReference; -import com.vaadin.tools.ReflectTools; - -/** - * An abstract class that defines default implementation for the - * {@link Component} interface. Basic UI components that are not derived from an - * external component can inherit this class to easily qualify as Vaadin - * components. Most components in Vaadin do just that. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public abstract class AbstractComponent extends AbstractClientConnector - implements Component, MethodEventSource { - - /* Private members */ - - /** - * Application specific data object. The component does not use or modify - * this. - */ - private Object applicationData; - - /** - * The EventRouter used for the event model. - */ - private EventRouter eventRouter = null; - - /** - * The internal error message of the component. - */ - private ErrorMessage componentError = null; - - /** - * Locale of this component. - */ - private Locale locale; - - /** - * The component should receive focus (if {@link Focusable}) when attached. - */ - private boolean delayedFocus; - - /* Sizeable fields */ - - private float width = SIZE_UNDEFINED; - private float height = SIZE_UNDEFINED; - private Unit widthUnit = Unit.PIXELS; - private Unit heightUnit = Unit.PIXELS; - private static final Pattern sizePattern = Pattern - .compile("^(-?\\d+(\\.\\d+)?)(%|px|em|ex|in|cm|mm|pt|pc)?$"); - - private ComponentErrorHandler errorHandler = null; - - /** - * Keeps track of the Actions added to this component; the actual - * handling/notifying is delegated, usually to the containing window. - */ - private ActionManager actionManager; - - /* Constructor */ - - /** - * Constructs a new Component. - */ - public AbstractComponent() { - // ComponentSizeValidator.setCreationLocation(this); - } - - /* Get/Set component properties */ - - @Override - public void setDebugId(String id) { - getState().setDebugId(id); - } - - @Override - public String getDebugId() { - return getState().getDebugId(); - } - - /** - * Gets style for component. Multiple styles are joined with spaces. - * - * @return the component's styleValue of property style. - * @deprecated Use getStyleName() instead; renamed for consistency and to - * indicate that "style" should not be used to switch client - * side implementation, only to style the component. - */ - @Deprecated - public String getStyle() { - return getStyleName(); - } - - /** - * Sets and replaces all previous style names of the component. This method - * will trigger a {@link RepaintRequestEvent}. - * - * @param style - * the new style of the component. - * @deprecated Use setStyleName() instead; renamed for consistency and to - * indicate that "style" should not be used to switch client - * side implementation, only to style the component. - */ - @Deprecated - public void setStyle(String style) { - setStyleName(style); - } - - /* - * Gets the component's style. Don't add a JavaDoc comment here, we use the - * default documentation from implemented interface. - */ - @Override - public String getStyleName() { - String s = ""; - if (getState().getStyles() != null) { - for (final Iterator it = getState().getStyles().iterator(); it - .hasNext();) { - s += it.next(); - if (it.hasNext()) { - s += " "; - } - } - } - return s; - } - - /* - * Sets the component's style. Don't add a JavaDoc comment here, we use the - * default documentation from implemented interface. - */ - @Override - public void setStyleName(String style) { - if (style == null || "".equals(style)) { - getState().setStyles(null); - requestRepaint(); - return; - } - if (getState().getStyles() == null) { - getState().setStyles(new ArrayList()); - } - List styles = getState().getStyles(); - styles.clear(); - String[] styleParts = style.split(" +"); - for (String part : styleParts) { - if (part.length() > 0) { - styles.add(part); - } - } - requestRepaint(); - } - - @Override - public void addStyleName(String style) { - if (style == null || "".equals(style)) { - return; - } - if (style.contains(" ")) { - // Split space separated style names and add them one by one. - for (String realStyle : style.split(" ")) { - addStyleName(realStyle); - } - return; - } - - if (getState().getStyles() == null) { - getState().setStyles(new ArrayList()); - } - List styles = getState().getStyles(); - if (!styles.contains(style)) { - styles.add(style); - requestRepaint(); - } - } - - @Override - public void removeStyleName(String style) { - if (getState().getStyles() != null) { - String[] styleParts = style.split(" +"); - for (String part : styleParts) { - if (part.length() > 0) { - getState().getStyles().remove(part); - } - } - requestRepaint(); - } - } - - /* - * Get's the component's caption. Don't add a JavaDoc comment here, we use - * the default documentation from implemented interface. - */ - @Override - public String getCaption() { - return getState().getCaption(); - } - - /** - * Sets the component's caption String. Caption is the visible - * name of the component. This method will trigger a - * {@link RepaintRequestEvent}. - * - * @param caption - * the new caption String for the component. - */ - @Override - public void setCaption(String caption) { - getState().setCaption(caption); - requestRepaint(); - } - - /* - * Don't add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public Locale getLocale() { - if (locale != null) { - return locale; - } - HasComponents parent = getParent(); - if (parent != null) { - return parent.getLocale(); - } - final Application app = getApplication(); - if (app != null) { - return app.getLocale(); - } - return null; - } - - /** - * Sets the locale of this component. - * - *
-     * // Component for which the locale is meaningful
-     * InlineDateField date = new InlineDateField("Datum");
-     * 
-     * // German language specified with ISO 639-1 language
-     * // code and ISO 3166-1 alpha-2 country code.
-     * date.setLocale(new Locale("de", "DE"));
-     * 
-     * date.setResolution(DateField.RESOLUTION_DAY);
-     * layout.addComponent(date);
-     * 
- * - * - * @param locale - * the locale to become this component's locale. - */ - public void setLocale(Locale locale) { - this.locale = locale; - - // FIXME: Reload value if there is a converter - requestRepaint(); - } - - /* - * Gets the component's icon resource. Don't add a JavaDoc comment here, we - * use the default documentation from implemented interface. - */ - @Override - public Resource getIcon() { - return ResourceReference.getResource(getState().getIcon()); - } - - /** - * Sets the component's icon. This method will trigger a - * {@link RepaintRequestEvent}. - * - * @param icon - * the icon to be shown with the component's caption. - */ - @Override - public void setIcon(Resource icon) { - getState().setIcon(ResourceReference.create(icon)); - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component#isEnabled() - */ - @Override - public boolean isEnabled() { - return getState().isEnabled(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component#setEnabled(boolean) - */ - @Override - public void setEnabled(boolean enabled) { - if (getState().isEnabled() != enabled) { - getState().setEnabled(enabled); - requestRepaint(); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.gwt.client.Connector#isConnectorEnabled() - */ - @Override - public boolean isConnectorEnabled() { - if (!isVisible()) { - return false; - } else if (!isEnabled()) { - return false; - } else if (!super.isConnectorEnabled()) { - return false; - } else if (!getParent().isComponentVisible(this)) { - return false; - } else { - return true; - } - } - - /* - * Tests if the component is in the immediate mode. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - public boolean isImmediate() { - return getState().isImmediate(); - } - - /** - * Sets the component's immediate mode to the specified status. This method - * will trigger a {@link RepaintRequestEvent}. - * - * @param immediate - * the boolean value specifying if the component should be in the - * immediate mode after the call. - * @see Component#isImmediate() - */ - public void setImmediate(boolean immediate) { - getState().setImmediate(immediate); - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component#isVisible() - */ - @Override - public boolean isVisible() { - return getState().isVisible(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component#setVisible(boolean) - */ - @Override - public void setVisible(boolean visible) { - if (getState().isVisible() == visible) { - return; - } - - getState().setVisible(visible); - requestRepaint(); - if (getParent() != null) { - // Must always repaint the parent (at least the hierarchy) when - // visibility of a child component changes. - getParent().requestRepaint(); - } - } - - /** - *

- * Gets the component's description, used in tooltips and can be displayed - * directly in certain other components such as forms. The description can - * be used to briefly describe the state of the component to the user. The - * description string may contain certain XML tags: - *

- * - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
TagDescriptionExample
<b>boldbold text
<i>italicitalic text
<u>underlinedunderlined text
<br>linebreakN/A
<ul>
- * <li>item1
- * <li>item1
- * </ul>
item list - *
    - *
  • item1 - *
  • item2 - *
- *
- *

- * - *

- * These tags may be nested. - *

- * - * @return component's description String - */ - public String getDescription() { - return getState().getDescription(); - } - - /** - * Sets the component's description. See {@link #getDescription()} for more - * information on what the description is. This method will trigger a - * {@link RepaintRequestEvent}. - * - * The description is displayed as HTML/XHTML in tooltips or directly in - * certain components so care should be taken to avoid creating the - * possibility for HTML injection and possibly XSS vulnerabilities. - * - * @param description - * the new description string for the component. - */ - public void setDescription(String description) { - getState().setDescription(description); - requestRepaint(); - } - - /* - * Gets the component's parent component. Don't add a JavaDoc comment here, - * we use the default documentation from implemented interface. - */ - @Override - public HasComponents getParent() { - return (HasComponents) super.getParent(); - } - - @Override - public void setParent(ClientConnector parent) { - if (parent == null || parent instanceof HasComponents) { - super.setParent(parent); - } else { - throw new IllegalArgumentException( - "The parent of a Component must implement HasComponents, which " - + parent.getClass() + " doesn't do."); - } - } - - /** - * Returns the closest ancestor with the given type. - *

- * To find the Window that contains the component, use {@code Window w = - * getParent(Window.class);} - *

- * - * @param - * The type of the ancestor - * @param parentType - * The ancestor class we are looking for - * @return The first ancestor that can be assigned to the given class. Null - * if no ancestor with the correct type could be found. - */ - public T findAncestor(Class parentType) { - HasComponents p = getParent(); - while (p != null) { - if (parentType.isAssignableFrom(p.getClass())) { - return parentType.cast(p); - } - p = p.getParent(); - } - return null; - } - - /** - * Gets the error message for this component. - * - * @return ErrorMessage containing the description of the error state of the - * component or null, if the component contains no errors. Extending - * classes should override this method if they support other error - * message types such as validation errors or buffering errors. The - * returned error message contains information about all the errors. - */ - public ErrorMessage getErrorMessage() { - return componentError; - } - - /** - * Gets the component's error message. - * - * @link Terminal.ErrorMessage#ErrorMessage(String, int) - * - * @return the component's error message. - */ - public ErrorMessage getComponentError() { - return componentError; - } - - /** - * Sets the component's error message. The message may contain certain XML - * tags, for more information see - * - * @link Component.ErrorMessage#ErrorMessage(String, int) - * - * @param componentError - * the new ErrorMessage of the component. - */ - public void setComponentError(ErrorMessage componentError) { - this.componentError = componentError; - fireComponentErrorEvent(); - requestRepaint(); - } - - /* - * Tests if the component is in read-only mode. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public boolean isReadOnly() { - return getState().isReadOnly(); - } - - /* - * Sets the component's read-only mode. Don't add a JavaDoc comment here, we - * use the default documentation from implemented interface. - */ - @Override - public void setReadOnly(boolean readOnly) { - getState().setReadOnly(readOnly); - requestRepaint(); - } - - /* - * Gets the parent window of the component. Don't add a JavaDoc comment - * here, we use the default documentation from implemented interface. - */ - @Override - public Root getRoot() { - // Just make method from implemented Component interface public - return super.getRoot(); - } - - /* - * Notify the component that it's attached to a window. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void attach() { - super.attach(); - if (delayedFocus) { - focus(); - } - setActionManagerViewer(); - } - - /* - * Detach the component from application. Don't add a JavaDoc comment here, - * we use the default documentation from implemented interface. - */ - @Override - public void detach() { - super.detach(); - if (actionManager != null) { - // Remove any existing viewer. Root cast is just to make the - // compiler happy - actionManager.setViewer((Root) null); - } - } - - /** - * Sets the focus for this component if the component is {@link Focusable}. - */ - protected void focus() { - if (this instanceof Focusable) { - final Application app = getApplication(); - if (app != null) { - getRoot().setFocusedComponent((Focusable) this); - delayedFocus = false; - } else { - delayedFocus = true; - } - } - } - - /** - * 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. This is often a problem in constructors of - * regular components and in the initializers of custom composite - * components. A standard workaround is to move the problematic - * initialization to {@link #attach()}, as described in the documentation of - * the method. - *

- *

- * This method is not meant to be overridden. Due to CDI requirements we - * cannot declare it as final even though it should be final. - *

- * - * @return the parent application of the component or null. - * @see #attach() - */ - @Override - public Application getApplication() { - // Just make method inherited from Component interface public - return super.getApplication(); - } - - /** - * Build CSS compatible string representation of height. - * - * @return CSS height - */ - private String getCSSHeight() { - if (getHeightUnits() == Unit.PIXELS) { - return ((int) getHeight()) + getHeightUnits().getSymbol(); - } else { - return getHeight() + getHeightUnits().getSymbol(); - } - } - - /** - * Build CSS compatible string representation of width. - * - * @return CSS width - */ - private String getCSSWidth() { - if (getWidthUnits() == Unit.PIXELS) { - return ((int) getWidth()) + getWidthUnits().getSymbol(); - } else { - return getWidth() + getWidthUnits().getSymbol(); - } - } - - /** - * Returns the shared state bean with information to be sent from the server - * to the client. - * - * Subclasses should override this method and set any relevant fields of the - * state returned by super.getState(). - * - * @since 7.0 - * - * @return updated component shared state - */ - @Override - public ComponentState getState() { - return (ComponentState) super.getState(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component#updateState() - */ - @Override - public void updateState() { - // TODO This logic should be on the client side and the state should - // simply be a data object with "width" and "height". - if (getHeight() >= 0 - && (getHeightUnits() != Unit.PERCENTAGE || ComponentSizeValidator - .parentCanDefineHeight(this))) { - getState().setHeight("" + getCSSHeight()); - } else { - getState().setHeight(""); - } - - if (getWidth() >= 0 - && (getWidthUnits() != Unit.PERCENTAGE || ComponentSizeValidator - .parentCanDefineWidth(this))) { - getState().setWidth("" + getCSSWidth()); - } else { - getState().setWidth(""); - } - - ErrorMessage error = getErrorMessage(); - if (null != error) { - getState().setErrorMessage(error.getFormattedHtmlMessage()); - } else { - getState().setErrorMessage(null); - } - } - - /* Documentation copied from interface */ - @Override - public void requestRepaint() { - // Invisible components (by flag in this particular component) do not - // need repaints - if (!getState().isVisible()) { - return; - } - super.requestRepaint(); - } - - /* General event framework */ - - private static final Method COMPONENT_EVENT_METHOD = ReflectTools - .findMethod(Component.Listener.class, "componentEvent", - Component.Event.class); - - /** - *

- * Registers a new listener with the specified activation method to listen - * events generated by this component. If the activation method does not - * have any arguments the event object will not be passed to it when it's - * called. - *

- * - *

- * This method additionally informs the event-api to route events with the - * given eventIdentifier to the components handleEvent function call. - *

- * - *

- * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

- * - * @param eventIdentifier - * the identifier of the event to listen for - * @param eventType - * the type of the listened event. Events of this type or its - * subclasses activate the listener. - * @param target - * the object instance who owns the activation method. - * @param method - * the activation method. - * - * @since 6.2 - */ - protected void addListener(String eventIdentifier, Class eventType, - Object target, Method method) { - if (eventRouter == null) { - eventRouter = new EventRouter(); - } - boolean needRepaint = !eventRouter.hasListeners(eventType); - eventRouter.addListener(eventType, target, method); - - if (needRepaint) { - getState().addRegisteredEventListener(eventIdentifier); - requestRepaint(); - } - } - - /** - * Checks if the given {@link Event} type is listened for this component. - * - * @param eventType - * the event type to be checked - * @return true if a listener is registered for the given event type - */ - protected boolean hasListeners(Class eventType) { - return eventRouter != null && eventRouter.hasListeners(eventType); - } - - /** - * Removes all registered listeners matching the given parameters. Since - * this method receives the event type and the listener object as - * parameters, it will unregister all object's methods that are - * registered to listen to events of type eventType generated - * by this component. - * - *

- * This method additionally informs the event-api to stop routing events - * with the given eventIdentifier to the components handleEvent function - * call. - *

- * - *

- * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

- * - * @param eventIdentifier - * the identifier of the event to stop listening for - * @param eventType - * the exact event type the object listens to. - * @param target - * the target object that has registered to listen to events of - * type eventType with one or more methods. - * - * @since 6.2 - */ - protected void removeListener(String eventIdentifier, Class eventType, - Object target) { - if (eventRouter != null) { - eventRouter.removeListener(eventType, target); - if (!eventRouter.hasListeners(eventType)) { - getState().removeRegisteredEventListener(eventIdentifier); - requestRepaint(); - } - } - } - - /** - *

- * Registers a new listener with the specified activation method to listen - * events generated by this component. If the activation method does not - * have any arguments the event object will not be passed to it when it's - * called. - *

- * - *

- * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

- * - * @param eventType - * the type of the listened event. Events of this type or its - * subclasses activate the listener. - * @param target - * the object instance who owns the activation method. - * @param method - * the activation method. - */ - @Override - public void addListener(Class eventType, Object target, Method method) { - if (eventRouter == null) { - eventRouter = new EventRouter(); - } - eventRouter.addListener(eventType, target, method); - } - - /** - *

- * Convenience method for registering a new listener with the specified - * activation method to listen events generated by this component. If the - * activation method does not have any arguments the event object will not - * be passed to it when it's called. - *

- * - *

- * This version of addListener gets the name of the activation - * method as a parameter. The actual method is reflected from - * object, and unless exactly one match is found, - * java.lang.IllegalArgumentException is thrown. - *

- * - *

- * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

- * - *

- * Note: Using this method is discouraged because it cannot be checked - * during compilation. Use {@link #addListener(Class, Object, Method)} or - * {@link #addListener(com.vaadin.ui.Component.Listener)} instead. - *

- * - * @param eventType - * the type of the listened event. Events of this type or its - * subclasses activate the listener. - * @param target - * the object instance who owns the activation method. - * @param methodName - * the name of the activation method. - */ - @Override - public void addListener(Class eventType, Object target, String methodName) { - if (eventRouter == null) { - eventRouter = new EventRouter(); - } - eventRouter.addListener(eventType, target, methodName); - } - - /** - * Removes all registered listeners matching the given parameters. Since - * this method receives the event type and the listener object as - * parameters, it will unregister all object's methods that are - * registered to listen to events of type eventType generated - * by this component. - * - *

- * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

- * - * @param eventType - * the exact event type the object listens to. - * @param target - * the target object that has registered to listen to events of - * type eventType with one or more methods. - */ - @Override - public void removeListener(Class eventType, Object target) { - if (eventRouter != null) { - eventRouter.removeListener(eventType, target); - } - } - - /** - * Removes one registered listener method. The given method owned by the - * given object will no longer be called when the specified events are - * generated by this component. - * - *

- * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

- * - * @param eventType - * the exact event type the object listens to. - * @param target - * target object that has registered to listen to events of type - * eventType with one or more methods. - * @param method - * the method owned by target that's registered to - * listen to events of type eventType. - */ - @Override - public void removeListener(Class eventType, Object target, Method method) { - if (eventRouter != null) { - eventRouter.removeListener(eventType, target, method); - } - } - - /** - *

- * Removes one registered listener method. The given method owned by the - * given object will no longer be called when the specified events are - * generated by this component. - *

- * - *

- * This version of removeListener gets the name of the - * activation method as a parameter. The actual method is reflected from - * target, and unless exactly one match is found, - * java.lang.IllegalArgumentException is thrown. - *

- * - *

- * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

- * - * @param eventType - * the exact event type the object listens to. - * @param target - * the target object that has registered to listen to events of - * type eventType with one or more methods. - * @param methodName - * the name of the method owned by target that's - * registered to listen to events of type eventType. - */ - @Override - public void removeListener(Class eventType, Object target, - String methodName) { - if (eventRouter != null) { - eventRouter.removeListener(eventType, target, methodName); - } - } - - /** - * Returns all listeners that are registered for the given event type or one - * of its subclasses. - * - * @param eventType - * The type of event to return listeners for. - * @return A collection with all registered listeners. Empty if no listeners - * are found. - */ - public Collection getListeners(Class eventType) { - if (eventRouter == null) { - return Collections.EMPTY_LIST; - } - - return eventRouter.getListeners(eventType); - } - - /** - * Sends the event to all listeners. - * - * @param event - * the Event to be sent to all listeners. - */ - protected void fireEvent(Component.Event event) { - if (eventRouter != null) { - eventRouter.fireEvent(event); - } - - } - - /* Component event framework */ - - /* - * Registers a new listener to listen events generated by this component. - * Don't add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public void addListener(Component.Listener listener) { - addListener(Component.Event.class, listener, COMPONENT_EVENT_METHOD); - } - - /* - * Removes a previously registered listener from this component. Don't add a - * JavaDoc comment here, we use the default documentation from implemented - * interface. - */ - @Override - public void removeListener(Component.Listener listener) { - removeListener(Component.Event.class, listener, COMPONENT_EVENT_METHOD); - } - - /** - * Emits the component event. It is transmitted to all registered listeners - * interested in such events. - */ - protected void fireComponentEvent() { - fireEvent(new Component.Event(this)); - } - - /** - * Emits the component error event. It is transmitted to all registered - * listeners interested in such events. - */ - protected void fireComponentErrorEvent() { - fireEvent(new Component.ErrorEvent(getComponentError(), this)); - } - - /** - * Sets the data object, that can be used for any application specific data. - * The component does not use or modify this data. - * - * @param data - * the Application specific data. - * @since 3.1 - */ - public void setData(Object data) { - applicationData = data; - } - - /** - * Gets the application specific data. See {@link #setData(Object)}. - * - * @return the Application specific data set with setData function. - * @since 3.1 - */ - public Object getData() { - return applicationData; - } - - /* Sizeable and other size related methods */ - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#getHeight() - */ - @Override - public float getHeight() { - return height; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#getHeightUnits() - */ - @Override - public Unit getHeightUnits() { - return heightUnit; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#getWidth() - */ - @Override - public float getWidth() { - return width; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#getWidthUnits() - */ - @Override - public Unit getWidthUnits() { - return widthUnit; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#setHeight(float, Unit) - */ - @Override - public void setHeight(float height, Unit unit) { - if (unit == null) { - throw new IllegalArgumentException("Unit can not be null"); - } - this.height = height; - heightUnit = unit; - requestRepaint(); - // ComponentSizeValidator.setHeightLocation(this); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#setSizeFull() - */ - @Override - public void setSizeFull() { - setWidth(100, Unit.PERCENTAGE); - setHeight(100, Unit.PERCENTAGE); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#setSizeUndefined() - */ - @Override - public void setSizeUndefined() { - setWidth(-1, Unit.PIXELS); - setHeight(-1, Unit.PIXELS); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#setWidth(float, Unit) - */ - @Override - public void setWidth(float width, Unit unit) { - if (unit == null) { - throw new IllegalArgumentException("Unit can not be null"); - } - this.width = width; - widthUnit = unit; - requestRepaint(); - // ComponentSizeValidator.setWidthLocation(this); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#setWidth(java.lang.String) - */ - @Override - public void setWidth(String width) { - Size size = parseStringSize(width); - if (size != null) { - setWidth(size.getSize(), size.getUnit()); - } else { - setWidth(-1, Unit.PIXELS); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.Sizeable#setHeight(java.lang.String) - */ - @Override - public void setHeight(String height) { - Size size = parseStringSize(height); - if (size != null) { - setHeight(size.getSize(), size.getUnit()); - } else { - setHeight(-1, Unit.PIXELS); - } - } - - /* - * Returns array with size in index 0 unit in index 1. Null or empty string - * will produce {-1,Unit#PIXELS} - */ - private static Size parseStringSize(String s) { - if (s == null) { - return null; - } - s = s.trim(); - if ("".equals(s)) { - return null; - } - float size = 0; - Unit unit = null; - Matcher matcher = sizePattern.matcher(s); - if (matcher.find()) { - size = Float.parseFloat(matcher.group(1)); - if (size < 0) { - size = -1; - unit = Unit.PIXELS; - } else { - String symbol = matcher.group(3); - unit = Unit.getUnitFromSymbol(symbol); - } - } else { - throw new IllegalArgumentException("Invalid size argument: \"" + s - + "\" (should match " + sizePattern.pattern() + ")"); - } - return new Size(size, unit); - } - - private static class Size implements Serializable { - float size; - Unit unit; - - public Size(float size, Unit unit) { - this.size = size; - this.unit = unit; - } - - public float getSize() { - return size; - } - - public Unit getUnit() { - return unit; - } - } - - public interface ComponentErrorEvent extends Terminal.ErrorEvent { - } - - public interface ComponentErrorHandler extends Serializable { - /** - * Handle the component error - * - * @param event - * @return True if the error has been handled False, otherwise - */ - public boolean handleComponentError(ComponentErrorEvent event); - } - - /** - * Gets the error handler for the component. - * - * The error handler is dispatched whenever there is an error processing the - * data coming from the client. - * - * @return - */ - public ComponentErrorHandler getErrorHandler() { - return errorHandler; - } - - /** - * Sets the error handler for the component. - * - * The error handler is dispatched whenever there is an error processing the - * data coming from the client. - * - * If the error handler is not set, the application error handler is used to - * handle the exception. - * - * @param errorHandler - * AbstractField specific error handler - */ - public void setErrorHandler(ComponentErrorHandler errorHandler) { - this.errorHandler = errorHandler; - } - - /** - * Handle the component error event. - * - * @param error - * Error event to handle - * @return True if the error has been handled False, otherwise. If the error - * haven't been handled by this component, it will be handled in the - * application error handler. - */ - public boolean handleError(ComponentErrorEvent error) { - if (errorHandler != null) { - return errorHandler.handleComponentError(error); - } - return false; - - } - - /* - * Actions - */ - - /** - * Gets the {@link ActionManager} used to manage the - * {@link ShortcutListener}s added to this {@link Field}. - * - * @return the ActionManager in use - */ - protected ActionManager getActionManager() { - if (actionManager == null) { - actionManager = new ActionManager(); - setActionManagerViewer(); - } - return actionManager; - } - - /** - * Set a viewer for the action manager to be the parent sub window (if the - * component is in a window) or the root (otherwise). This is still a - * simplification of the real case as this should be handled by the parent - * VOverlay (on the client side) if the component is inside an VOverlay - * component. - */ - private void setActionManagerViewer() { - if (actionManager != null && getRoot() != null) { - // Attached and has action manager - Window w = findAncestor(Window.class); - if (w != null) { - actionManager.setViewer(w); - } else { - actionManager.setViewer(getRoot()); - } - } - - } - - public void addShortcutListener(ShortcutListener shortcut) { - getActionManager().addAction(shortcut); - } - - public void removeShortcutListener(ShortcutListener shortcut) { - if (actionManager != null) { - actionManager.removeAction(shortcut); - } - } -} diff --git a/src/com/vaadin/ui/AbstractComponentContainer.java b/src/com/vaadin/ui/AbstractComponentContainer.java deleted file mode 100644 index bc27242bb8..0000000000 --- a/src/com/vaadin/ui/AbstractComponentContainer.java +++ /dev/null @@ -1,351 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; - -import com.vaadin.terminal.gwt.server.ComponentSizeValidator; - -/** - * Extension to {@link AbstractComponent} that defines the default - * implementation for the methods in {@link ComponentContainer}. Basic UI - * components that need to contain other components inherit this class to easily - * qualify as a component container. - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public abstract class AbstractComponentContainer extends AbstractComponent - implements ComponentContainer { - - /** - * Constructs a new component container. - */ - public AbstractComponentContainer() { - super(); - } - - /** - * Removes all components from the container. This should probably be - * re-implemented in extending classes for a more powerful implementation. - */ - @Override - public void removeAllComponents() { - final LinkedList l = new LinkedList(); - - // Adds all components - for (final Iterator i = getComponentIterator(); i.hasNext();) { - l.add(i.next()); - } - - // Removes all component - for (final Iterator i = l.iterator(); i.hasNext();) { - removeComponent(i.next()); - } - } - - /* - * Moves all components from an another container into this container. Don't - * add a JavaDoc comment here, we use the default documentation from - * implemented interface. - */ - @Override - public void moveComponentsFrom(ComponentContainer source) { - final LinkedList components = new LinkedList(); - for (final Iterator i = source.getComponentIterator(); i - .hasNext();) { - components.add(i.next()); - } - - for (final Iterator i = components.iterator(); i.hasNext();) { - final Component c = i.next(); - source.removeComponent(c); - addComponent(c); - } - } - - /* Events */ - - private static final Method COMPONENT_ATTACHED_METHOD; - - private static final Method COMPONENT_DETACHED_METHOD; - - static { - try { - COMPONENT_ATTACHED_METHOD = ComponentAttachListener.class - .getDeclaredMethod("componentAttachedToContainer", - new Class[] { ComponentAttachEvent.class }); - COMPONENT_DETACHED_METHOD = ComponentDetachListener.class - .getDeclaredMethod("componentDetachedFromContainer", - new Class[] { ComponentDetachEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in AbstractComponentContainer"); - } - } - - /* documented in interface */ - @Override - public void addListener(ComponentAttachListener listener) { - addListener(ComponentContainer.ComponentAttachEvent.class, listener, - COMPONENT_ATTACHED_METHOD); - } - - /* documented in interface */ - @Override - public void addListener(ComponentDetachListener listener) { - addListener(ComponentContainer.ComponentDetachEvent.class, listener, - COMPONENT_DETACHED_METHOD); - } - - /* documented in interface */ - @Override - public void removeListener(ComponentAttachListener listener) { - removeListener(ComponentContainer.ComponentAttachEvent.class, listener, - COMPONENT_ATTACHED_METHOD); - } - - /* documented in interface */ - @Override - public void removeListener(ComponentDetachListener listener) { - removeListener(ComponentContainer.ComponentDetachEvent.class, listener, - COMPONENT_DETACHED_METHOD); - } - - /** - * Fires the component attached event. This should be called by the - * addComponent methods after the component have been added to this - * container. - * - * @param component - * the component that has been added to this container. - */ - protected void fireComponentAttachEvent(Component component) { - fireEvent(new ComponentAttachEvent(this, component)); - } - - /** - * Fires the component detached event. This should be called by the - * removeComponent methods after the component have been removed from this - * container. - * - * @param component - * the component that has been removed from this container. - */ - protected void fireComponentDetachEvent(Component component) { - fireEvent(new ComponentDetachEvent(this, component)); - } - - /** - * This only implements the events and component parent calls. The extending - * classes must implement component list maintenance and call this method - * after component list maintenance. - * - * @see com.vaadin.ui.ComponentContainer#addComponent(Component) - */ - @Override - public void addComponent(Component c) { - if (c instanceof ComponentContainer) { - // Make sure we're not adding the component inside it's own content - for (Component parent = this; parent != null; parent = parent - .getParent()) { - if (parent == c) { - throw new IllegalArgumentException( - "Component cannot be added inside it's own content"); - } - } - } - - if (c.getParent() != null) { - // If the component already has a parent, try to remove it - ComponentContainer oldParent = (ComponentContainer) c.getParent(); - oldParent.removeComponent(c); - - } - - c.setParent(this); - fireComponentAttachEvent(c); - } - - /** - * This only implements the events and component parent calls. The extending - * classes must implement component list maintenance and call this method - * before component list maintenance. - * - * @see com.vaadin.ui.ComponentContainer#removeComponent(Component) - */ - @Override - public void removeComponent(Component c) { - if (c.getParent() == this) { - c.setParent(null); - fireComponentDetachEvent(c); - } - } - - @Override - public void setVisible(boolean visible) { - if (getState().isVisible() == visible) { - return; - } - - super.setVisible(visible); - // If the visibility state is toggled it might affect all children - // aswell, e.g. make container visible should make children visible if - // they were only hidden because the container was hidden. - requestRepaintAll(); - } - - @Override - public void setWidth(float width, Unit unit) { - /* - * child tree repaints may be needed, due to our fall back support for - * invalid relative sizes - */ - Collection dirtyChildren = null; - boolean childrenMayBecomeUndefined = false; - if (getWidth() == SIZE_UNDEFINED && width != SIZE_UNDEFINED) { - // children currently in invalid state may need repaint - dirtyChildren = getInvalidSizedChildren(false); - } else if ((width == SIZE_UNDEFINED && getWidth() != SIZE_UNDEFINED) - || (unit == Unit.PERCENTAGE - && getWidthUnits() != Unit.PERCENTAGE && !ComponentSizeValidator - .parentCanDefineWidth(this))) { - /* - * relative width children may get to invalid state if width becomes - * invalid. Width may also become invalid if units become percentage - * due to the fallback support - */ - childrenMayBecomeUndefined = true; - dirtyChildren = getInvalidSizedChildren(false); - } - super.setWidth(width, unit); - repaintChangedChildTrees(dirtyChildren, childrenMayBecomeUndefined, - false); - } - - private void repaintChangedChildTrees( - Collection invalidChildren, - boolean childrenMayBecomeUndefined, boolean vertical) { - if (childrenMayBecomeUndefined) { - Collection previouslyInvalidComponents = invalidChildren; - invalidChildren = getInvalidSizedChildren(vertical); - if (previouslyInvalidComponents != null && invalidChildren != null) { - for (Iterator iterator = invalidChildren.iterator(); iterator - .hasNext();) { - Component component = iterator.next(); - if (previouslyInvalidComponents.contains(component)) { - // still invalid don't repaint - iterator.remove(); - } - } - } - } else if (invalidChildren != null) { - Collection stillInvalidChildren = getInvalidSizedChildren(vertical); - if (stillInvalidChildren != null) { - for (Component component : stillInvalidChildren) { - // didn't become valid - invalidChildren.remove(component); - } - } - } - if (invalidChildren != null) { - repaintChildTrees(invalidChildren); - } - } - - private Collection getInvalidSizedChildren(final boolean vertical) { - HashSet components = null; - if (this instanceof Panel) { - Panel p = (Panel) this; - ComponentContainer content = p.getContent(); - boolean valid = vertical ? ComponentSizeValidator - .checkHeights(content) : ComponentSizeValidator - .checkWidths(content); - - if (!valid) { - components = new HashSet(1); - components.add(content); - } - } else { - for (Iterator componentIterator = getComponentIterator(); componentIterator - .hasNext();) { - Component component = componentIterator.next(); - boolean valid = vertical ? ComponentSizeValidator - .checkHeights(component) : ComponentSizeValidator - .checkWidths(component); - if (!valid) { - if (components == null) { - components = new HashSet(); - } - components.add(component); - } - } - } - return components; - } - - private void repaintChildTrees(Collection dirtyChildren) { - for (Component c : dirtyChildren) { - if (c instanceof ComponentContainer) { - ComponentContainer cc = (ComponentContainer) c; - cc.requestRepaintAll(); - } else { - c.requestRepaint(); - } - } - } - - @Override - public void setHeight(float height, Unit unit) { - /* - * child tree repaints may be needed, due to our fall back support for - * invalid relative sizes - */ - Collection dirtyChildren = null; - boolean childrenMayBecomeUndefined = false; - if (getHeight() == SIZE_UNDEFINED && height != SIZE_UNDEFINED) { - // children currently in invalid state may need repaint - dirtyChildren = getInvalidSizedChildren(true); - } else if ((height == SIZE_UNDEFINED && getHeight() != SIZE_UNDEFINED) - || (unit == Unit.PERCENTAGE - && getHeightUnits() != Unit.PERCENTAGE && !ComponentSizeValidator - .parentCanDefineHeight(this))) { - /* - * relative height children may get to invalid state if height - * becomes invalid. Height may also become invalid if units become - * percentage due to the fallback support. - */ - childrenMayBecomeUndefined = true; - dirtyChildren = getInvalidSizedChildren(true); - } - super.setHeight(height, unit); - repaintChangedChildTrees(dirtyChildren, childrenMayBecomeUndefined, - true); - } - - @Override - public Iterator iterator() { - return getComponentIterator(); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.ui.HasComponents#isComponentVisible(com.vaadin.ui.Component) - */ - @Override - public boolean isComponentVisible(Component childComponent) { - return true; - } -} \ No newline at end of file diff --git a/src/com/vaadin/ui/AbstractField.java b/src/com/vaadin/ui/AbstractField.java deleted file mode 100644 index 6fe7f54df5..0000000000 --- a/src/com/vaadin/ui/AbstractField.java +++ /dev/null @@ -1,1657 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.logging.Logger; - -import com.vaadin.data.Buffered; -import com.vaadin.data.Property; -import com.vaadin.data.Validatable; -import com.vaadin.data.Validator; -import com.vaadin.data.Validator.InvalidValueException; -import com.vaadin.data.util.converter.Converter; -import com.vaadin.data.util.converter.Converter.ConversionException; -import com.vaadin.data.util.converter.ConverterUtil; -import com.vaadin.event.Action; -import com.vaadin.event.ShortcutAction; -import com.vaadin.event.ShortcutListener; -import com.vaadin.shared.AbstractFieldState; -import com.vaadin.terminal.AbstractErrorMessage; -import com.vaadin.terminal.CompositeErrorMessage; -import com.vaadin.terminal.ErrorMessage; - -/** - *

- * Abstract field component for implementing buffered property editors. The - * field may hold an internal value, or it may be connected to any data source - * that implements the {@link com.vaadin.data.Property}interface. - * AbstractField implements that interface itself, too, so - * accessing the Property value represented by it is straightforward. - *

- * - *

- * AbstractField also provides the {@link com.vaadin.data.Buffered} interface - * for buffering the data source value. By default the Field is in write - * through-mode and {@link #setWriteThrough(boolean)}should be called to enable - * buffering. - *

- * - *

- * The class also supports {@link com.vaadin.data.Validator validators} to make - * sure the value contained in the field is valid. - *

- * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public abstract class AbstractField extends AbstractComponent implements - Field, Property.ReadOnlyStatusChangeListener, - Property.ReadOnlyStatusChangeNotifier, Action.ShortcutNotifier { - - /* Private members */ - - private static final Logger logger = Logger.getLogger(AbstractField.class - .getName()); - - /** - * Value of the abstract field. - */ - private T value; - - /** - * A converter used to convert from the data model type to the field type - * and vice versa. - */ - private Converter converter = null; - /** - * Connected data-source. - */ - private Property dataSource = null; - - /** - * The list of validators. - */ - private LinkedList validators = null; - - /** - * Auto commit mode. - */ - private boolean writeThroughMode = true; - - /** - * Reads the value from data-source, when it is not modified. - */ - private boolean readThroughMode = true; - - /** - * Flag to indicate that the field is currently committing its value to the - * datasource. - */ - private boolean committingValueToDataSource = false; - - /** - * Current source exception. - */ - private Buffered.SourceException currentBufferedSourceException = null; - - /** - * Are the invalid values allowed in fields ? - */ - private boolean invalidAllowed = true; - - /** - * Are the invalid values committed ? - */ - private boolean invalidCommitted = false; - - /** - * The error message for the exception that is thrown when the field is - * required but empty. - */ - private String requiredError = ""; - - /** - * The error message that is shown when the field value cannot be converted. - */ - private String conversionError = "Could not convert value to {0}"; - - /** - * Is automatic validation enabled. - */ - private boolean validationVisible = true; - - private boolean valueWasModifiedByDataSourceDuringCommit; - - /** - * Whether this field is currently registered as listening to events from - * its data source. - * - * @see #setPropertyDataSource(Property) - * @see #addPropertyListeners() - * @see #removePropertyListeners() - */ - private boolean isListeningToPropertyEvents = false; - - /* Component basics */ - - /* - * Paints the field. Don't add a JavaDoc comment here, we use the default - * documentation from the implemented interface. - */ - - /** - * Returns true if the error indicator be hidden when painting the component - * even when there are errors. - * - * This is a mostly internal method, but can be overridden in subclasses - * e.g. if the error indicator should also be shown for empty fields in some - * cases. - * - * @return true to hide the error indicator, false to use the normal logic - * to show it when there are errors - */ - protected boolean shouldHideErrors() { - // getErrorMessage() can still return something else than null based on - // validation etc. - return isRequired() && isEmpty() && getComponentError() == null; - } - - /** - * Returns the type of the Field. The methods getValue and - * setValue must be compatible with this type: one must be able - * to safely cast the value returned from getValue to the given - * type and pass any variable assignable to this type as an argument to - * setValue. - * - * @return the type of the Field - */ - @Override - public abstract Class getType(); - - /** - * The abstract field is read only also if the data source is in read only - * mode. - */ - @Override - public boolean isReadOnly() { - return super.isReadOnly() - || (dataSource != null && dataSource.isReadOnly()); - } - - /** - * Changes the readonly state and throw read-only status change events. - * - * @see com.vaadin.ui.Component#setReadOnly(boolean) - */ - @Override - public void setReadOnly(boolean readOnly) { - super.setReadOnly(readOnly); - fireReadOnlyStatusChange(); - } - - /** - * Tests if the invalid data is committed to datasource. - * - * @see com.vaadin.data.BufferedValidatable#isInvalidCommitted() - */ - @Override - public boolean isInvalidCommitted() { - return invalidCommitted; - } - - /** - * Sets if the invalid data should be committed to datasource. - * - * @see com.vaadin.data.BufferedValidatable#setInvalidCommitted(boolean) - */ - @Override - public void setInvalidCommitted(boolean isCommitted) { - invalidCommitted = isCommitted; - } - - /* - * Saves the current value to the data source Don't add a JavaDoc comment - * here, we use the default documentation from the implemented interface. - */ - @Override - public void commit() throws Buffered.SourceException, InvalidValueException { - if (dataSource != null && !dataSource.isReadOnly()) { - if ((isInvalidCommitted() || isValid())) { - try { - - // Commits the value to datasource. - valueWasModifiedByDataSourceDuringCommit = false; - committingValueToDataSource = true; - getPropertyDataSource().setValue(getConvertedValue()); - } catch (final Throwable e) { - - // Sets the buffering state. - SourceException sourceException = new Buffered.SourceException( - this, e); - setCurrentBufferedSourceException(sourceException); - - // Throws the source exception. - throw sourceException; - } finally { - committingValueToDataSource = false; - } - } else { - /* An invalid value and we don't allow them, throw the exception */ - validate(); - } - } - - // The abstract field is not modified anymore - if (isModified()) { - setModified(false); - } - - // If successful, remove set the buffering state to be ok - if (getCurrentBufferedSourceException() != null) { - setCurrentBufferedSourceException(null); - } - - if (valueWasModifiedByDataSourceDuringCommit) { - valueWasModifiedByDataSourceDuringCommit = false; - fireValueChange(false); - } - - } - - /* - * Updates the value from the data source. Don't add a JavaDoc comment here, - * we use the default documentation from the implemented interface. - */ - @Override - public void discard() throws Buffered.SourceException { - if (dataSource != null) { - - // Gets the correct value from datasource - T newFieldValue; - try { - - // Discards buffer by overwriting from datasource - newFieldValue = convertFromDataSource(getDataSourceValue()); - - // If successful, remove set the buffering state to be ok - if (getCurrentBufferedSourceException() != null) { - setCurrentBufferedSourceException(null); - } - } catch (final Throwable e) { - // FIXME: What should really be done here if conversion fails? - - // Sets the buffering state - currentBufferedSourceException = new Buffered.SourceException( - this, e); - requestRepaint(); - - // Throws the source exception - throw currentBufferedSourceException; - } - - final boolean wasModified = isModified(); - setModified(false); - - // If the new value differs from the previous one - if (!equals(newFieldValue, getInternalValue())) { - setInternalValue(newFieldValue); - fireValueChange(false); - } else if (wasModified) { - // If the value did not change, but the modification status did - requestRepaint(); - } - } - } - - /** - * Gets the value from the data source. This is only here because of clarity - * in the code that handles both the data model value and the field value. - * - * @return The value of the property data source - */ - private Object getDataSourceValue() { - return dataSource.getValue(); - } - - /** - * Returns the field value. This is always identical to {@link #getValue()} - * and only here because of clarity in the code that handles both the data - * model value and the field value. - * - * @return The value of the field - */ - private T getFieldValue() { - // Give the value from abstract buffers if the field if possible - if (dataSource == null || !isReadThrough() || isModified()) { - return getInternalValue(); - } - - // There is no buffered value so use whatever the data model provides - return convertFromDataSource(getDataSourceValue()); - } - - /* - * Has the field been modified since the last commit()? Don't add a JavaDoc - * comment here, we use the default documentation from the implemented - * interface. - */ - @Override - public boolean isModified() { - return getState().isModified(); - } - - private void setModified(boolean modified) { - getState().setModified(modified); - requestRepaint(); - } - - /* - * Tests if the field is in write-through mode. Don't add a JavaDoc comment - * here, we use the default documentation from the implemented interface. - */ - @Override - public boolean isWriteThrough() { - return writeThroughMode; - } - - /** - * Sets the field's write-through mode to the specified status. When - * switching the write-through mode on, a {@link #commit()} will be - * performed. - * - * @see #setBuffered(boolean) for an easier way to control read through and - * write through modes - * - * @param writeThrough - * Boolean value to indicate if the object should be in - * write-through mode after the call. - * @throws SourceException - * If the operation fails because of an exception is thrown by - * the data source. - * @throws InvalidValueException - * If the implicit commit operation fails because of a - * validation error. - * @deprecated Use {@link #setBuffered(boolean)} instead. Note that - * setReadThrough(true), setWriteThrough(true) equals - * setBuffered(false) - */ - @Override - @Deprecated - public void setWriteThrough(boolean writeThrough) - throws Buffered.SourceException, InvalidValueException { - if (writeThroughMode == writeThrough) { - return; - } - writeThroughMode = writeThrough; - if (writeThroughMode) { - commit(); - } - } - - /* - * Tests if the field is in read-through mode. Don't add a JavaDoc comment - * here, we use the default documentation from the implemented interface. - */ - @Override - public boolean isReadThrough() { - return readThroughMode; - } - - /** - * Sets the field's read-through mode to the specified status. When - * switching read-through mode on, the object's value is updated from the - * data source. - * - * @see #setBuffered(boolean) for an easier way to control read through and - * write through modes - * - * @param readThrough - * Boolean value to indicate if the object should be in - * read-through mode after the call. - * - * @throws SourceException - * If the operation fails because of an exception is thrown by - * the data source. The cause is included in the exception. - * @deprecated Use {@link #setBuffered(boolean)} instead. Note that - * setReadThrough(true), setWriteThrough(true) equals - * setBuffered(false) - */ - @Override - @Deprecated - public void setReadThrough(boolean readThrough) - throws Buffered.SourceException { - if (readThroughMode == readThrough) { - return; - } - readThroughMode = readThrough; - if (!isModified() && readThroughMode && getPropertyDataSource() != null) { - setInternalValue(convertFromDataSource(getDataSourceValue())); - fireValueChange(false); - } - } - - /** - * Sets the buffered mode of this Field. - *

- * When the field is in buffered mode, changes will not be committed to the - * property data source until {@link #commit()} is called. - *

- *

- * Changing buffered mode will change the read through and write through - * state for the field. - *

- *

- * Mixing calls to {@link #setBuffered(boolean)} and - * {@link #setReadThrough(boolean)} or {@link #setWriteThrough(boolean)} is - * generally a bad idea. - *

- * - * @param buffered - * true if buffered mode should be turned on, false otherwise - */ - @Override - public void setBuffered(boolean buffered) { - setReadThrough(!buffered); - setWriteThrough(!buffered); - } - - /** - * Checks the buffered mode of this Field. - *

- * This method only returns true if both read and write buffering is used. - * - * @return true if buffered mode is on, false otherwise - */ - @Override - public boolean isBuffered() { - return !isReadThrough() && !isWriteThrough(); - } - - /* Property interface implementation */ - - /** - * Returns the (field) value converted to a String using toString(). - * - * @see java.lang.Object#toString() - * @deprecated Instead use {@link #getValue()} to get the value of the - * field, {@link #getConvertedValue()} to get the field value - * converted to the data model type or - * {@link #getPropertyDataSource()} .getValue() to get the value - * of the data source. - */ - @Deprecated - @Override - public String toString() { - logger.warning("You are using AbstractField.toString() to get the value for a " - + getClass().getSimpleName() - + ". This is not recommended and will not be supported in future versions."); - final Object value = getFieldValue(); - if (value == null) { - return null; - } - return value.toString(); - } - - /** - * Gets the current value of the field. - * - *

- * This is the visible, modified and possible invalid value the user have - * entered to the field. - *

- * - *

- * Note that the object returned is compatible with getType(). For example, - * if the type is String, this returns Strings even when the underlying - * datasource is of some other type. In order to access the converted value, - * use {@link #getConvertedValue()} and to access the value of the property - * data source, use {@link Property#getValue()} for the property data - * source. - *

- * - *

- * Since Vaadin 7.0, no implicit conversions between other data types and - * String are performed, but a converter is used if set. - *

- * - * @return the current value of the field. - */ - @Override - public T getValue() { - return getFieldValue(); - } - - /** - * Sets the value of the field. - * - * @param newFieldValue - * the New value of the field. - * @throws Property.ReadOnlyException - */ - @Override - public void setValue(Object newFieldValue) - throws Property.ReadOnlyException, Converter.ConversionException { - // This check is needed as long as setValue accepts Object instead of T - if (newFieldValue != null) { - if (!getType().isAssignableFrom(newFieldValue.getClass())) { - throw new Converter.ConversionException("Value of type " - + newFieldValue.getClass() + " cannot be assigned to " - + getType().getName()); - } - } - setValue((T) newFieldValue, false); - } - - /** - * Sets the value of the field. - * - * @param newFieldValue - * the New value of the field. - * @param repaintIsNotNeeded - * True iff caller is sure that repaint is not needed. - * @throws Property.ReadOnlyException - */ - protected void setValue(T newFieldValue, boolean repaintIsNotNeeded) - throws Property.ReadOnlyException, Converter.ConversionException, - InvalidValueException { - - if (!equals(newFieldValue, getInternalValue())) { - - // Read only fields can not be changed - if (isReadOnly()) { - throw new Property.ReadOnlyException(); - } - - // Repaint is needed even when the client thinks that it knows the - // new state if validity of the component may change - if (repaintIsNotNeeded - && (isRequired() || getValidators() != null || getConverter() != null)) { - repaintIsNotNeeded = false; - } - - if (!isInvalidAllowed()) { - /* - * If invalid values are not allowed the value must be validated - * before it is set. If validation fails, the - * InvalidValueException is thrown and the internal value is not - * updated. - */ - validate(newFieldValue); - } - - // Changes the value - setInternalValue(newFieldValue); - setModified(dataSource != null); - - valueWasModifiedByDataSourceDuringCommit = false; - // In write through mode , try to commit - if (isWriteThrough() && dataSource != null - && (isInvalidCommitted() || isValid())) { - try { - - // Commits the value to datasource - committingValueToDataSource = true; - getPropertyDataSource().setValue( - convertToModel(newFieldValue)); - - // The buffer is now unmodified - setModified(false); - - } catch (final Throwable e) { - - // Sets the buffering state - currentBufferedSourceException = new Buffered.SourceException( - this, e); - requestRepaint(); - - // Throws the source exception - throw currentBufferedSourceException; - } finally { - committingValueToDataSource = false; - } - } - - // If successful, remove set the buffering state to be ok - if (getCurrentBufferedSourceException() != null) { - setCurrentBufferedSourceException(null); - } - - if (valueWasModifiedByDataSourceDuringCommit) { - /* - * Value was modified by datasource. Force repaint even if - * repaint was not requested. - */ - valueWasModifiedByDataSourceDuringCommit = repaintIsNotNeeded = false; - } - - // Fires the value change - fireValueChange(repaintIsNotNeeded); - - } - } - - private static boolean equals(Object value1, Object value2) { - if (value1 == null) { - return value2 == null; - } - return value1.equals(value2); - } - - /* External data source */ - - /** - * Gets the current data source of the field, if any. - * - * @return the current data source as a Property, or null if - * none defined. - */ - @Override - public Property getPropertyDataSource() { - return dataSource; - } - - /** - *

- * Sets the specified Property as the data source for the field. All - * uncommitted changes are replaced with a value from the new data source. - *

- * - *

- * If the datasource has any validators, the same validators are added to - * the field. Because the default behavior of the field is to allow invalid - * values, but not to allow committing them, this only adds visual error - * messages to fields and do not allow committing them as long as the value - * is invalid. After the value is valid, the error message is not shown and - * the commit can be done normally. - *

- * - *

- * If the data source implements - * {@link com.vaadin.data.Property.ValueChangeNotifier} and/or - * {@link com.vaadin.data.Property.ReadOnlyStatusChangeNotifier}, the field - * registers itself as a listener and updates itself according to the events - * it receives. To avoid memory leaks caused by references to a field no - * longer in use, the listener registrations are removed on - * {@link AbstractField#detach() detach} and re-added on - * {@link AbstractField#attach() attach}. - *

- * - *

- * Note: before 6.5 we actually called discard() method in the beginning of - * the method. This was removed to simplify implementation, avoid excess - * calls to backing property and to avoid odd value change events that were - * previously fired (developer expects 0-1 value change events if this - * method is called). Some complex field implementations might now need to - * override this method to do housekeeping similar to discard(). - *

- * - * @param newDataSource - * the new data source Property. - */ - @Override - public void setPropertyDataSource(Property newDataSource) { - - // Saves the old value - final Object oldValue = getInternalValue(); - - // Stop listening to the old data source - removePropertyListeners(); - - // Sets the new data source - dataSource = newDataSource; - getState().setPropertyReadOnly( - dataSource == null ? false : dataSource.isReadOnly()); - - // Check if the current converter is compatible. - if (newDataSource != null - && !ConverterUtil.canConverterHandle(getConverter(), getType(), - newDataSource.getType())) { - // Changing from e.g. Number -> Double should set a new converter, - // changing from Double -> Number can keep the old one (Property - // accepts Number) - - // Set a new converter if there is a new data source and - // there is no old converter or the old is incompatible. - setConverter(newDataSource.getType()); - } - // Gets the value from source - try { - if (dataSource != null) { - T fieldValue = convertFromDataSource(getDataSourceValue()); - setInternalValue(fieldValue); - } - setModified(false); - if (getCurrentBufferedSourceException() != null) { - setCurrentBufferedSourceException(null); - } - } catch (final Throwable e) { - setCurrentBufferedSourceException(new Buffered.SourceException( - this, e)); - setModified(true); - } - - // Listen to new data source if possible - addPropertyListeners(); - - // Copy the validators from the data source - if (dataSource instanceof Validatable) { - final Collection validators = ((Validatable) dataSource) - .getValidators(); - if (validators != null) { - for (final Iterator i = validators.iterator(); i - .hasNext();) { - addValidator(i.next()); - } - } - } - - // Fires value change if the value has changed - T value = getInternalValue(); - if ((value != oldValue) - && ((value != null && !value.equals(oldValue)) || value == null)) { - fireValueChange(false); - } - } - - /** - * Retrieves a converter for the field from the converter factory defined - * for the application. Clears the converter if no application reference is - * available or if the factory returns null. - * - * @param datamodelType - * The type of the data model that we want to be able to convert - * from - */ - public void setConverter(Class datamodelType) { - Converter c = (Converter) ConverterUtil.getConverter( - getType(), datamodelType, getApplication()); - setConverter(c); - } - - /** - * Convert the given value from the data source type to the UI type. - * - * @param newValue - * The data source value to convert. - * @return The converted value that is compatible with the UI type or the - * original value if its type is compatible and no converter is set. - * @throws Converter.ConversionException - * if there is no converter and the type is not compatible with - * the data source type. - */ - private T convertFromDataSource(Object newValue) { - return ConverterUtil.convertFromModel(newValue, getType(), - getConverter(), getLocale()); - } - - /** - * Convert the given value from the UI type to the data source type. - * - * @param fieldValue - * The value to convert. Typically returned by - * {@link #getFieldValue()} - * @return The converted value that is compatible with the data source type. - * @throws Converter.ConversionException - * if there is no converter and the type is not compatible with - * the data source type. - */ - private Object convertToModel(T fieldValue) - throws Converter.ConversionException { - try { - Class modelType = null; - Property pd = getPropertyDataSource(); - if (pd != null) { - modelType = pd.getType(); - } else if (getConverter() != null) { - modelType = getConverter().getModelType(); - } - return ConverterUtil.convertToModel(fieldValue, - (Class) modelType, getConverter(), getLocale()); - } catch (ConversionException e) { - throw new ConversionException( - getConversionError(converter.getModelType()), e); - } - } - - /** - * Returns the conversion error with {0} replaced by the data source type. - * - * @param dataSourceType - * The type of the data source - * @return The value conversion error string with parameters replaced. - */ - protected String getConversionError(Class dataSourceType) { - if (dataSourceType == null) { - return getConversionError(); - } else { - return getConversionError().replace("{0}", - dataSourceType.getSimpleName()); - } - } - - /** - * Returns the current value (as returned by {@link #getValue()}) converted - * to the data source type. - *

- * This returns the same as {@link AbstractField#getValue()} if no converter - * has been set. The value is not necessarily the same as the data source - * value e.g. if the field is in buffered mode and has been modified. - *

- * - * @return The converted value that is compatible with the data source type - */ - public Object getConvertedValue() { - return convertToModel(getFieldValue()); - } - - /** - * Sets the value of the field using a value of the data source type. The - * value given is converted to the field type and then assigned to the - * field. This will update the property data source in the same way as when - * {@link #setValue(Object)} is called. - * - * @param value - * The value to set. Must be the same type as the data source. - */ - public void setConvertedValue(Object value) { - setValue(convertFromDataSource(value)); - } - - /* Validation */ - - /** - * Adds a new validator for the field's value. All validators added to a - * field are checked each time the its value changes. - * - * @param validator - * the new validator to be added. - */ - @Override - public void addValidator(Validator validator) { - if (validators == null) { - validators = new LinkedList(); - } - validators.add(validator); - requestRepaint(); - } - - /** - * Gets the validators of the field. - * - * @return the Unmodifiable collection that holds all validators for the - * field. - */ - @Override - public Collection getValidators() { - if (validators == null || validators.isEmpty()) { - return null; - } - return Collections.unmodifiableCollection(validators); - } - - /** - * Removes the validator from the field. - * - * @param validator - * the validator to remove. - */ - @Override - public void removeValidator(Validator validator) { - if (validators != null) { - validators.remove(validator); - } - requestRepaint(); - } - - /** - * Removes all validators from the field. - */ - public void removeAllValidators() { - if (validators != null) { - validators.clear(); - } - requestRepaint(); - } - - /** - * Tests the current value against registered validators if the field is not - * empty. If the field is empty it is considered valid if it is not required - * and invalid otherwise. Validators are never checked for empty fields. - * - * In most cases, {@link #validate()} should be used instead of - * {@link #isValid()} to also get the error message. - * - * @return true if all registered validators claim that the - * current value is valid or if the field is empty and not required, - * false otherwise. - */ - @Override - public boolean isValid() { - - try { - validate(); - return true; - } catch (InvalidValueException e) { - return false; - } - } - - /** - * Checks the validity of the Field. - * - * A field is invalid if it is set as required (using - * {@link #setRequired(boolean)} and is empty, if one or several of the - * validators added to the field indicate it is invalid or if the value - * cannot be converted provided a converter has been set. - * - * The "required" validation is a built-in validation feature. If the field - * is required and empty this method throws an EmptyValueException with the - * error message set using {@link #setRequiredError(String)}. - * - * @see com.vaadin.data.Validatable#validate() - */ - @Override - public void validate() throws Validator.InvalidValueException { - - if (isRequired() && isEmpty()) { - throw new Validator.EmptyValueException(requiredError); - } - validate(getFieldValue()); - } - - /** - * Validates that the given value pass the validators for the field. - *

- * This method does not check the requiredness of the field. - * - * @param fieldValue - * The value to check - * @throws Validator.InvalidValueException - * if one or several validators fail - */ - protected void validate(T fieldValue) - throws Validator.InvalidValueException { - - Object valueToValidate = fieldValue; - - // If there is a converter we start by converting the value as we want - // to validate the converted value - if (getConverter() != null) { - try { - valueToValidate = getConverter().convertToModel(fieldValue, - getLocale()); - } catch (Exception e) { - throw new InvalidValueException( - getConversionError(getConverter().getModelType())); - } - } - - List validationExceptions = new ArrayList(); - if (validators != null) { - // Gets all the validation errors - for (Validator v : validators) { - try { - v.validate(valueToValidate); - } catch (final Validator.InvalidValueException e) { - validationExceptions.add(e); - } - } - } - - // If there were no errors - if (validationExceptions.isEmpty()) { - return; - } - - // If only one error occurred, throw it forwards - if (validationExceptions.size() == 1) { - throw validationExceptions.get(0); - } - - InvalidValueException[] exceptionArray = validationExceptions - .toArray(new InvalidValueException[validationExceptions.size()]); - - // Create a composite validator and include all exceptions - throw new Validator.InvalidValueException(null, exceptionArray); - } - - /** - * Fields allow invalid values by default. In most cases this is wanted, - * because the field otherwise visually forget the user input immediately. - * - * @return true iff the invalid values are allowed. - * @see com.vaadin.data.Validatable#isInvalidAllowed() - */ - @Override - public boolean isInvalidAllowed() { - return invalidAllowed; - } - - /** - * Fields allow invalid values by default. In most cases this is wanted, - * because the field otherwise visually forget the user input immediately. - *

- * In common setting where the user wants to assure the correctness of the - * datasource, but allow temporarily invalid contents in the field, the user - * should add the validators to datasource, that should not allow invalid - * values. The validators are automatically copied to the field when the - * datasource is set. - *

- * - * @see com.vaadin.data.Validatable#setInvalidAllowed(boolean) - */ - @Override - public void setInvalidAllowed(boolean invalidAllowed) - throws UnsupportedOperationException { - this.invalidAllowed = invalidAllowed; - } - - /** - * Error messages shown by the fields are composites of the error message - * thrown by the superclasses (that is the component error message), - * validation errors and buffered source errors. - * - * @see com.vaadin.ui.AbstractComponent#getErrorMessage() - */ - @Override - public ErrorMessage getErrorMessage() { - - /* - * Check validation errors only if automatic validation is enabled. - * Empty, required fields will generate a validation error containing - * the requiredError string. For these fields the exclamation mark will - * be hidden but the error must still be sent to the client. - */ - Validator.InvalidValueException validationError = null; - if (isValidationVisible()) { - try { - validate(); - } catch (Validator.InvalidValueException e) { - if (!e.isInvisible()) { - validationError = e; - } - } - } - - // Check if there are any systems errors - final ErrorMessage superError = super.getErrorMessage(); - - // Return if there are no errors at all - if (superError == null && validationError == null - && getCurrentBufferedSourceException() == null) { - return null; - } - - // Throw combination of the error types - return new CompositeErrorMessage( - new ErrorMessage[] { - superError, - AbstractErrorMessage - .getErrorMessageForException(validationError), - AbstractErrorMessage - .getErrorMessageForException(getCurrentBufferedSourceException()) }); - - } - - /* Value change events */ - - private static final Method VALUE_CHANGE_METHOD; - - static { - try { - VALUE_CHANGE_METHOD = Property.ValueChangeListener.class - .getDeclaredMethod("valueChange", - new Class[] { Property.ValueChangeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in AbstractField"); - } - } - - /* - * Adds a value change listener for the field. Don't add a JavaDoc comment - * here, we use the default documentation from the implemented interface. - */ - @Override - public void addListener(Property.ValueChangeListener listener) { - addListener(AbstractField.ValueChangeEvent.class, listener, - VALUE_CHANGE_METHOD); - } - - /* - * Removes a value change listener from the field. Don't add a JavaDoc - * comment here, we use the default documentation from the implemented - * interface. - */ - @Override - public void removeListener(Property.ValueChangeListener listener) { - removeListener(AbstractField.ValueChangeEvent.class, listener, - VALUE_CHANGE_METHOD); - } - - /** - * Emits the value change event. The value contained in the field is - * validated before the event is created. - */ - protected void fireValueChange(boolean repaintIsNotNeeded) { - fireEvent(new AbstractField.ValueChangeEvent(this)); - if (!repaintIsNotNeeded) { - requestRepaint(); - } - } - - /* Read-only status change events */ - - private static final Method READ_ONLY_STATUS_CHANGE_METHOD; - - static { - try { - READ_ONLY_STATUS_CHANGE_METHOD = Property.ReadOnlyStatusChangeListener.class - .getDeclaredMethod( - "readOnlyStatusChange", - new Class[] { Property.ReadOnlyStatusChangeEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in AbstractField"); - } - } - - /** - * React to read only status changes of the property by requesting a - * repaint. - * - * @see Property.ReadOnlyStatusChangeListener - */ - @Override - public void readOnlyStatusChange(Property.ReadOnlyStatusChangeEvent event) { - getState().setPropertyReadOnly(event.getProperty().isReadOnly()); - requestRepaint(); - } - - /** - * An Event object specifying the Property whose read-only - * status has changed. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public static class ReadOnlyStatusChangeEvent extends Component.Event - implements Property.ReadOnlyStatusChangeEvent, Serializable { - - /** - * New instance of text change event. - * - * @param source - * the Source of the event. - */ - public ReadOnlyStatusChangeEvent(AbstractField source) { - super(source); - } - - /** - * Property where the event occurred. - * - * @return the Source of the event. - */ - @Override - public Property getProperty() { - return (Property) getSource(); - } - } - - /* - * Adds a read-only status change listener for the field. Don't add a - * JavaDoc comment here, we use the default documentation from the - * implemented interface. - */ - @Override - public void addListener(Property.ReadOnlyStatusChangeListener listener) { - addListener(Property.ReadOnlyStatusChangeEvent.class, listener, - READ_ONLY_STATUS_CHANGE_METHOD); - } - - /* - * Removes a read-only status change listener from the field. Don't add a - * JavaDoc comment here, we use the default documentation from the - * implemented interface. - */ - @Override - public void removeListener(Property.ReadOnlyStatusChangeListener listener) { - removeListener(Property.ReadOnlyStatusChangeEvent.class, listener, - READ_ONLY_STATUS_CHANGE_METHOD); - } - - /** - * Emits the read-only status change event. The value contained in the field - * is validated before the event is created. - */ - protected void fireReadOnlyStatusChange() { - fireEvent(new AbstractField.ReadOnlyStatusChangeEvent(this)); - } - - /** - * This method listens to data source value changes and passes the changes - * forwards. - * - * Changes are not forwarded to the listeners of the field during internal - * operations of the field to avoid duplicate notifications. - * - * @param event - * the value change event telling the data source contents have - * changed. - */ - @Override - public void valueChange(Property.ValueChangeEvent event) { - if (isReadThrough()) { - if (committingValueToDataSource) { - boolean propertyNotifiesOfTheBufferedValue = equals(event - .getProperty().getValue(), getInternalValue()); - if (!propertyNotifiesOfTheBufferedValue) { - /* - * Property (or chained property like PropertyFormatter) now - * reports different value than the one the field has just - * committed to it. In this case we respect the property - * value. - * - * Still, we don't fire value change yet, but instead - * postpone it until "commit" is done. See setValue(Object, - * boolean) and commit(). - */ - readValueFromProperty(event); - valueWasModifiedByDataSourceDuringCommit = true; - } - } else if (!isModified()) { - readValueFromProperty(event); - fireValueChange(false); - } - } - } - - private void readValueFromProperty(Property.ValueChangeEvent event) { - setInternalValue(convertFromDataSource(event.getProperty().getValue())); - } - - /** - * {@inheritDoc} - */ - @Override - public void focus() { - super.focus(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component.Focusable#getTabIndex() - */ - @Override - public int getTabIndex() { - return getState().getTabIndex(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component.Focusable#setTabIndex(int) - */ - @Override - public void setTabIndex(int tabIndex) { - getState().setTabIndex(tabIndex); - requestRepaint(); - } - - /** - * Returns the internal field value, which might not match the data source - * value e.g. if the field has been modified and is not in write-through - * mode. - * - * This method can be overridden by subclasses together with - * {@link #setInternalValue(Object)} to compute internal field value at - * runtime. When doing so, typically also {@link #isModified()} needs to be - * overridden and care should be taken in the management of the empty state - * and buffering support. - * - * @return internal field value - */ - protected T getInternalValue() { - return value; - } - - /** - * Sets the internal field value. This is purely used by AbstractField to - * change the internal Field value. It does not trigger valuechange events. - * It can be overridden by the inheriting classes to update all dependent - * variables. - * - * Subclasses can also override {@link #getInternalValue()} if necessary. - * - * @param newValue - * the new value to be set. - */ - protected void setInternalValue(T newValue) { - value = newValue; - if (validators != null && !validators.isEmpty()) { - requestRepaint(); - } - } - - /** - * Notifies the component that it is connected to an application. - * - * @see com.vaadin.ui.Component#attach() - */ - @Override - public void attach() { - super.attach(); - - if (!isListeningToPropertyEvents) { - addPropertyListeners(); - if (!isModified() && isReadThrough()) { - // Update value from data source - discard(); - } - } - } - - @Override - public void detach() { - super.detach(); - // Stop listening to data source events on detach to avoid a potential - // memory leak. See #6155. - removePropertyListeners(); - } - - /** - * Is this field required. Required fields must filled by the user. - * - * If the field is required, it is visually indicated in the user interface. - * Furthermore, setting field to be required implicitly adds "non-empty" - * validator and thus isValid() == false or any isEmpty() fields. In those - * cases validation errors are not painted as it is obvious that the user - * must fill in the required fields. - * - * On the other hand, for the non-required fields isValid() == true if the - * field isEmpty() regardless of any attached validators. - * - * - * @return true if the field is required, otherwise - * false. - */ - @Override - public boolean isRequired() { - return getState().isRequired(); - } - - /** - * Sets the field required. Required fields must filled by the user. - * - * If the field is required, it is visually indicated in the user interface. - * Furthermore, setting field to be required implicitly adds "non-empty" - * validator and thus isValid() == false or any isEmpty() fields. In those - * cases validation errors are not painted as it is obvious that the user - * must fill in the required fields. - * - * On the other hand, for the non-required fields isValid() == true if the - * field isEmpty() regardless of any attached validators. - * - * @param required - * Is the field required. - */ - @Override - public void setRequired(boolean required) { - getState().setRequired(required); - requestRepaint(); - } - - /** - * Set the error that is show if this field is required, but empty. When - * setting requiredMessage to be "" or null, no error pop-up or exclamation - * mark is shown for a empty required field. This faults to "". Even in - * those cases isValid() returns false for empty required fields. - * - * @param requiredMessage - * Message to be shown when this field is required, but empty. - */ - @Override - public void setRequiredError(String requiredMessage) { - requiredError = requiredMessage; - requestRepaint(); - } - - @Override - public String getRequiredError() { - return requiredError; - } - - /** - * Gets the error that is shown if the field value cannot be converted to - * the data source type. - * - * @return The error that is shown if conversion of the field value fails - */ - public String getConversionError() { - return conversionError; - } - - /** - * Sets the error that is shown if the field value cannot be converted to - * the data source type. If {0} is present in the message, it will be - * replaced by the simple name of the data source type. - * - * @param valueConversionError - * Message to be shown when conversion of the value fails - */ - public void setConversionError(String valueConversionError) { - this.conversionError = valueConversionError; - requestRepaint(); - } - - /** - * Is the field empty? - * - * In general, "empty" state is same as null. As an exception, TextField - * also treats empty string as "empty". - */ - protected boolean isEmpty() { - return (getFieldValue() == null); - } - - /** - * Is automatic, visible validation enabled? - * - * If automatic validation is enabled, any validators connected to this - * component are evaluated while painting the component and potential error - * messages are sent to client. If the automatic validation is turned off, - * isValid() and validate() methods still work, but one must show the - * validation in their own code. - * - * @return True, if automatic validation is enabled. - */ - public boolean isValidationVisible() { - return validationVisible; - } - - /** - * Enable or disable automatic, visible validation. - * - * If automatic validation is enabled, any validators connected to this - * component are evaluated while painting the component and potential error - * messages are sent to client. If the automatic validation is turned off, - * isValid() and validate() methods still work, but one must show the - * validation in their own code. - * - * @param validateAutomatically - * True, if automatic validation is enabled. - */ - public void setValidationVisible(boolean validateAutomatically) { - if (validationVisible != validateAutomatically) { - requestRepaint(); - validationVisible = validateAutomatically; - } - } - - /** - * Sets the current buffered source exception. - * - * @param currentBufferedSourceException - */ - public void setCurrentBufferedSourceException( - Buffered.SourceException currentBufferedSourceException) { - this.currentBufferedSourceException = currentBufferedSourceException; - requestRepaint(); - } - - /** - * Gets the current buffered source exception. - * - * @return The current source exception - */ - protected Buffered.SourceException getCurrentBufferedSourceException() { - return currentBufferedSourceException; - } - - /** - * A ready-made {@link ShortcutListener} that focuses the given - * {@link Focusable} (usually a {@link Field}) when the keyboard shortcut is - * invoked. - * - */ - public static class FocusShortcut extends ShortcutListener { - protected Focusable focusable; - - /** - * Creates a keyboard shortcut for focusing the given {@link Focusable} - * using the shorthand notation defined in {@link ShortcutAction}. - * - * @param focusable - * to focused when the shortcut is invoked - * @param shorthandCaption - * caption with keycode and modifiers indicated - */ - public FocusShortcut(Focusable focusable, String shorthandCaption) { - super(shorthandCaption); - this.focusable = focusable; - } - - /** - * Creates a keyboard shortcut for focusing the given {@link Focusable}. - * - * @param focusable - * to focused when the shortcut is invoked - * @param keyCode - * keycode that invokes the shortcut - * @param modifiers - * modifiers required to invoke the shortcut - */ - public FocusShortcut(Focusable focusable, int keyCode, int... modifiers) { - super(null, keyCode, modifiers); - this.focusable = focusable; - } - - /** - * Creates a keyboard shortcut for focusing the given {@link Focusable}. - * - * @param focusable - * to focused when the shortcut is invoked - * @param keyCode - * keycode that invokes the shortcut - */ - public FocusShortcut(Focusable focusable, int keyCode) { - this(focusable, keyCode, null); - } - - @Override - public void handleAction(Object sender, Object target) { - focusable.focus(); - } - } - - /** - * Gets the converter used to convert the property data source value to the - * field value. - * - * @return The converter or null if none is set. - */ - public Converter getConverter() { - return converter; - } - - /** - * Sets the converter used to convert the field value to property data - * source type. The converter must have a presentation type that matches the - * field type. - * - * @param converter - * The new converter to use. - */ - public void setConverter(Converter converter) { - this.converter = (Converter) converter; - requestRepaint(); - } - - @Override - public AbstractFieldState getState() { - return (AbstractFieldState) super.getState(); - } - - @Override - public void updateState() { - super.updateState(); - - // Hide the error indicator if needed - getState().setHideErrors(shouldHideErrors()); - } - - /** - * Registers this as an event listener for events sent by the data source - * (if any). Does nothing if - * isListeningToPropertyEvents == true. - */ - private void addPropertyListeners() { - if (!isListeningToPropertyEvents) { - if (dataSource instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) dataSource).addListener(this); - } - if (dataSource instanceof Property.ReadOnlyStatusChangeNotifier) { - ((Property.ReadOnlyStatusChangeNotifier) dataSource) - .addListener(this); - } - isListeningToPropertyEvents = true; - } - } - - /** - * Stops listening to events sent by the data source (if any). Does nothing - * if isListeningToPropertyEvents == false. - */ - private void removePropertyListeners() { - if (isListeningToPropertyEvents) { - if (dataSource instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) dataSource) - .removeListener(this); - } - if (dataSource instanceof Property.ReadOnlyStatusChangeNotifier) { - ((Property.ReadOnlyStatusChangeNotifier) dataSource) - .removeListener(this); - } - isListeningToPropertyEvents = false; - } - } -} diff --git a/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/src/com/vaadin/ui/AbstractJavaScriptComponent.java deleted file mode 100644 index 5ec80573ab..0000000000 --- a/src/com/vaadin/ui/AbstractJavaScriptComponent.java +++ /dev/null @@ -1,165 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -import com.vaadin.shared.ui.JavaScriptComponentState; -import com.vaadin.terminal.JavaScriptCallbackHelper; -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.client.ui.JavaScriptWidget; - -/** - * Base class for Components with all client-side logic implemented using - * JavaScript. - *

- * When a new JavaScript component is initialized in the browser, the framework - * will look for a globally defined JavaScript function that will initialize the - * component. The name of the initialization function is formed by replacing . - * with _ in the name of the server-side class. If no such function is defined, - * each super class is used in turn until a match is found. The framework will - * thus first attempt with com_example_MyComponent for the - * server-side - * com.example.MyComponent extends AbstractJavaScriptComponent - * class. If MyComponent instead extends com.example.SuperComponent - * , then com_example_SuperComponent will also be attempted if - * com_example_MyComponent has not been defined. - *

- * JavaScript components have a very simple GWT widget ({@link JavaScriptWidget} - * ) just consisting of a div element to which the JavaScript code - * should initialize its own user interface. - *

- * The initialization function will be called with this pointing to - * a connector wrapper object providing integration to Vaadin with the following - * functions: - *

    - *
  • getConnectorId() - returns a string with the id of the - * connector.
  • - *
  • getParentId([connectorId]) - returns a string with the id of - * the connector's parent. If connectorId is provided, the id of - * the parent of the corresponding connector with the passed id is returned - * instead.
  • - *
  • getElement([connectorId]) - returns the DOM Element that is - * the root of a connector's widget. null is returned if the - * connector can not be found or if the connector doesn't have a widget. If - * connectorId is not provided, the connector id of the current - * connector will be used.
  • - *
  • getState() - returns an object corresponding to the shared - * state defined on the server. The scheme for conversion between Java and - * JavaScript types is described bellow.
  • - *
  • registerRpc([name, ] rpcObject) - registers the - * rpcObject as a RPC handler. rpcObject should be an - * object with field containing functions for all eligible RPC functions. If - * name is provided, the RPC handler will only used for RPC calls - * for the RPC interface with the same fully qualified Java name. If no - * name is provided, the RPC handler will be used for all incoming - * RPC invocations where the RPC method name is defined as a function field in - * the handler. The scheme for conversion between Java types in the RPC - * interface definition and the JavaScript values passed as arguments to the - * handler functions is described bellow.
  • - *
  • getRpcProxy([name]) - returns an RPC proxy object. If - * name is provided, the proxy object will contain functions for - * all methods in the RPC interface with the same fully qualified name, provided - * a RPC handler has been registered by the server-side code. If no - * name is provided, the returned RPC proxy object will contain - * functions for all methods in all RPC interfaces registered for the connector - * on the server. If the same method name is present in multiple registered RPC - * interfaces, the corresponding function in the RPC proxy object will throw an - * exception when called. The scheme for conversion between Java types in the - * RPC interface and the JavaScript values that should be passed to the - * functions is described bellow.
  • - *
  • translateVaadinUri(uri) - Translates a Vaadin URI to a URL - * that can be used in the browser. This is just way of accessing - * {@link ApplicationConnection#translateVaadinUri(String)}
  • - *
- * The connector wrapper also supports these special functions: - *
    - *
  • onStateChange - If the JavaScript code assigns a function to - * the field, that function is called whenever the contents of the shared state - * is changed.
  • - *
  • Any field name corresponding to a call to - * {@link #addFunction(String, JavaScriptFunction)} on the server will - * automatically be present as a function that triggers the registered function - * on the server.
  • - *
  • Any field name referred to using - * {@link #callFunction(String, Object...)} on the server will be called if a - * function has been assigned to the field.
  • - *
- *

- * - * Values in the Shared State and in RPC calls are converted between Java and - * JavaScript using the following conventions: - *

    - *
  • Primitive Java numbers (byte, char, int, long, float, double) and their - * boxed types (Byte, Character, Integer, Long, Float, Double) are represented - * by JavaScript numbers.
  • - *
  • The primitive Java boolean and the boxed Boolean are represented by - * JavaScript booleans.
  • - *
  • Java Strings are represented by JavaScript strings.
  • - *
  • List, Set and all arrays in Java are represented by JavaScript arrays.
  • - *
  • Map in Java is represented by JavaScript object with fields - * corresponding to the map keys.
  • - *
  • Any other Java Map is represented by a JavaScript array containing two - * arrays, the first contains the keys and the second contains the values in the - * same order.
  • - *
  • A Java Bean is represented by a JavaScript object with fields - * corresponding to the bean's properties.
  • - *
  • A Java Connector is represented by a JavaScript string containing the - * connector's id.
  • - *
  • A pluggable serialization mechanism is provided for types not described - * here. Please refer to the documentation for specific types for serialization - * information.
  • - *
- * - * @author Vaadin Ltd - * @version @VERSION@ - * @since 7.0.0 - */ -public abstract class AbstractJavaScriptComponent extends AbstractComponent { - private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( - this); - - @Override - protected void registerRpc(T implementation, Class rpcInterfaceType) { - super.registerRpc(implementation, rpcInterfaceType); - callbackHelper.registerRpc(rpcInterfaceType); - } - - /** - * Register a {@link JavaScriptFunction} that can be called from the - * JavaScript using the provided name. A JavaScript function with the - * provided name will be added to the connector wrapper object (initially - * available as this). Calling that JavaScript function will - * cause the call method in the registered {@link JavaScriptFunction} to be - * invoked with the same arguments. - * - * @param functionName - * the name that should be used for client-side function - * @param function - * the {@link JavaScriptFunction} object that will be invoked - * when the JavaScript function is called - */ - protected void addFunction(String functionName, JavaScriptFunction function) { - callbackHelper.registerCallback(functionName, function); - } - - /** - * Invoke a named function that the connector JavaScript has added to the - * JavaScript connector wrapper object. The arguments should only contain - * data types that can be represented in JavaScript including primitives, - * their boxed types, arrays, String, List, Set, Map, Connector and - * JavaBeans. - * - * @param name - * the name of the function - * @param arguments - * function arguments - */ - protected void callFunction(String name, Object... arguments) { - callbackHelper.invokeCallback(name, arguments); - } - - @Override - public JavaScriptComponentState getState() { - return (JavaScriptComponentState) super.getState(); - } -} diff --git a/src/com/vaadin/ui/AbstractLayout.java b/src/com/vaadin/ui/AbstractLayout.java deleted file mode 100644 index 7b3a537d06..0000000000 --- a/src/com/vaadin/ui/AbstractLayout.java +++ /dev/null @@ -1,77 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import com.vaadin.shared.ui.AbstractLayoutState; -import com.vaadin.ui.Layout.MarginHandler; - -/** - * An abstract class that defines default implementation for the {@link Layout} - * interface. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.0 - */ -@SuppressWarnings("serial") -public abstract class AbstractLayout extends AbstractComponentContainer - implements Layout, MarginHandler { - - protected MarginInfo margins = new MarginInfo(false); - - @Override - public AbstractLayoutState getState() { - return (AbstractLayoutState) super.getState(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Layout#setMargin(boolean) - */ - @Override - public void setMargin(boolean enabled) { - margins.setMargins(enabled); - getState().setMarginsBitmask(margins.getBitMask()); - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Layout.MarginHandler#getMargin() - */ - @Override - public MarginInfo getMargin() { - return margins; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Layout.MarginHandler#setMargin(MarginInfo) - */ - @Override - public void setMargin(MarginInfo marginInfo) { - margins.setMargins(marginInfo); - getState().setMarginsBitmask(margins.getBitMask()); - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Layout#setMargin(boolean, boolean, boolean, boolean) - */ - @Override - public void setMargin(boolean topEnabled, boolean rightEnabled, - boolean bottomEnabled, boolean leftEnabled) { - margins.setMargins(topEnabled, rightEnabled, bottomEnabled, leftEnabled); - getState().setMarginsBitmask(margins.getBitMask()); - requestRepaint(); - } - -} diff --git a/src/com/vaadin/ui/AbstractMedia.java b/src/com/vaadin/ui/AbstractMedia.java deleted file mode 100644 index 71b2e38ef3..0000000000 --- a/src/com/vaadin/ui/AbstractMedia.java +++ /dev/null @@ -1,196 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.util.ArrayList; -import java.util.List; - -import com.vaadin.shared.communication.URLReference; -import com.vaadin.shared.ui.AbstractMediaState; -import com.vaadin.shared.ui.MediaControl; -import com.vaadin.terminal.Resource; -import com.vaadin.terminal.gwt.server.ResourceReference; - -/** - * Abstract base class for the HTML5 media components. - * - * @author Vaadin Ltd - */ -public abstract class AbstractMedia extends AbstractComponent { - - @Override - public AbstractMediaState getState() { - return (AbstractMediaState) super.getState(); - } - - /** - * Sets a single media file as the source of the media component. - * - * @param source - */ - public void setSource(Resource source) { - clearSources(); - - addSource(source); - } - - private void clearSources() { - getState().getSources().clear(); - getState().getSourceTypes().clear(); - } - - /** - * Adds an alternative media file to the sources list. Which of the sources - * is used is selected by the browser depending on which file formats it - * supports. See wikipedia for a - * table of formats supported by different browsers. - * - * @param source - */ - public void addSource(Resource source) { - if (source != null) { - getState().getSources().add(new ResourceReference(source)); - getState().getSourceTypes().add(source.getMIMEType()); - requestRepaint(); - } - } - - /** - * Set multiple sources at once. Which of the sources is used is selected by - * the browser depending on which file formats it supports. See wikipedia for a - * table of formats supported by different browsers. - * - * @param sources - */ - public void setSources(Resource... sources) { - clearSources(); - for (Resource source : sources) { - addSource(source); - } - } - - /** - * @return The sources pointed to in this media. - */ - public List getSources() { - ArrayList sources = new ArrayList(); - for (URLReference ref : getState().getSources()) { - sources.add(((ResourceReference) ref).getResource()); - } - return sources; - } - - /** - * Sets whether or not the browser should show native media controls. - * - * @param showControls - */ - public void setShowControls(boolean showControls) { - getState().setShowControls(showControls); - requestRepaint(); - } - - /** - * @return true if the browser is to show native media controls. - */ - public boolean isShowControls() { - return getState().isShowControls(); - } - - /** - * Sets the alternative text to be displayed if the browser does not support - * HTML5. This text is rendered as HTML if - * {@link #setHtmlContentAllowed(boolean)} is set to true. With HTML - * rendering, this method can also be used to implement fallback to a - * flash-based player, see the Mozilla Developer Network for details. - * - * @param altText - */ - public void setAltText(String altText) { - getState().setAltText(altText); - requestRepaint(); - } - - /** - * @return The text/html that is displayed when a browser doesn't support - * HTML5. - */ - public String getAltText() { - return getState().getAltText(); - } - - /** - * Set whether the alternative text ({@link #setAltText(String)}) is - * rendered as HTML or not. - * - * @param htmlContentAllowed - */ - public void setHtmlContentAllowed(boolean htmlContentAllowed) { - getState().setHtmlContentAllowed(htmlContentAllowed); - requestRepaint(); - } - - /** - * @return true if the alternative text ({@link #setAltText(String)}) is to - * be rendered as HTML. - */ - public boolean isHtmlContentAllowed() { - return getState().isHtmlContentAllowed(); - } - - /** - * Sets whether the media is to automatically start playback when enough - * data has been loaded. - * - * @param autoplay - */ - public void setAutoplay(boolean autoplay) { - getState().setAutoplay(autoplay); - requestRepaint(); - } - - /** - * @return true if the media is set to automatically start playback. - */ - public boolean isAutoplay() { - return getState().isAutoplay(); - } - - /** - * Set whether to mute the audio or not. - * - * @param muted - */ - public void setMuted(boolean muted) { - getState().setMuted(muted); - requestRepaint(); - } - - /** - * @return true if the audio is muted. - */ - public boolean isMuted() { - return getState().isMuted(); - } - - /** - * Pauses the media. - */ - public void pause() { - getRpcProxy(MediaControl.class).pause(); - } - - /** - * Starts playback of the media. - */ - public void play() { - getRpcProxy(MediaControl.class).play(); - } - -} diff --git a/src/com/vaadin/ui/AbstractOrderedLayout.java b/src/com/vaadin/ui/AbstractOrderedLayout.java deleted file mode 100644 index 0581d0a279..0000000000 --- a/src/com/vaadin/ui/AbstractOrderedLayout.java +++ /dev/null @@ -1,383 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.util.Iterator; -import java.util.LinkedList; - -import com.vaadin.event.LayoutEvents.LayoutClickEvent; -import com.vaadin.event.LayoutEvents.LayoutClickListener; -import com.vaadin.event.LayoutEvents.LayoutClickNotifier; -import com.vaadin.shared.Connector; -import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutServerRpc; -import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState; -import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState.ChildComponentData; -import com.vaadin.terminal.Sizeable; -import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler; - -@SuppressWarnings("serial") -public abstract class AbstractOrderedLayout extends AbstractLayout implements - Layout.AlignmentHandler, Layout.SpacingHandler, LayoutClickNotifier { - - private AbstractOrderedLayoutServerRpc rpc = new AbstractOrderedLayoutServerRpc() { - - @Override - public void layoutClick(MouseEventDetails mouseDetails, - Connector clickedConnector) { - fireEvent(LayoutClickEvent.createEvent(AbstractOrderedLayout.this, - mouseDetails, clickedConnector)); - } - }; - - public static final Alignment ALIGNMENT_DEFAULT = Alignment.TOP_LEFT; - - /** - * Custom layout slots containing the components. - */ - protected LinkedList components = new LinkedList(); - - /* Child component alignments */ - - /** - * Mapping from components to alignments (horizontal + vertical). - */ - public AbstractOrderedLayout() { - registerRpc(rpc); - } - - @Override - public AbstractOrderedLayoutState getState() { - return (AbstractOrderedLayoutState) super.getState(); - } - - /** - * Add a component into this container. The component is added to the right - * or under the previous component. - * - * @param c - * the component to be added. - */ - @Override - public void addComponent(Component c) { - // Add to components before calling super.addComponent - // so that it is available to AttachListeners - components.add(c); - try { - super.addComponent(c); - } catch (IllegalArgumentException e) { - components.remove(c); - throw e; - } - componentAdded(c); - } - - /** - * Adds a component into this container. The component is added to the left - * or on top of the other components. - * - * @param c - * the component to be added. - */ - public void addComponentAsFirst(Component c) { - // If c is already in this, we must remove it before proceeding - // see ticket #7668 - if (c.getParent() == this) { - removeComponent(c); - } - components.addFirst(c); - try { - super.addComponent(c); - } catch (IllegalArgumentException e) { - components.remove(c); - throw e; - } - componentAdded(c); - - } - - /** - * Adds a component into indexed position in this container. - * - * @param c - * the component to be added. - * @param index - * the index of the component position. The components currently - * in and after the position are shifted forwards. - */ - public void addComponent(Component c, int index) { - // If c is already in this, we must remove it before proceeding - // see ticket #7668 - if (c.getParent() == this) { - // When c is removed, all components after it are shifted down - if (index > getComponentIndex(c)) { - index--; - } - removeComponent(c); - } - components.add(index, c); - try { - super.addComponent(c); - } catch (IllegalArgumentException e) { - components.remove(c); - throw e; - } - - componentAdded(c); - } - - private void componentRemoved(Component c) { - getState().getChildData().remove(c); - requestRepaint(); - } - - private void componentAdded(Component c) { - getState().getChildData().put(c, new ChildComponentData()); - requestRepaint(); - - } - - /** - * Removes the component from this container. - * - * @param c - * the component to be removed. - */ - @Override - public void removeComponent(Component c) { - components.remove(c); - super.removeComponent(c); - componentRemoved(c); - } - - /** - * Gets the component container iterator for going trough all the components - * in the container. - * - * @return the Iterator of the components inside the container. - */ - @Override - public Iterator getComponentIterator() { - return components.iterator(); - } - - /** - * Gets the number of contained components. Consistent with the iterator - * returned by {@link #getComponentIterator()}. - * - * @return the number of contained components - */ - @Override - public int getComponentCount() { - return components.size(); - } - - /* Documented in superclass */ - @Override - public void replaceComponent(Component oldComponent, Component newComponent) { - - // Gets the locations - int oldLocation = -1; - int newLocation = -1; - int location = 0; - for (final Iterator i = components.iterator(); i.hasNext();) { - final Component component = i.next(); - - if (component == oldComponent) { - oldLocation = location; - } - if (component == newComponent) { - newLocation = location; - } - - location++; - } - - if (oldLocation == -1) { - addComponent(newComponent); - } else if (newLocation == -1) { - removeComponent(oldComponent); - addComponent(newComponent, oldLocation); - } else { - // Both old and new are in the layout - if (oldLocation > newLocation) { - components.remove(oldComponent); - components.add(newLocation, oldComponent); - components.remove(newComponent); - components.add(oldLocation, newComponent); - } else { - components.remove(newComponent); - components.add(oldLocation, newComponent); - components.remove(oldComponent); - components.add(newLocation, oldComponent); - } - - requestRepaint(); - } - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Layout.AlignmentHandler#setComponentAlignment(com - * .vaadin.ui.Component, int, int) - */ - @Override - public void setComponentAlignment(Component childComponent, - int horizontalAlignment, int verticalAlignment) { - Alignment a = new Alignment(horizontalAlignment + verticalAlignment); - setComponentAlignment(childComponent, a); - } - - @Override - public void setComponentAlignment(Component childComponent, - Alignment alignment) { - ChildComponentData childData = getState().getChildData().get( - childComponent); - if (childData != null) { - // Alignments are bit masks - childData.setAlignmentBitmask(alignment.getBitMask()); - requestRepaint(); - } else { - throw new IllegalArgumentException( - "Component must be added to layout before using setComponentAlignment()"); - } - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Layout.AlignmentHandler#getComponentAlignment(com - * .vaadin.ui.Component) - */ - @Override - public Alignment getComponentAlignment(Component childComponent) { - ChildComponentData childData = getState().getChildData().get( - childComponent); - if (childData == null) { - throw new IllegalArgumentException( - "The given component is not a child of this layout"); - } - - return new Alignment(childData.getAlignmentBitmask()); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Layout.SpacingHandler#setSpacing(boolean) - */ - @Override - public void setSpacing(boolean spacing) { - getState().setSpacing(spacing); - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Layout.SpacingHandler#isSpacing() - */ - @Override - public boolean isSpacing() { - return getState().isSpacing(); - } - - /** - *

- * This method is used to control how excess space in layout is distributed - * among components. Excess space may exist if layout is sized and contained - * non relatively sized components don't consume all available space. - * - *

- * Example how to distribute 1:3 (33%) for component1 and 2:3 (67%) for - * component2 : - * - * - * layout.setExpandRatio(component1, 1);
- * layout.setExpandRatio(component2, 2); - *
- * - *

- * If no ratios have been set, the excess space is distributed evenly among - * all components. - * - *

- * Note, that width or height (depending on orientation) needs to be defined - * for this method to have any effect. - * - * @see Sizeable - * - * @param component - * the component in this layout which expand ratio is to be set - * @param ratio - */ - public void setExpandRatio(Component component, float ratio) { - ChildComponentData childData = getState().getChildData().get(component); - if (childData == null) { - throw new IllegalArgumentException( - "The given component is not a child of this layout"); - } - - childData.setExpandRatio(ratio); - requestRepaint(); - }; - - /** - * Returns the expand ratio of given component. - * - * @param component - * which expand ratios is requested - * @return expand ratio of given component, 0.0f by default. - */ - public float getExpandRatio(Component component) { - ChildComponentData childData = getState().getChildData().get(component); - if (childData == null) { - throw new IllegalArgumentException( - "The given component is not a child of this layout"); - } - - return childData.getExpandRatio(); - } - - @Override - public void addListener(LayoutClickListener listener) { - addListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER, - LayoutClickEvent.class, listener, - LayoutClickListener.clickMethod); - } - - @Override - public void removeListener(LayoutClickListener listener) { - removeListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER, - LayoutClickEvent.class, listener); - } - - /** - * Returns the index of the given component. - * - * @param component - * The component to look up. - * @return The index of the component or -1 if the component is not a child. - */ - public int getComponentIndex(Component component) { - return components.indexOf(component); - } - - /** - * Returns the component at the given position. - * - * @param index - * The position of the component. - * @return The component at the given index. - * @throws IndexOutOfBoundsException - * If the index is out of range. - */ - public Component getComponent(int index) throws IndexOutOfBoundsException { - return components.get(index); - } - -} diff --git a/src/com/vaadin/ui/AbstractSelect.java b/src/com/vaadin/ui/AbstractSelect.java deleted file mode 100644 index 0a97ceb649..0000000000 --- a/src/com/vaadin/ui/AbstractSelect.java +++ /dev/null @@ -1,2029 +0,0 @@ -/* - * @VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; - -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.Property; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.event.DataBoundTransferable; -import com.vaadin.event.Transferable; -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.DropTarget; -import com.vaadin.event.dd.TargetDetailsImpl; -import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion; -import com.vaadin.event.dd.acceptcriteria.ContainsDataFlavor; -import com.vaadin.event.dd.acceptcriteria.TargetDetailIs; -import com.vaadin.shared.ui.dd.VerticalDropLocation; -import com.vaadin.terminal.KeyMapper; -import com.vaadin.terminal.PaintException; -import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.Resource; -import com.vaadin.terminal.Vaadin6Component; -import com.vaadin.ui.AbstractSelect.ItemCaptionMode; - -/** - *

- * A class representing a selection of items the user has selected in a UI. The - * set of choices is presented as a set of {@link com.vaadin.data.Item}s in a - * {@link com.vaadin.data.Container}. - *

- * - *

- * A Select component may be in single- or multiselect mode. - * Multiselect mode means that more than one item can be selected - * simultaneously. - *

- * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.0 - */ -@SuppressWarnings("serial") -// TODO currently cannot specify type more precisely in case of multi-select -public abstract class AbstractSelect extends AbstractField implements - Container, Container.Viewer, Container.PropertySetChangeListener, - Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier, - Container.ItemSetChangeListener, Vaadin6Component { - - public enum ItemCaptionMode { - /** - * Item caption mode: Item's ID's String representation is - * used as caption. - */ - ID, - /** - * Item caption mode: Item's String representation is used - * as caption. - */ - ITEM, - /** - * Item caption mode: Index of the item is used as caption. The index - * mode can only be used with the containers implementing the - * {@link com.vaadin.data.Container.Indexed} interface. - */ - INDEX, - /** - * Item caption mode: If an Item has a caption it's used, if not, Item's - * ID's String representation is used as caption. This - * is the default. - */ - EXPLICIT_DEFAULTS_ID, - /** - * Item caption mode: Captions must be explicitly specified. - */ - EXPLICIT, - /** - * Item caption mode: Only icons are shown, captions are hidden. - */ - ICON_ONLY, - /** - * Item caption mode: Item captions are read from property specified - * with setItemCaptionPropertyId. - */ - PROPERTY; - } - - /** - * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_ID = ItemCaptionMode.ID; - - /** - * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_ITEM = ItemCaptionMode.ITEM; - - /** - * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_INDEX = ItemCaptionMode.INDEX; - - /** - * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID = ItemCaptionMode.EXPLICIT_DEFAULTS_ID; - - /** - * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_EXPLICIT = ItemCaptionMode.EXPLICIT; - - /** - * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_ICON_ONLY = ItemCaptionMode.ICON_ONLY; - - /** - * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead - */ - @Deprecated - public static final ItemCaptionMode ITEM_CAPTION_MODE_PROPERTY = ItemCaptionMode.PROPERTY; - - /** - * Interface for option filtering, used to filter options based on user - * entered value. The value is matched to the item caption. - * FILTERINGMODE_OFF (0) turns the filtering off. - * FILTERINGMODE_STARTSWITH (1) matches from the start of the - * caption. FILTERINGMODE_CONTAINS (1) matches anywhere in the - * caption. - */ - public interface Filtering extends Serializable { - public static final int FILTERINGMODE_OFF = 0; - public static final int FILTERINGMODE_STARTSWITH = 1; - public static final int FILTERINGMODE_CONTAINS = 2; - - /** - * Sets the option filtering mode. - * - * @param filteringMode - * the filtering mode to use - */ - public void setFilteringMode(int filteringMode); - - /** - * Gets the current filtering mode. - * - * @return the filtering mode in use - */ - public int getFilteringMode(); - - } - - /** - * Multi select modes that controls how multi select behaves. - */ - public enum MultiSelectMode { - /** - * The default behavior of the multi select mode - */ - DEFAULT, - - /** - * The previous more simple behavior of the multselect - */ - SIMPLE - } - - /** - * Is the select in multiselect mode? - */ - private boolean multiSelect = false; - - /** - * Select options. - */ - protected Container items; - - /** - * Is the user allowed to add new options? - */ - private boolean allowNewOptions; - - /** - * Keymapper used to map key values. - */ - protected KeyMapper itemIdMapper = new KeyMapper(); - - /** - * Item icons. - */ - private final HashMap itemIcons = new HashMap(); - - /** - * Item captions. - */ - private final HashMap itemCaptions = new HashMap(); - - /** - * Item caption mode. - */ - private ItemCaptionMode itemCaptionMode = ItemCaptionMode.EXPLICIT_DEFAULTS_ID; - - /** - * Item caption source property id. - */ - private Object itemCaptionPropertyId = null; - - /** - * Item icon source property id. - */ - private Object itemIconPropertyId = null; - - /** - * List of property set change event listeners. - */ - private Set propertySetEventListeners = null; - - /** - * List of item set change event listeners. - */ - private Set itemSetEventListeners = null; - - /** - * Item id that represents null selection of this select. - * - *

- * Data interface does not support nulls as item ids. Selecting the item - * identified by this id is the same as selecting no items at all. This - * setting only affects the single select mode. - *

- */ - private Object nullSelectionItemId = null; - - // Null (empty) selection is enabled by default - private boolean nullSelectionAllowed = true; - private NewItemHandler newItemHandler; - - // Caption (Item / Property) change listeners - CaptionChangeListener captionChangeListener; - - /* Constructors */ - - /** - * Creates an empty Select. The caption is not used. - */ - public AbstractSelect() { - setContainerDataSource(new IndexedContainer()); - } - - /** - * Creates an empty Select with caption. - */ - public AbstractSelect(String caption) { - setContainerDataSource(new IndexedContainer()); - setCaption(caption); - } - - /** - * Creates a new select that is connected to a data-source. - * - * @param caption - * the Caption of the component. - * @param dataSource - * the Container datasource to be selected from by this select. - */ - public AbstractSelect(String caption, Container dataSource) { - setCaption(caption); - setContainerDataSource(dataSource); - } - - /** - * Creates a new select that is filled from a collection of option values. - * - * @param caption - * the Caption of this field. - * @param options - * the Collection containing the options. - */ - public AbstractSelect(String caption, Collection options) { - - // Creates the options container and add given options to it - final Container c = new IndexedContainer(); - if (options != null) { - for (final Iterator i = options.iterator(); i.hasNext();) { - c.addItem(i.next()); - } - } - - setCaption(caption); - setContainerDataSource(c); - } - - /* Component methods */ - - /** - * Paints the content of this component. - * - * @param target - * the Paint Event. - * @throws PaintException - * if the paint operation failed. - */ - @Override - public void paintContent(PaintTarget target) throws PaintException { - - // Paints select attributes - if (isMultiSelect()) { - target.addAttribute("selectmode", "multi"); - } - if (isNewItemsAllowed()) { - target.addAttribute("allownewitem", true); - } - if (isNullSelectionAllowed()) { - target.addAttribute("nullselect", true); - if (getNullSelectionItemId() != null) { - target.addAttribute("nullselectitem", true); - } - } - - // Constructs selected keys array - String[] selectedKeys; - if (isMultiSelect()) { - selectedKeys = new String[((Set) getValue()).size()]; - } else { - selectedKeys = new String[(getValue() == null - && getNullSelectionItemId() == null ? 0 : 1)]; - } - - // == - // first remove all previous item/property listeners - getCaptionChangeListener().clear(); - // Paints the options and create array of selected id keys - - target.startTag("options"); - int keyIndex = 0; - // Support for external null selection item id - final Collection ids = getItemIds(); - if (isNullSelectionAllowed() && getNullSelectionItemId() != null - && !ids.contains(getNullSelectionItemId())) { - final Object id = getNullSelectionItemId(); - // Paints option - target.startTag("so"); - paintItem(target, id); - if (isSelected(id)) { - selectedKeys[keyIndex++] = itemIdMapper.key(id); - } - target.endTag("so"); - } - - final Iterator i = getItemIds().iterator(); - // Paints the available selection options from data source - while (i.hasNext()) { - // Gets the option attribute values - final Object id = i.next(); - if (!isNullSelectionAllowed() && id != null - && id.equals(getNullSelectionItemId())) { - // Remove item if it's the null selection item but null - // selection is not allowed - continue; - } - final String key = itemIdMapper.key(id); - // add listener for each item, to cause repaint if an item changes - getCaptionChangeListener().addNotifierForItem(id); - target.startTag("so"); - paintItem(target, id); - if (isSelected(id) && keyIndex < selectedKeys.length) { - selectedKeys[keyIndex++] = key; - } - target.endTag("so"); - } - target.endTag("options"); - // == - - // Paint variables - target.addVariable(this, "selected", selectedKeys); - if (isNewItemsAllowed()) { - target.addVariable(this, "newitem", ""); - } - - } - - protected void paintItem(PaintTarget target, Object itemId) - throws PaintException { - final String key = itemIdMapper.key(itemId); - final String caption = getItemCaption(itemId); - final Resource icon = getItemIcon(itemId); - if (icon != null) { - target.addAttribute("icon", icon); - } - target.addAttribute("caption", caption); - if (itemId != null && itemId.equals(getNullSelectionItemId())) { - target.addAttribute("nullselection", true); - } - target.addAttribute("key", key); - if (isSelected(itemId)) { - target.addAttribute("selected", true); - } - } - - /** - * Invoked when the value of a variable has changed. - * - * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, - * java.util.Map) - */ - @Override - public void changeVariables(Object source, Map variables) { - - // New option entered (and it is allowed) - if (isNewItemsAllowed()) { - final String newitem = (String) variables.get("newitem"); - if (newitem != null && newitem.length() > 0) { - getNewItemHandler().addNewItem(newitem); - } - } - - // Selection change - if (variables.containsKey("selected")) { - final String[] clientSideSelectedKeys = (String[]) variables - .get("selected"); - - // Multiselect mode - if (isMultiSelect()) { - - // TODO Optimize by adding repaintNotNeeded when applicable - - // Converts the key-array to id-set - final LinkedList acceptedSelections = new LinkedList(); - for (int i = 0; i < clientSideSelectedKeys.length; i++) { - final Object id = itemIdMapper - .get(clientSideSelectedKeys[i]); - if (!isNullSelectionAllowed() - && (id == null || id == getNullSelectionItemId())) { - // skip empty selection if nullselection is not allowed - requestRepaint(); - } else if (id != null && containsId(id)) { - acceptedSelections.add(id); - } - } - - if (!isNullSelectionAllowed() && acceptedSelections.size() < 1) { - // empty selection not allowed, keep old value - requestRepaint(); - return; - } - - // Limits the deselection to the set of visible items - // (non-visible items can not be deselected) - Collection visibleNotSelected = getVisibleItemIds(); - if (visibleNotSelected != null) { - visibleNotSelected = new HashSet(visibleNotSelected); - // Don't remove those that will be added to preserve order - visibleNotSelected.removeAll(acceptedSelections); - - @SuppressWarnings("unchecked") - Set newsel = (Set) getValue(); - if (newsel == null) { - newsel = new LinkedHashSet(); - } else { - newsel = new LinkedHashSet(newsel); - } - newsel.removeAll(visibleNotSelected); - newsel.addAll(acceptedSelections); - setValue(newsel, true); - } - } else { - // Single select mode - if (!isNullSelectionAllowed() - && (clientSideSelectedKeys.length == 0 - || clientSideSelectedKeys[0] == null || clientSideSelectedKeys[0] == getNullSelectionItemId())) { - requestRepaint(); - return; - } - if (clientSideSelectedKeys.length == 0) { - // Allows deselection only if the deselected item is - // visible - final Object current = getValue(); - final Collection visible = getVisibleItemIds(); - if (visible != null && visible.contains(current)) { - setValue(null, true); - } - } else { - final Object id = itemIdMapper - .get(clientSideSelectedKeys[0]); - if (!isNullSelectionAllowed() && id == null) { - requestRepaint(); - } else if (id != null - && id.equals(getNullSelectionItemId())) { - setValue(null, true); - } else { - setValue(id, true); - } - } - } - } - } - - /** - * TODO refine doc Setter for new item handler that is called when user adds - * new item in newItemAllowed mode. - * - * @param newItemHandler - */ - public void setNewItemHandler(NewItemHandler newItemHandler) { - this.newItemHandler = newItemHandler; - } - - /** - * TODO refine doc - * - * @return - */ - public NewItemHandler getNewItemHandler() { - if (newItemHandler == null) { - newItemHandler = new DefaultNewItemHandler(); - } - return newItemHandler; - } - - public interface NewItemHandler extends Serializable { - void addNewItem(String newItemCaption); - } - - /** - * TODO refine doc - * - * This is a default class that handles adding new items that are typed by - * user to selects container. - * - * By extending this class one may implement some logic on new item addition - * like database inserts. - * - */ - public class DefaultNewItemHandler implements NewItemHandler { - @Override - public void addNewItem(String newItemCaption) { - // Checks for readonly - if (isReadOnly()) { - throw new Property.ReadOnlyException(); - } - - // Adds new option - if (addItem(newItemCaption) != null) { - - // Sets the caption property, if used - if (getItemCaptionPropertyId() != null) { - getContainerProperty(newItemCaption, - getItemCaptionPropertyId()) - .setValue(newItemCaption); - } - if (isMultiSelect()) { - Set values = new HashSet((Collection) getValue()); - values.add(newItemCaption); - setValue(values); - } else { - setValue(newItemCaption); - } - } - } - } - - /** - * Gets the visible item ids. In Select, this returns list of all item ids, - * but can be overriden in subclasses if they paint only part of the items - * to the terminal or null if no items is visible. - */ - public Collection getVisibleItemIds() { - return getItemIds(); - } - - /* Property methods */ - - /** - * Returns the type of the property. getValue and - * setValue methods must be compatible with this type: one can - * safely cast getValue to given type and pass any variable - * assignable to this type as a parameter to setValue. - * - * @return the Type of the property. - */ - @Override - public Class getType() { - if (isMultiSelect()) { - return Set.class; - } else { - return Object.class; - } - } - - /** - * Gets the selected item id or in multiselect mode a set of selected ids. - * - * @see com.vaadin.ui.AbstractField#getValue() - */ - @Override - public Object getValue() { - final Object retValue = super.getValue(); - - if (isMultiSelect()) { - - // If the return value is not a set - if (retValue == null) { - return new HashSet(); - } - if (retValue instanceof Set) { - return Collections.unmodifiableSet((Set) retValue); - } else if (retValue instanceof Collection) { - return new HashSet((Collection) retValue); - } else { - final Set s = new HashSet(); - if (items.containsId(retValue)) { - s.add(retValue); - } - return s; - } - - } else { - return retValue; - } - } - - /** - * Sets the visible value of the property. - * - *

- * The value of the select is the selected item id. If the select is in - * multiselect-mode, the value is a set of selected item keys. In - * multiselect mode all collections of id:s can be assigned. - *

- * - * @param newValue - * the New selected item or collection of selected items. - * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object) - */ - @Override - public void setValue(Object newValue) throws Property.ReadOnlyException { - if (newValue == getNullSelectionItemId()) { - newValue = null; - } - - setValue(newValue, false); - } - - /** - * Sets the visible value of the property. - * - *

- * The value of the select is the selected item id. If the select is in - * multiselect-mode, the value is a set of selected item keys. In - * multiselect mode all collections of id:s can be assigned. - *

- * - * @param newValue - * the New selected item or collection of selected items. - * @param repaintIsNotNeeded - * True if caller is sure that repaint is not needed. - * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object, - * java.lang.Boolean) - */ - @Override - protected void setValue(Object newValue, boolean repaintIsNotNeeded) - throws Property.ReadOnlyException { - - if (isMultiSelect()) { - if (newValue == null) { - super.setValue(new LinkedHashSet(), repaintIsNotNeeded); - } else if (Collection.class.isAssignableFrom(newValue.getClass())) { - super.setValue(new LinkedHashSet( - (Collection) newValue), repaintIsNotNeeded); - } - } else if (newValue == null || items.containsId(newValue)) { - super.setValue(newValue, repaintIsNotNeeded); - } - } - - /* Container methods */ - - /** - * Gets the item from the container with given id. If the container does not - * contain the requested item, null is returned. - * - * @param itemId - * the item id. - * @return the item from the container. - */ - @Override - public Item getItem(Object itemId) { - return items.getItem(itemId); - } - - /** - * Gets the item Id collection from the container. - * - * @return the Collection of item ids. - */ - @Override - public Collection getItemIds() { - return items.getItemIds(); - } - - /** - * Gets the property Id collection from the container. - * - * @return the Collection of property ids. - */ - @Override - public Collection getContainerPropertyIds() { - return items.getContainerPropertyIds(); - } - - /** - * Gets the property type. - * - * @param propertyId - * the Id identifying the property. - * @see com.vaadin.data.Container#getType(java.lang.Object) - */ - @Override - public Class getType(Object propertyId) { - return items.getType(propertyId); - } - - /* - * Gets the number of items in the container. - * - * @return the Number of items in the container. - * - * @see com.vaadin.data.Container#size() - */ - @Override - public int size() { - return items.size(); - } - - /** - * Tests, if the collection contains an item with given id. - * - * @param itemId - * the Id the of item to be tested. - */ - @Override - public boolean containsId(Object itemId) { - if (itemId != null) { - return items.containsId(itemId); - } else { - return false; - } - } - - /** - * Gets the Property identified by the given itemId and propertyId from the - * Container - * - * @see com.vaadin.data.Container#getContainerProperty(Object, Object) - */ - @Override - public Property getContainerProperty(Object itemId, Object propertyId) { - return items.getContainerProperty(itemId, propertyId); - } - - /** - * Adds the new property to all items. Adds a property with given id, type - * and default value to all items in the container. - * - * This functionality is optional. If the function is unsupported, it always - * returns false. - * - * @return True if the operation succeeded. - * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object, - * java.lang.Class, java.lang.Object) - */ - @Override - public boolean addContainerProperty(Object propertyId, Class type, - Object defaultValue) throws UnsupportedOperationException { - - final boolean retval = items.addContainerProperty(propertyId, type, - defaultValue); - if (retval && !(items instanceof Container.PropertySetChangeNotifier)) { - firePropertySetChange(); - } - return retval; - } - - /** - * Removes all items from the container. - * - * This functionality is optional. If the function is unsupported, it always - * returns false. - * - * @return True if the operation succeeded. - * @see com.vaadin.data.Container#removeAllItems() - */ - @Override - public boolean removeAllItems() throws UnsupportedOperationException { - - final boolean retval = items.removeAllItems(); - itemIdMapper.removeAll(); - if (retval) { - setValue(null); - if (!(items instanceof Container.ItemSetChangeNotifier)) { - fireItemSetChange(); - } - } - return retval; - } - - /** - * Creates a new item into container with container managed id. The id of - * the created new item is returned. The item can be fetched with getItem() - * method. if the creation fails, null is returned. - * - * @return the Id of the created item or null in case of failure. - * @see com.vaadin.data.Container#addItem() - */ - @Override - public Object addItem() throws UnsupportedOperationException { - - final Object retval = items.addItem(); - if (retval != null - && !(items instanceof Container.ItemSetChangeNotifier)) { - fireItemSetChange(); - } - return retval; - } - - /** - * Create a new item into container. The created new item is returned and - * ready for setting property values. if the creation fails, null is - * returned. In case the container already contains the item, null is - * returned. - * - * This functionality is optional. If the function is unsupported, it always - * returns null. - * - * @param itemId - * the Identification of the item to be created. - * @return the Created item with the given id, or null in case of failure. - * @see com.vaadin.data.Container#addItem(java.lang.Object) - */ - @Override - public Item addItem(Object itemId) throws UnsupportedOperationException { - - final Item retval = items.addItem(itemId); - if (retval != null - && !(items instanceof Container.ItemSetChangeNotifier)) { - fireItemSetChange(); - } - return retval; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#removeItem(java.lang.Object) - */ - @Override - public boolean removeItem(Object itemId) - throws UnsupportedOperationException { - - unselect(itemId); - final boolean retval = items.removeItem(itemId); - itemIdMapper.remove(itemId); - if (retval && !(items instanceof Container.ItemSetChangeNotifier)) { - fireItemSetChange(); - } - return retval; - } - - /** - * Removes the property from all items. Removes a property with given id - * from all the items in the container. - * - * This functionality is optional. If the function is unsupported, it always - * returns false. - * - * @return True if the operation succeeded. - * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object) - */ - @Override - public boolean removeContainerProperty(Object propertyId) - throws UnsupportedOperationException { - - final boolean retval = items.removeContainerProperty(propertyId); - if (retval && !(items instanceof Container.PropertySetChangeNotifier)) { - firePropertySetChange(); - } - return retval; - } - - /* Container.Viewer methods */ - - /** - * Sets the Container that serves as the data source of the viewer. - * - * As a side-effect the fields value (selection) is set to null due old - * selection not necessary exists in new Container. - * - * @see com.vaadin.data.Container.Viewer#setContainerDataSource(Container) - * - * @param newDataSource - * the new data source. - */ - @Override - public void setContainerDataSource(Container newDataSource) { - if (newDataSource == null) { - newDataSource = new IndexedContainer(); - } - - getCaptionChangeListener().clear(); - - if (items != newDataSource) { - - // Removes listeners from the old datasource - if (items != null) { - if (items instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) items) - .removeListener(this); - } - if (items instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) items) - .removeListener(this); - } - } - - // Assigns new data source - items = newDataSource; - - // Clears itemIdMapper also - itemIdMapper.removeAll(); - - // Adds listeners - if (items != null) { - if (items instanceof Container.ItemSetChangeNotifier) { - ((Container.ItemSetChangeNotifier) items).addListener(this); - } - if (items instanceof Container.PropertySetChangeNotifier) { - ((Container.PropertySetChangeNotifier) items) - .addListener(this); - } - } - - /* - * We expect changing the data source should also clean value. See - * #810, #4607, #5281 - */ - setValue(null); - - requestRepaint(); - - } - } - - /** - * Gets the viewing data-source container. - * - * @see com.vaadin.data.Container.Viewer#getContainerDataSource() - */ - @Override - public Container getContainerDataSource() { - return items; - } - - /* Select attributes */ - - /** - * Is the select in multiselect mode? In multiselect mode - * - * @return the Value of property multiSelect. - */ - public boolean isMultiSelect() { - return multiSelect; - } - - /** - * Sets the multiselect mode. Setting multiselect mode false may lose - * selection information: if selected items set contains one or more - * selected items, only one of the selected items is kept as selected. - * - * Subclasses of AbstractSelect can choose not to support changing the - * multiselect mode, and may throw {@link UnsupportedOperationException}. - * - * @param multiSelect - * the New value of property multiSelect. - */ - public void setMultiSelect(boolean multiSelect) { - if (multiSelect && getNullSelectionItemId() != null) { - throw new IllegalStateException( - "Multiselect and NullSelectionItemId can not be set at the same time."); - } - if (multiSelect != this.multiSelect) { - - // Selection before mode change - final Object oldValue = getValue(); - - this.multiSelect = multiSelect; - - // Convert the value type - if (multiSelect) { - final Set s = new HashSet(); - if (oldValue != null) { - s.add(oldValue); - } - setValue(s); - } else { - final Set s = (Set) oldValue; - if (s == null || s.isEmpty()) { - setValue(null); - } else { - // Set the single select to contain only the first - // selected value in the multiselect - setValue(s.iterator().next()); - } - } - - requestRepaint(); - } - } - - /** - * Does the select allow adding new options by the user. If true, the new - * options can be added to the Container. The text entered by the user is - * used as id. Note that data-source must allow adding new items. - * - * @return True if additions are allowed. - */ - public boolean isNewItemsAllowed() { - - return allowNewOptions; - } - - /** - * Enables or disables possibility to add new options by the user. - * - * @param allowNewOptions - * the New value of property allowNewOptions. - */ - public void setNewItemsAllowed(boolean allowNewOptions) { - - // Only handle change requests - if (this.allowNewOptions != allowNewOptions) { - - this.allowNewOptions = allowNewOptions; - - requestRepaint(); - } - } - - /** - * Override the caption of an item. Setting caption explicitly overrides id, - * item and index captions. - * - * @param itemId - * the id of the item to be recaptioned. - * @param caption - * the New caption. - */ - public void setItemCaption(Object itemId, String caption) { - if (itemId != null) { - itemCaptions.put(itemId, caption); - requestRepaint(); - } - } - - /** - * Gets the caption of an item. The caption is generated as specified by the - * item caption mode. See setItemCaptionMode() for more - * details. - * - * @param itemId - * the id of the item to be queried. - * @return the caption for specified item. - */ - public String getItemCaption(Object itemId) { - - // Null items can not be found - if (itemId == null) { - return null; - } - - String caption = null; - - switch (getItemCaptionMode()) { - - case ID: - caption = itemId.toString(); - break; - - case INDEX: - if (items instanceof Container.Indexed) { - caption = String.valueOf(((Container.Indexed) items) - .indexOfId(itemId)); - } else { - caption = "ERROR: Container is not indexed"; - } - break; - - case ITEM: - final Item i = getItem(itemId); - if (i != null) { - caption = i.toString(); - } - break; - - case EXPLICIT: - caption = itemCaptions.get(itemId); - break; - - case EXPLICIT_DEFAULTS_ID: - caption = itemCaptions.get(itemId); - if (caption == null) { - caption = itemId.toString(); - } - break; - - case PROPERTY: - final Property p = getContainerProperty(itemId, - getItemCaptionPropertyId()); - if (p != null) { - Object value = p.getValue(); - if (value != null) { - caption = value.toString(); - } - } - break; - } - - // All items must have some captions - return caption != null ? caption : ""; - } - - /** - * Sets tqhe icon for an item. - * - * @param itemId - * the id of the item to be assigned an icon. - * @param icon - * the icon to use or null. - */ - public void setItemIcon(Object itemId, Resource icon) { - if (itemId != null) { - if (icon == null) { - itemIcons.remove(itemId); - } else { - itemIcons.put(itemId, icon); - } - requestRepaint(); - } - } - - /** - * Gets the item icon. - * - * @param itemId - * the id of the item to be assigned an icon. - * @return the icon for the item or null, if not specified. - */ - public Resource getItemIcon(Object itemId) { - final Resource explicit = itemIcons.get(itemId); - if (explicit != null) { - return explicit; - } - - if (getItemIconPropertyId() == null) { - return null; - } - - final Property ip = getContainerProperty(itemId, - getItemIconPropertyId()); - if (ip == null) { - return null; - } - final Object icon = ip.getValue(); - if (icon instanceof Resource) { - return (Resource) icon; - } - - return null; - } - - /** - * Sets the item caption mode. - * - *

- * The mode can be one of the following ones: - *

    - *
  • ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID : Items - * Id-objects toString is used as item caption. If caption is - * explicitly specified, it overrides the id-caption. - *
  • ITEM_CAPTION_MODE_ID : Items Id-objects - * toString is used as item caption.
  • - *
  • ITEM_CAPTION_MODE_ITEM : Item-objects - * toString is used as item caption.
  • - *
  • ITEM_CAPTION_MODE_INDEX : The index of the item is used - * as item caption. The index mode can only be used with the containers - * implementing Container.Indexed interface.
  • - *
  • ITEM_CAPTION_MODE_EXPLICIT : The item captions must be - * explicitly specified.
  • - *
  • ITEM_CAPTION_MODE_PROPERTY : The item captions are read - * from property, that must be specified with - * setItemCaptionPropertyId.
  • - *
- * The ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID is the default - * mode. - *

- * - * @param mode - * the One of the modes listed above. - */ - public void setItemCaptionMode(ItemCaptionMode mode) { - if (mode != null) { - itemCaptionMode = mode; - requestRepaint(); - } - } - - /** - * Gets the item caption mode. - * - *

- * The mode can be one of the following ones: - *

    - *
  • ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID : Items - * Id-objects toString is used as item caption. If caption is - * explicitly specified, it overrides the id-caption. - *
  • ITEM_CAPTION_MODE_ID : Items Id-objects - * toString is used as item caption.
  • - *
  • ITEM_CAPTION_MODE_ITEM : Item-objects - * toString is used as item caption.
  • - *
  • ITEM_CAPTION_MODE_INDEX : The index of the item is used - * as item caption. The index mode can only be used with the containers - * implementing Container.Indexed interface.
  • - *
  • ITEM_CAPTION_MODE_EXPLICIT : The item captions must be - * explicitly specified.
  • - *
  • ITEM_CAPTION_MODE_PROPERTY : The item captions are read - * from property, that must be specified with - * setItemCaptionPropertyId.
  • - *
- * The ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID is the default - * mode. - *

- * - * @return the One of the modes listed above. - */ - public ItemCaptionMode getItemCaptionMode() { - return itemCaptionMode; - } - - /** - * Sets the item caption property. - * - *

- * Setting the id to a existing property implicitly sets the item caption - * mode to ITEM_CAPTION_MODE_PROPERTY. If the object is in - * ITEM_CAPTION_MODE_PROPERTY mode, setting caption property id - * null resets the item caption mode to - * ITEM_CAPTION_EXPLICIT_DEFAULTS_ID. - *

- *

- * Note that the type of the property used for caption must be String - *

- *

- * Setting the property id to null disables this feature. The id is null by - * default - *

- * . - * - * @param propertyId - * the id of the property. - * - */ - public void setItemCaptionPropertyId(Object propertyId) { - if (propertyId != null) { - itemCaptionPropertyId = propertyId; - setItemCaptionMode(ITEM_CAPTION_MODE_PROPERTY); - requestRepaint(); - } else { - itemCaptionPropertyId = null; - if (getItemCaptionMode() == ITEM_CAPTION_MODE_PROPERTY) { - setItemCaptionMode(ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID); - } - requestRepaint(); - } - } - - /** - * Gets the item caption property. - * - * @return the Id of the property used as item caption source. - */ - public Object getItemCaptionPropertyId() { - return itemCaptionPropertyId; - } - - /** - * Sets the item icon property. - * - *

- * If the property id is set to a valid value, each item is given an icon - * got from the given property of the items. The type of the property must - * be assignable to Resource. - *

- * - *

- * Note : The icons set with setItemIcon function override the - * icons from the property. - *

- * - *

- * Setting the property id to null disables this feature. The id is null by - * default - *

- * . - * - * @param propertyId - * the id of the property that specifies icons for items or null - * @throws IllegalArgumentException - * If the propertyId is not in the container or is not of a - * valid type - */ - public void setItemIconPropertyId(Object propertyId) - throws IllegalArgumentException { - if (propertyId == null) { - itemIconPropertyId = null; - } else if (!getContainerPropertyIds().contains(propertyId)) { - throw new IllegalArgumentException( - "Property id not found in the container"); - } else if (Resource.class.isAssignableFrom(getType(propertyId))) { - itemIconPropertyId = propertyId; - } else { - throw new IllegalArgumentException( - "Property type must be assignable to Resource"); - } - requestRepaint(); - } - - /** - * Gets the item icon property. - * - *

- * If the property id is set to a valid value, each item is given an icon - * got from the given property of the items. The type of the property must - * be assignable to Icon. - *

- * - *

- * Note : The icons set with setItemIcon function override the - * icons from the property. - *

- * - *

- * Setting the property id to null disables this feature. The id is null by - * default - *

- * . - * - * @return the Id of the property containing the item icons. - */ - public Object getItemIconPropertyId() { - return itemIconPropertyId; - } - - /** - * Tests if an item is selected. - * - *

- * In single select mode testing selection status of the item identified by - * {@link #getNullSelectionItemId()} returns true if the value of the - * property is null. - *

- * - * @param itemId - * the Id the of the item to be tested. - * @see #getNullSelectionItemId() - * @see #setNullSelectionItemId(Object) - * - */ - public boolean isSelected(Object itemId) { - if (itemId == null) { - return false; - } - if (isMultiSelect()) { - return ((Set) getValue()).contains(itemId); - } else { - final Object value = getValue(); - return itemId.equals(value == null ? getNullSelectionItemId() - : value); - } - } - - /** - * Selects an item. - * - *

- * In single select mode selecting item identified by - * {@link #getNullSelectionItemId()} sets the value of the property to null. - *

- * - * @param itemId - * the identifier of Item to be selected. - * @see #getNullSelectionItemId() - * @see #setNullSelectionItemId(Object) - * - */ - public void select(Object itemId) { - if (!isMultiSelect()) { - setValue(itemId); - } else if (!isSelected(itemId) && itemId != null - && items.containsId(itemId)) { - final Set s = new HashSet((Set) getValue()); - s.add(itemId); - setValue(s); - } - } - - /** - * Unselects an item. - * - * @param itemId - * the identifier of the Item to be unselected. - * @see #getNullSelectionItemId() - * @see #setNullSelectionItemId(Object) - * - */ - public void unselect(Object itemId) { - if (isSelected(itemId)) { - if (isMultiSelect()) { - final Set s = new HashSet((Set) getValue()); - s.remove(itemId); - setValue(s); - } else { - setValue(null); - } - } - } - - /** - * Notifies this listener that the Containers contents has changed. - * - * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent) - */ - @Override - public void containerPropertySetChange( - Container.PropertySetChangeEvent event) { - firePropertySetChange(); - } - - /** - * Adds a new Property set change listener for this Container. - * - * @see com.vaadin.data.Container.PropertySetChangeNotifier#addListener(com.vaadin.data.Container.PropertySetChangeListener) - */ - @Override - public void addListener(Container.PropertySetChangeListener listener) { - if (propertySetEventListeners == null) { - propertySetEventListeners = new LinkedHashSet(); - } - propertySetEventListeners.add(listener); - } - - /** - * Removes a previously registered Property set change listener. - * - * @see com.vaadin.data.Container.PropertySetChangeNotifier#removeListener(com.vaadin.data.Container.PropertySetChangeListener) - */ - @Override - public void removeListener(Container.PropertySetChangeListener listener) { - if (propertySetEventListeners != null) { - propertySetEventListeners.remove(listener); - if (propertySetEventListeners.isEmpty()) { - propertySetEventListeners = null; - } - } - } - - /** - * Adds an Item set change listener for the object. - * - * @see com.vaadin.data.Container.ItemSetChangeNotifier#addListener(com.vaadin.data.Container.ItemSetChangeListener) - */ - @Override - public void addListener(Container.ItemSetChangeListener listener) { - if (itemSetEventListeners == null) { - itemSetEventListeners = new LinkedHashSet(); - } - itemSetEventListeners.add(listener); - } - - /** - * Removes the Item set change listener from the object. - * - * @see com.vaadin.data.Container.ItemSetChangeNotifier#removeListener(com.vaadin.data.Container.ItemSetChangeListener) - */ - @Override - public void removeListener(Container.ItemSetChangeListener listener) { - if (itemSetEventListeners != null) { - itemSetEventListeners.remove(listener); - if (itemSetEventListeners.isEmpty()) { - itemSetEventListeners = null; - } - } - } - - @Override - public Collection getListeners(Class eventType) { - if (Container.ItemSetChangeEvent.class.isAssignableFrom(eventType)) { - if (itemSetEventListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(itemSetEventListeners); - } - } else if (Container.PropertySetChangeEvent.class - .isAssignableFrom(eventType)) { - if (propertySetEventListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(propertySetEventListeners); - } - } - - return super.getListeners(eventType); - } - - /** - * Lets the listener know a Containers Item set has changed. - * - * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent) - */ - @Override - public void containerItemSetChange(Container.ItemSetChangeEvent event) { - // Clears the item id mapping table - itemIdMapper.removeAll(); - - // Notify all listeners - fireItemSetChange(); - } - - /** - * Fires the property set change event. - */ - protected void firePropertySetChange() { - if (propertySetEventListeners != null - && !propertySetEventListeners.isEmpty()) { - final Container.PropertySetChangeEvent event = new PropertySetChangeEvent(); - final Object[] listeners = propertySetEventListeners.toArray(); - for (int i = 0; i < listeners.length; i++) { - ((Container.PropertySetChangeListener) listeners[i]) - .containerPropertySetChange(event); - } - } - requestRepaint(); - } - - /** - * Fires the item set change event. - */ - protected void fireItemSetChange() { - if (itemSetEventListeners != null && !itemSetEventListeners.isEmpty()) { - final Container.ItemSetChangeEvent event = new ItemSetChangeEvent(); - final Object[] listeners = itemSetEventListeners.toArray(); - for (int i = 0; i < listeners.length; i++) { - ((Container.ItemSetChangeListener) listeners[i]) - .containerItemSetChange(event); - } - } - requestRepaint(); - } - - /** - * Implementation of item set change event. - */ - private class ItemSetChangeEvent implements Serializable, - Container.ItemSetChangeEvent { - - /** - * Gets the Property where the event occurred. - * - * @see com.vaadin.data.Container.ItemSetChangeEvent#getContainer() - */ - @Override - public Container getContainer() { - return AbstractSelect.this; - } - - } - - /** - * Implementation of property set change event. - */ - private class PropertySetChangeEvent implements - Container.PropertySetChangeEvent, Serializable { - - /** - * Retrieves the Container whose contents have been modified. - * - * @see com.vaadin.data.Container.PropertySetChangeEvent#getContainer() - */ - @Override - public Container getContainer() { - return AbstractSelect.this; - } - - } - - /** - * For multi-selectable fields, also an empty collection of values is - * considered to be an empty field. - * - * @see AbstractField#isEmpty(). - */ - @Override - protected boolean isEmpty() { - if (!multiSelect) { - return super.isEmpty(); - } else { - Object value = getValue(); - return super.isEmpty() - || (value instanceof Collection && ((Collection) value) - .isEmpty()); - } - } - - /** - * Allow or disallow empty selection by the user. If the select is in - * single-select mode, you can make an item represent the empty selection by - * calling setNullSelectionItemId(). This way you can for - * instance set an icon and caption for the null selection item. - * - * @param nullSelectionAllowed - * whether or not to allow empty selection - * @see #setNullSelectionItemId(Object) - * @see #isNullSelectionAllowed() - */ - public void setNullSelectionAllowed(boolean nullSelectionAllowed) { - if (nullSelectionAllowed != this.nullSelectionAllowed) { - this.nullSelectionAllowed = nullSelectionAllowed; - requestRepaint(); - } - } - - /** - * Checks if null empty selection is allowed by the user. - * - * @return whether or not empty selection is allowed - * @see #setNullSelectionAllowed(boolean) - */ - public boolean isNullSelectionAllowed() { - return nullSelectionAllowed; - } - - /** - * Returns the item id that represents null value of this select in single - * select mode. - * - *

- * Data interface does not support nulls as item ids. Selecting the item - * identified by this id is the same as selecting no items at all. This - * setting only affects the single select mode. - *

- * - * @return the Object Null value item id. - * @see #setNullSelectionItemId(Object) - * @see #isSelected(Object) - * @see #select(Object) - */ - public Object getNullSelectionItemId() { - return nullSelectionItemId; - } - - /** - * Sets the item id that represents null value of this select. - * - *

- * Data interface does not support nulls as item ids. Selecting the item - * identified by this id is the same as selecting no items at all. This - * setting only affects the single select mode. - *

- * - * @param nullSelectionItemId - * the nullSelectionItemId to set. - * @see #getNullSelectionItemId() - * @see #isSelected(Object) - * @see #select(Object) - */ - public void setNullSelectionItemId(Object nullSelectionItemId) { - if (nullSelectionItemId != null && isMultiSelect()) { - throw new IllegalStateException( - "Multiselect and NullSelectionItemId can not be set at the same time."); - } - this.nullSelectionItemId = nullSelectionItemId; - } - - /** - * Notifies the component that it is connected to an application. - * - * @see com.vaadin.ui.AbstractField#attach() - */ - @Override - public void attach() { - super.attach(); - } - - /** - * Detaches the component from application. - * - * @see com.vaadin.ui.AbstractComponent#detach() - */ - @Override - public void detach() { - getCaptionChangeListener().clear(); - super.detach(); - } - - // Caption change listener - protected CaptionChangeListener getCaptionChangeListener() { - if (captionChangeListener == null) { - captionChangeListener = new CaptionChangeListener(); - } - return captionChangeListener; - } - - /** - * This is a listener helper for Item and Property changes that should cause - * a repaint. It should be attached to all items that are displayed, and the - * default implementation does this in paintContent(). Especially - * "lazyloading" components should take care to add and remove listeners as - * appropriate. Call addNotifierForItem() for each painted item (and - * remember to clear). - * - * NOTE: singleton, use getCaptionChangeListener(). - * - */ - protected class CaptionChangeListener implements - Item.PropertySetChangeListener, Property.ValueChangeListener { - - // TODO clean this up - type is either Item.PropertySetChangeNotifier or - // Property.ValueChangeNotifier - HashSet captionChangeNotifiers = new HashSet(); - - public void addNotifierForItem(Object itemId) { - switch (getItemCaptionMode()) { - case ITEM: - final Item i = getItem(itemId); - if (i == null) { - return; - } - if (i instanceof Item.PropertySetChangeNotifier) { - ((Item.PropertySetChangeNotifier) i) - .addListener(getCaptionChangeListener()); - captionChangeNotifiers.add(i); - } - Collection pids = i.getItemPropertyIds(); - if (pids != null) { - for (Iterator it = pids.iterator(); it.hasNext();) { - Property p = i.getItemProperty(it.next()); - if (p != null - && p instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) p) - .addListener(getCaptionChangeListener()); - captionChangeNotifiers.add(p); - } - } - - } - break; - case PROPERTY: - final Property p = getContainerProperty(itemId, - getItemCaptionPropertyId()); - if (p != null && p instanceof Property.ValueChangeNotifier) { - ((Property.ValueChangeNotifier) p) - .addListener(getCaptionChangeListener()); - captionChangeNotifiers.add(p); - } - break; - - } - } - - public void clear() { - for (Iterator it = captionChangeNotifiers.iterator(); it - .hasNext();) { - Object notifier = it.next(); - if (notifier instanceof Item.PropertySetChangeNotifier) { - ((Item.PropertySetChangeNotifier) notifier) - .removeListener(getCaptionChangeListener()); - } else { - ((Property.ValueChangeNotifier) notifier) - .removeListener(getCaptionChangeListener()); - } - } - captionChangeNotifiers.clear(); - } - - @Override - public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) { - requestRepaint(); - } - - @Override - public void itemPropertySetChange( - com.vaadin.data.Item.PropertySetChangeEvent event) { - requestRepaint(); - } - - } - - /** - * Criterion which accepts a drop only if the drop target is (one of) the - * given Item identifier(s). Criterion can be used only on a drop targets - * that extends AbstractSelect like {@link Table} and {@link Tree}. The - * target and identifiers of valid Items are given in constructor. - * - * @since 6.3 - */ - public static class TargetItemIs extends AbstractItemSetCriterion { - - /** - * @param select - * the select implementation that is used as a drop target - * @param itemId - * the identifier(s) that are valid drop locations - */ - public TargetItemIs(AbstractSelect select, Object... itemId) { - super(select, itemId); - } - - @Override - public boolean accept(DragAndDropEvent dragEvent) { - AbstractSelectTargetDetails dropTargetData = (AbstractSelectTargetDetails) dragEvent - .getTargetDetails(); - if (dropTargetData.getTarget() != select) { - return false; - } - return itemIds.contains(dropTargetData.getItemIdOver()); - } - - } - - /** - * Abstract helper class to implement item id based criterion. - * - * Note, inner class used not to open itemIdMapper for public access. - * - * @since 6.3 - * - */ - private static abstract class AbstractItemSetCriterion extends - ClientSideCriterion { - protected final Collection itemIds = new HashSet(); - protected AbstractSelect select; - - public AbstractItemSetCriterion(AbstractSelect select, Object... itemId) { - if (itemIds == null || select == null) { - throw new IllegalArgumentException( - "Accepted item identifiers must be accepted."); - } - Collections.addAll(itemIds, itemId); - this.select = select; - } - - @Override - public void paintContent(PaintTarget target) throws PaintException { - super.paintContent(target); - String[] keys = new String[itemIds.size()]; - int i = 0; - for (Object itemId : itemIds) { - String key = select.itemIdMapper.key(itemId); - keys[i++] = key; - } - target.addAttribute("keys", keys); - target.addAttribute("s", select); - } - - } - - /** - * This criterion accepts a only a {@link Transferable} that contains given - * Item (practically its identifier) from a specific AbstractSelect. - * - * @since 6.3 - */ - public static class AcceptItem extends AbstractItemSetCriterion { - - /** - * @param select - * the select from which the item id's are checked - * @param itemId - * the item identifier(s) of the select that are accepted - */ - public AcceptItem(AbstractSelect select, Object... itemId) { - super(select, itemId); - } - - @Override - public boolean accept(DragAndDropEvent dragEvent) { - DataBoundTransferable transferable = (DataBoundTransferable) dragEvent - .getTransferable(); - if (transferable.getSourceComponent() != select) { - return false; - } - return itemIds.contains(transferable.getItemId()); - } - - /** - * A simple accept criterion which ensures that {@link Transferable} - * contains an {@link Item} (or actually its identifier). In other words - * the criterion check that drag is coming from a {@link Container} like - * {@link Tree} or {@link Table}. - */ - public static final ClientSideCriterion ALL = new ContainsDataFlavor( - "itemId"); - - } - - /** - * TargetDetails implementation for subclasses of {@link AbstractSelect} - * that implement {@link DropTarget}. - * - * @since 6.3 - */ - public class AbstractSelectTargetDetails extends TargetDetailsImpl { - - /** - * The item id over which the drag event happened. - */ - protected Object idOver; - - /** - * Constructor that automatically converts itemIdOver key to - * corresponding item Id - * - */ - protected AbstractSelectTargetDetails(Map rawVariables) { - super(rawVariables, (DropTarget) AbstractSelect.this); - // eagar fetch itemid, mapper may be emptied - String keyover = (String) getData("itemIdOver"); - if (keyover != null) { - idOver = itemIdMapper.get(keyover); - } - } - - /** - * If the drag operation is currently over an {@link Item}, this method - * returns the identifier of that {@link Item}. - * - */ - public Object getItemIdOver() { - return idOver; - } - - /** - * Returns a detailed vertical location where the drop happened on Item. - */ - public VerticalDropLocation getDropLocation() { - String detail = (String) getData("detail"); - if (detail == null) { - return null; - } - return VerticalDropLocation.valueOf(detail); - } - - } - - /** - * An accept criterion to accept drops only on a specific vertical location - * of an item. - *

- * This accept criterion is currently usable in Tree and Table - * implementations. - */ - public static class VerticalLocationIs extends TargetDetailIs { - public static VerticalLocationIs TOP = new VerticalLocationIs( - VerticalDropLocation.TOP); - public static VerticalLocationIs BOTTOM = new VerticalLocationIs( - VerticalDropLocation.BOTTOM); - public static VerticalLocationIs MIDDLE = new VerticalLocationIs( - VerticalDropLocation.MIDDLE); - - private VerticalLocationIs(VerticalDropLocation l) { - super("detail", l.name()); - } - } - - /** - * Implement this interface and pass it to Tree.setItemDescriptionGenerator - * or Table.setItemDescriptionGenerator to generate mouse over descriptions - * ("tooltips") for the rows and cells in Table or for the items in Tree. - */ - public interface ItemDescriptionGenerator extends Serializable { - - /** - * Called by Table when a cell (and row) is painted or a item is painted - * in Tree - * - * @param source - * The source of the generator, the Tree or Table the - * generator is attached to - * @param itemId - * The itemId of the painted cell - * @param propertyId - * The propertyId of the cell, null when getting row - * description - * @return The description or "tooltip" of the item. - */ - public String generateDescription(Component source, Object itemId, - Object propertyId); - } -} diff --git a/src/com/vaadin/ui/AbstractSplitPanel.java b/src/com/vaadin/ui/AbstractSplitPanel.java deleted file mode 100644 index 90dc38ff65..0000000000 --- a/src/com/vaadin/ui/AbstractSplitPanel.java +++ /dev/null @@ -1,521 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.Iterator; - -import com.vaadin.event.ComponentEventListener; -import com.vaadin.event.MouseEvents.ClickEvent; -import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelRpc; -import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState; -import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState.SplitterState; -import com.vaadin.terminal.Sizeable; -import com.vaadin.terminal.gwt.client.ui.ClickEventHandler; -import com.vaadin.tools.ReflectTools; - -/** - * AbstractSplitPanel. - * - * AbstractSplitPanel is base class for a component container that - * can contain two components. The components are split by a divider element. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 6.5 - */ -public abstract class AbstractSplitPanel extends AbstractComponentContainer { - - // TODO use Unit in AbstractSplitPanelState and remove these - private Unit posUnit; - private Unit posMinUnit; - private Unit posMaxUnit; - - private AbstractSplitPanelRpc rpc = new AbstractSplitPanelRpc() { - - @Override - public void splitterClick(MouseEventDetails mouseDetails) { - fireEvent(new SplitterClickEvent(AbstractSplitPanel.this, - mouseDetails)); - } - - @Override - public void setSplitterPosition(float position) { - getSplitterState().setPosition(position); - } - }; - - public AbstractSplitPanel() { - registerRpc(rpc); - setSplitPosition(50, Unit.PERCENTAGE, false); - setSplitPositionLimits(0, Unit.PERCENTAGE, 100, Unit.PERCENTAGE); - } - - /** - * Modifiable and Serializable Iterator for the components, used by - * {@link AbstractSplitPanel#getComponentIterator()}. - */ - private class ComponentIterator implements Iterator, - Serializable { - - int i = 0; - - @Override - public boolean hasNext() { - if (i < getComponentCount()) { - return true; - } - return false; - } - - @Override - public Component next() { - if (!hasNext()) { - return null; - } - i++; - if (i == 1) { - return (getFirstComponent() == null ? getSecondComponent() - : getFirstComponent()); - } else if (i == 2) { - return getSecondComponent(); - } - return null; - } - - @Override - public void remove() { - if (i == 1) { - if (getFirstComponent() != null) { - setFirstComponent(null); - i = 0; - } else { - setSecondComponent(null); - } - } else if (i == 2) { - setSecondComponent(null); - } - } - } - - /** - * Add a component into this container. The component is added to the right - * or under the previous component. - * - * @param c - * the component to be added. - */ - - @Override - public void addComponent(Component c) { - if (getFirstComponent() == null) { - setFirstComponent(c); - } else if (getSecondComponent() == null) { - setSecondComponent(c); - } else { - throw new UnsupportedOperationException( - "Split panel can contain only two components"); - } - } - - /** - * Sets the first component of this split panel. Depending on the direction - * the first component is shown at the top or to the left. - * - * @param c - * The component to use as first component - */ - public void setFirstComponent(Component c) { - if (getFirstComponent() == c) { - // Nothing to do - return; - } - - if (getFirstComponent() != null) { - // detach old - removeComponent(getFirstComponent()); - } - getState().setFirstChild(c); - if (c != null) { - super.addComponent(c); - } - - requestRepaint(); - } - - /** - * Sets the second component of this split panel. Depending on the direction - * the second component is shown at the bottom or to the left. - * - * @param c - * The component to use as first component - */ - public void setSecondComponent(Component c) { - if (getSecondComponent() == c) { - // Nothing to do - return; - } - - if (getSecondComponent() != null) { - // detach old - removeComponent(getSecondComponent()); - } - getState().setSecondChild(c); - if (c != null) { - super.addComponent(c); - } - requestRepaint(); - } - - /** - * Gets the first component of this split panel. Depending on the direction - * this is either the component shown at the top or to the left. - * - * @return the first component of this split panel - */ - public Component getFirstComponent() { - return (Component) getState().getFirstChild(); - } - - /** - * Gets the second component of this split panel. Depending on the direction - * this is either the component shown at the top or to the left. - * - * @return the second component of this split panel - */ - public Component getSecondComponent() { - return (Component) getState().getSecondChild(); - } - - /** - * Removes the component from this container. - * - * @param c - * the component to be removed. - */ - - @Override - public void removeComponent(Component c) { - super.removeComponent(c); - if (c == getFirstComponent()) { - getState().setFirstChild(null); - } else if (c == getSecondComponent()) { - getState().setSecondChild(null); - } - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.ComponentContainer#getComponentIterator() - */ - - @Override - public Iterator getComponentIterator() { - return new ComponentIterator(); - } - - /** - * Gets the number of contained components. Consistent with the iterator - * returned by {@link #getComponentIterator()}. - * - * @return the number of contained components (zero, one or two) - */ - - @Override - public int getComponentCount() { - int count = 0; - if (getFirstComponent() != null) { - count++; - } - if (getSecondComponent() != null) { - count++; - } - return count; - } - - /* Documented in superclass */ - - @Override - public void replaceComponent(Component oldComponent, Component newComponent) { - if (oldComponent == getFirstComponent()) { - setFirstComponent(newComponent); - } else if (oldComponent == getSecondComponent()) { - setSecondComponent(newComponent); - } - requestRepaint(); - } - - /** - * Moves the position of the splitter. - * - * @param pos - * the new size of the first region in the unit that was last - * used (default is percentage). Fractions are only allowed when - * unit is percentage. - */ - public void setSplitPosition(float pos) { - setSplitPosition(pos, posUnit, false); - } - - /** - * Moves the position of the splitter. - * - * @param pos - * the new size of the region in the unit that was last used - * (default is percentage). Fractions are only allowed when unit - * is percentage. - * - * @param reverse - * if set to true the split splitter position is measured by the - * second region else it is measured by the first region - */ - public void setSplitPosition(float pos, boolean reverse) { - setSplitPosition(pos, posUnit, reverse); - } - - /** - * Moves the position of the splitter with given position and unit. - * - * @param pos - * the new size of the first region. Fractions are only allowed - * when unit is percentage. - * @param unit - * the unit (from {@link Sizeable}) in which the size is given. - */ - public void setSplitPosition(float pos, Unit unit) { - setSplitPosition(pos, unit, false); - } - - /** - * Moves the position of the splitter with given position and unit. - * - * @param pos - * the new size of the first region. Fractions are only allowed - * when unit is percentage. - * @param unit - * the unit (from {@link Sizeable}) in which the size is given. - * @param reverse - * if set to true the split splitter position is measured by the - * second region else it is measured by the first region - * - */ - public void setSplitPosition(float pos, Unit unit, boolean reverse) { - if (unit != Unit.PERCENTAGE && unit != Unit.PIXELS) { - throw new IllegalArgumentException( - "Only percentage and pixel units are allowed"); - } - if (unit != Unit.PERCENTAGE) { - pos = Math.round(pos); - } - SplitterState splitterState = getSplitterState(); - splitterState.setPosition(pos); - splitterState.setPositionUnit(unit.getSymbol()); - splitterState.setPositionReversed(reverse); - posUnit = unit; - - requestRepaint(); - } - - /** - * Returns the current position of the splitter, in - * {@link #getSplitPositionUnit()} units. - * - * @return position of the splitter - */ - public float getSplitPosition() { - return getSplitterState().getPosition(); - } - - /** - * Returns the unit of position of the splitter - * - * @return unit of position of the splitter - */ - public Unit getSplitPositionUnit() { - return posUnit; - } - - /** - * Sets the minimum split position to the given position and unit. If the - * split position is reversed, maximum and minimum are also reversed. - * - * @param pos - * the minimum position of the split - * @param unit - * the unit (from {@link Sizeable}) in which the size is given. - * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS - */ - public void setMinSplitPosition(int pos, Unit unit) { - setSplitPositionLimits(pos, unit, getSplitterState().getMaxPosition(), - posMaxUnit); - } - - /** - * Returns the current minimum position of the splitter, in - * {@link #getMinSplitPositionUnit()} units. - * - * @return the minimum position of the splitter - */ - public float getMinSplitPosition() { - return getSplitterState().getMinPosition(); - } - - /** - * Returns the unit of the minimum position of the splitter. - * - * @return the unit of the minimum position of the splitter - */ - public Unit getMinSplitPositionUnit() { - return posMinUnit; - } - - /** - * Sets the maximum split position to the given position and unit. If the - * split position is reversed, maximum and minimum are also reversed. - * - * @param pos - * the maximum position of the split - * @param unit - * the unit (from {@link Sizeable}) in which the size is given. - * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS - */ - public void setMaxSplitPosition(float pos, Unit unit) { - setSplitPositionLimits(getSplitterState().getMinPosition(), posMinUnit, - pos, unit); - } - - /** - * Returns the current maximum position of the splitter, in - * {@link #getMaxSplitPositionUnit()} units. - * - * @return the maximum position of the splitter - */ - public float getMaxSplitPosition() { - return getSplitterState().getMaxPosition(); - } - - /** - * Returns the unit of the maximum position of the splitter - * - * @return the unit of the maximum position of the splitter - */ - public Unit getMaxSplitPositionUnit() { - return posMaxUnit; - } - - /** - * Sets the maximum and minimum position of the splitter. If the split - * position is reversed, maximum and minimum are also reversed. - * - * @param minPos - * the new minimum position - * @param minPosUnit - * the unit (from {@link Sizeable}) in which the minimum position - * is given. - * @param maxPos - * the new maximum position - * @param maxPosUnit - * the unit (from {@link Sizeable}) in which the maximum position - * is given. - */ - private void setSplitPositionLimits(float minPos, Unit minPosUnit, - float maxPos, Unit maxPosUnit) { - if ((minPosUnit != Unit.PERCENTAGE && minPosUnit != Unit.PIXELS) - || (maxPosUnit != Unit.PERCENTAGE && maxPosUnit != Unit.PIXELS)) { - throw new IllegalArgumentException( - "Only percentage and pixel units are allowed"); - } - - SplitterState state = getSplitterState(); - - state.setMinPosition(minPos); - state.setMinPositionUnit(minPosUnit.getSymbol()); - posMinUnit = minPosUnit; - - state.setMaxPosition(maxPos); - state.setMaxPositionUnit(maxPosUnit.getSymbol()); - posMaxUnit = maxPosUnit; - - requestRepaint(); - } - - /** - * Lock the SplitPanels position, disabling the user from dragging the split - * handle. - * - * @param locked - * Set true if locked, false otherwise. - */ - public void setLocked(boolean locked) { - getSplitterState().setLocked(locked); - requestRepaint(); - } - - /** - * Is the SplitPanel handle locked (user not allowed to change split - * position by dragging). - * - * @return true if locked, false otherwise. - */ - public boolean isLocked() { - return getSplitterState().isLocked(); - } - - /** - * SplitterClickListener interface for listening for - * SplitterClickEvent fired by a SplitPanel. - * - * @see SplitterClickEvent - * @since 6.2 - */ - public interface SplitterClickListener extends ComponentEventListener { - - public static final Method clickMethod = ReflectTools.findMethod( - SplitterClickListener.class, "splitterClick", - SplitterClickEvent.class); - - /** - * SplitPanel splitter has been clicked - * - * @param event - * SplitterClickEvent event. - */ - public void splitterClick(SplitterClickEvent event); - } - - public class SplitterClickEvent extends ClickEvent { - - public SplitterClickEvent(Component source, - MouseEventDetails mouseEventDetails) { - super(source, mouseEventDetails); - } - - } - - public void addListener(SplitterClickListener listener) { - addListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER, - SplitterClickEvent.class, listener, - SplitterClickListener.clickMethod); - } - - public void removeListener(SplitterClickListener listener) { - removeListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER, - SplitterClickEvent.class, listener); - } - - @Override - public AbstractSplitPanelState getState() { - return (AbstractSplitPanelState) super.getState(); - } - - private SplitterState getSplitterState() { - return getState().getSplitterState(); - } -} diff --git a/src/com/vaadin/ui/AbstractTextField.java b/src/com/vaadin/ui/AbstractTextField.java deleted file mode 100644 index 2326c07d97..0000000000 --- a/src/com/vaadin/ui/AbstractTextField.java +++ /dev/null @@ -1,674 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.util.Map; - -import com.vaadin.event.FieldEvents.BlurEvent; -import com.vaadin.event.FieldEvents.BlurListener; -import com.vaadin.event.FieldEvents.BlurNotifier; -import com.vaadin.event.FieldEvents.FocusEvent; -import com.vaadin.event.FieldEvents.FocusListener; -import com.vaadin.event.FieldEvents.FocusNotifier; -import com.vaadin.event.FieldEvents.TextChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeListener; -import com.vaadin.event.FieldEvents.TextChangeNotifier; -import com.vaadin.shared.ui.textfield.AbstractTextFieldState; -import com.vaadin.terminal.PaintException; -import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.Vaadin6Component; -import com.vaadin.terminal.gwt.client.ui.textfield.VTextField; - -public abstract class AbstractTextField extends AbstractField implements - BlurNotifier, FocusNotifier, TextChangeNotifier, Vaadin6Component { - - /** - * Null representation. - */ - private String nullRepresentation = "null"; - /** - * Is setting to null from non-null value allowed by setting with null - * representation . - */ - private boolean nullSettingAllowed = false; - /** - * The text content when the last messages to the server was sent. Cleared - * when value is changed. - */ - private String lastKnownTextContent; - - /** - * The position of the cursor when the last message to the server was sent. - */ - private int lastKnownCursorPosition; - - /** - * Flag indicating that a text change event is pending to be triggered. - * Cleared by {@link #setInternalValue(Object)} and when the event is fired. - */ - private boolean textChangeEventPending; - - private boolean isFiringTextChangeEvent = false; - - private TextChangeEventMode textChangeEventMode = TextChangeEventMode.LAZY; - - private final int DEFAULT_TEXTCHANGE_TIMEOUT = 400; - - private int textChangeEventTimeout = DEFAULT_TEXTCHANGE_TIMEOUT; - - /** - * Temporarily holds the new selection position. Cleared on paint. - */ - private int selectionPosition = -1; - - /** - * Temporarily holds the new selection length. - */ - private int selectionLength; - - /** - * Flag used to determine whether we are currently handling a state change - * triggered by a user. Used to properly fire text change event before value - * change event triggered by the client side. - */ - private boolean changingVariables; - - protected AbstractTextField() { - super(); - } - - @Override - public AbstractTextFieldState getState() { - return (AbstractTextFieldState) super.getState(); - } - - @Override - public void updateState() { - super.updateState(); - - String value = getValue(); - if (value == null) { - value = getNullRepresentation(); - } - getState().setText(value); - } - - @Override - public void paintContent(PaintTarget target) throws PaintException { - - if (selectionPosition != -1) { - target.addAttribute("selpos", selectionPosition); - target.addAttribute("sellen", selectionLength); - selectionPosition = -1; - } - - if (hasListeners(TextChangeEvent.class)) { - target.addAttribute(VTextField.ATTR_TEXTCHANGE_EVENTMODE, - getTextChangeEventMode().toString()); - target.addAttribute(VTextField.ATTR_TEXTCHANGE_TIMEOUT, - getTextChangeTimeout()); - if (lastKnownTextContent != null) { - /* - * The field has be repainted for some reason (e.g. caption, - * size, stylename), but the value has not been changed since - * the last text change event. Let the client side know about - * the value the server side knows. Client side may then ignore - * the actual value, depending on its state. - */ - target.addAttribute( - VTextField.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS, true); - } - } - - } - - @Override - public void changeVariables(Object source, Map variables) { - changingVariables = true; - - try { - - if (variables.containsKey(VTextField.VAR_CURSOR)) { - Integer object = (Integer) variables.get(VTextField.VAR_CURSOR); - lastKnownCursorPosition = object.intValue(); - } - - if (variables.containsKey(VTextField.VAR_CUR_TEXT)) { - /* - * NOTE, we might want to develop this further so that on a - * value change event the whole text content don't need to be - * sent from the client to server. Just "commit" the value from - * currentText to the value. - */ - handleInputEventTextChange(variables); - } - - // Sets the text - if (variables.containsKey("text") && !isReadOnly()) { - - // Only do the setting if the string representation of the value - // has been updated - String newValue = (String) variables.get("text"); - - // server side check for max length - if (getMaxLength() != -1 && newValue.length() > getMaxLength()) { - newValue = newValue.substring(0, getMaxLength()); - } - final String oldValue = getValue(); - if (newValue != null - && (oldValue == null || isNullSettingAllowed()) - && newValue.equals(getNullRepresentation())) { - newValue = null; - } - if (newValue != oldValue - && (newValue == null || !newValue.equals(oldValue))) { - boolean wasModified = isModified(); - setValue(newValue, true); - - // If the modified status changes, or if we have a - // formatter, repaint is needed after all. - if (wasModified != isModified()) { - requestRepaint(); - } - } - } - firePendingTextChangeEvent(); - - if (variables.containsKey(FocusEvent.EVENT_ID)) { - fireEvent(new FocusEvent(this)); - } - if (variables.containsKey(BlurEvent.EVENT_ID)) { - fireEvent(new BlurEvent(this)); - } - } finally { - changingVariables = false; - - } - - } - - @Override - public Class getType() { - return String.class; - } - - /** - * Gets the null-string representation. - * - *

- * The null-valued strings are represented on the user interface by - * replacing the null value with this string. If the null representation is - * set null (not 'null' string), painting null value throws exception. - *

- * - *

- * The default value is string 'null'. - *

- * - * @return the String Textual representation for null strings. - * @see TextField#isNullSettingAllowed() - */ - public String getNullRepresentation() { - return nullRepresentation; - } - - /** - * Is setting nulls with null-string representation allowed. - * - *

- * If this property is true, writing null-representation string to text - * field always sets the field value to real null. If this property is - * false, null setting is not made, but the null values are maintained. - * Maintenance of null-values is made by only converting the textfield - * contents to real null, if the text field matches the null-string - * representation and the current value of the field is null. - *

- * - *

- * By default this setting is false - *

- * - * @return boolean Should the null-string represenation be always converted - * to null-values. - * @see TextField#getNullRepresentation() - */ - public boolean isNullSettingAllowed() { - return nullSettingAllowed; - } - - /** - * Sets the null-string representation. - * - *

- * The null-valued strings are represented on the user interface by - * replacing the null value with this string. If the null representation is - * set null (not 'null' string), painting null value throws exception. - *

- * - *

- * The default value is string 'null' - *

- * - * @param nullRepresentation - * Textual representation for null strings. - * @see TextField#setNullSettingAllowed(boolean) - */ - public void setNullRepresentation(String nullRepresentation) { - this.nullRepresentation = nullRepresentation; - requestRepaint(); - } - - /** - * Sets the null conversion mode. - * - *

- * If this property is true, writing null-representation string to text - * field always sets the field value to real null. If this property is - * false, null setting is not made, but the null values are maintained. - * Maintenance of null-values is made by only converting the textfield - * contents to real null, if the text field matches the null-string - * representation and the current value of the field is null. - *

- * - *

- * By default this setting is false. - *

- * - * @param nullSettingAllowed - * Should the null-string representation always be converted to - * null-values. - * @see TextField#getNullRepresentation() - */ - public void setNullSettingAllowed(boolean nullSettingAllowed) { - this.nullSettingAllowed = nullSettingAllowed; - requestRepaint(); - } - - @Override - protected boolean isEmpty() { - return super.isEmpty() || getValue().length() == 0; - } - - /** - * Returns the maximum number of characters in the field. Value -1 is - * considered unlimited. Terminal may however have some technical limits. - * - * @return the maxLength - */ - public int getMaxLength() { - return getState().getMaxLength(); - } - - /** - * Sets the maximum number of characters in the field. Value -1 is - * considered unlimited. Terminal may however have some technical limits. - * - * @param maxLength - * the maxLength to set - */ - public void setMaxLength(int maxLength) { - getState().setMaxLength(maxLength); - requestRepaint(); - } - - /** - * Gets the number of columns in the editor. If the number of columns is set - * 0, the actual number of displayed columns is determined implicitly by the - * adapter. - * - * @return the number of columns in the editor. - */ - public int getColumns() { - return getState().getColumns(); - } - - /** - * Sets the number of columns in the editor. If the number of columns is set - * 0, the actual number of displayed columns is determined implicitly by the - * adapter. - * - * @param columns - * the number of columns to set. - */ - public void setColumns(int columns) { - if (columns < 0) { - columns = 0; - } - getState().setColumns(columns); - requestRepaint(); - } - - /** - * Gets the current input prompt. - * - * @see #setInputPrompt(String) - * @return the current input prompt, or null if not enabled - */ - public String getInputPrompt() { - return getState().getInputPrompt(); - } - - /** - * Sets the input prompt - a textual prompt that is displayed when the field - * would otherwise be empty, to prompt the user for input. - * - * @param inputPrompt - */ - public void setInputPrompt(String inputPrompt) { - getState().setInputPrompt(inputPrompt); - requestRepaint(); - } - - /* ** Text Change Events ** */ - - private void firePendingTextChangeEvent() { - if (textChangeEventPending && !isFiringTextChangeEvent) { - isFiringTextChangeEvent = true; - textChangeEventPending = false; - try { - fireEvent(new TextChangeEventImpl(this)); - } finally { - isFiringTextChangeEvent = false; - } - } - } - - @Override - protected void setInternalValue(String newValue) { - if (changingVariables && !textChangeEventPending) { - - /* - * TODO check for possible (minor?) issue (not tested) - * - * -field with e.g. PropertyFormatter. - * - * -TextChangeListener and it changes value. - * - * -if formatter again changes the value, do we get an extra - * simulated text change event ? - */ - - /* - * Fire a "simulated" text change event before value change event if - * change is coming from the client side. - * - * Iff there is both value change and textChangeEvent in same - * variable burst, it is a text field in non immediate mode and the - * text change event "flushed" queued value change event. In this - * case textChangeEventPending flag is already on and text change - * event will be fired after the value change event. - */ - if (newValue == null && lastKnownTextContent != null - && !lastKnownTextContent.equals(getNullRepresentation())) { - // Value was changed from something to null representation - lastKnownTextContent = getNullRepresentation(); - textChangeEventPending = true; - } else if (newValue != null - && !newValue.toString().equals(lastKnownTextContent)) { - // Value was changed to something else than null representation - lastKnownTextContent = newValue.toString(); - textChangeEventPending = true; - } - firePendingTextChangeEvent(); - } - - super.setInternalValue(newValue); - } - - @Override - public void setValue(Object newValue) throws ReadOnlyException { - super.setValue(newValue); - /* - * Make sure w reset lastKnownTextContent field on value change. The - * clearing must happen here as well because TextChangeListener can - * revert the original value. Client must respect the value in this - * case. AbstractField optimizes value change if the existing value is - * reset. Also we need to force repaint if the flag is on. - */ - if (lastKnownTextContent != null) { - lastKnownTextContent = null; - requestRepaint(); - } - } - - private void handleInputEventTextChange(Map variables) { - /* - * TODO we could vastly optimize the communication of values by using - * some sort of diffs instead of always sending the whole text content. - * Also on value change events we could use the mechanism. - */ - String object = (String) variables.get(VTextField.VAR_CUR_TEXT); - lastKnownTextContent = object; - textChangeEventPending = true; - } - - /** - * Sets the mode how the TextField triggers {@link TextChangeEvent}s. - * - * @param inputEventMode - * the new mode - * - * @see TextChangeEventMode - */ - public void setTextChangeEventMode(TextChangeEventMode inputEventMode) { - textChangeEventMode = inputEventMode; - requestRepaint(); - } - - /** - * @return the mode used to trigger {@link TextChangeEvent}s. - */ - public TextChangeEventMode getTextChangeEventMode() { - return textChangeEventMode; - } - - /** - * Different modes how the TextField can trigger {@link TextChangeEvent}s. - */ - public enum TextChangeEventMode { - - /** - * An event is triggered on each text content change, most commonly key - * press events. - */ - EAGER, - /** - * Each text change event in the UI causes the event to be communicated - * to the application after a timeout. The length of the timeout can be - * controlled with {@link TextField#setInputEventTimeout(int)}. Only the - * last input event is reported to the server side if several text - * change events happen during the timeout. - *

- * In case of a {@link ValueChangeEvent} the schedule is not kept - * strictly. Before a {@link ValueChangeEvent} a {@link TextChangeEvent} - * is triggered if the text content has changed since the previous - * TextChangeEvent regardless of the schedule. - */ - TIMEOUT, - /** - * An event is triggered when there is a pause of text modifications. - * The length of the pause can be modified with - * {@link TextField#setInputEventTimeout(int)}. Like with the - * {@link #TIMEOUT} mode, an event is forced before - * {@link ValueChangeEvent}s, even if the user did not keep a pause - * while entering the text. - *

- * This is the default mode. - */ - LAZY - } - - @Override - public void addListener(TextChangeListener listener) { - addListener(TextChangeListener.EVENT_ID, TextChangeEvent.class, - listener, TextChangeListener.EVENT_METHOD); - } - - @Override - public void removeListener(TextChangeListener listener) { - removeListener(TextChangeListener.EVENT_ID, TextChangeEvent.class, - listener); - } - - /** - * The text change timeout modifies how often text change events are - * communicated to the application when {@link #getTextChangeEventMode()} is - * {@link TextChangeEventMode#LAZY} or {@link TextChangeEventMode#TIMEOUT}. - * - * - * @see #getTextChangeEventMode() - * - * @param timeout - * the timeout in milliseconds - */ - public void setTextChangeTimeout(int timeout) { - textChangeEventTimeout = timeout; - requestRepaint(); - } - - /** - * Gets the timeout used to fire {@link TextChangeEvent}s when the - * {@link #getTextChangeEventMode()} is {@link TextChangeEventMode#LAZY} or - * {@link TextChangeEventMode#TIMEOUT}. - * - * @return the timeout value in milliseconds - */ - public int getTextChangeTimeout() { - return textChangeEventTimeout; - } - - public class TextChangeEventImpl extends TextChangeEvent { - private String curText; - private int cursorPosition; - - private TextChangeEventImpl(final AbstractTextField tf) { - super(tf); - curText = tf.getCurrentTextContent(); - cursorPosition = tf.getCursorPosition(); - } - - @Override - public AbstractTextField getComponent() { - return (AbstractTextField) super.getComponent(); - } - - @Override - public String getText() { - return curText; - } - - @Override - public int getCursorPosition() { - return cursorPosition; - } - - } - - /** - * Gets the current (or the last known) text content in the field. - *

- * Note the text returned by this method is not necessary the same that is - * returned by the {@link #getValue()} method. The value is updated when the - * terminal fires a value change event via e.g. blurring the field or by - * pressing enter. The value returned by this method is updated also on - * {@link TextChangeEvent}s. Due to this high dependency to the terminal - * implementation this method is (at least at this point) not published. - * - * @return the text which is currently displayed in the field. - */ - private String getCurrentTextContent() { - if (lastKnownTextContent != null) { - return lastKnownTextContent; - } else { - Object text = getValue(); - if (text == null) { - return getNullRepresentation(); - } - return text.toString(); - } - } - - /** - * Selects all text in the field. - * - * @since 6.4 - */ - public void selectAll() { - String text = getValue() == null ? "" : getValue().toString(); - setSelectionRange(0, text.length()); - } - - /** - * Sets the range of text to be selected. - * - * As a side effect the field will become focused. - * - * @since 6.4 - * - * @param pos - * the position of the first character to be selected - * @param length - * the number of characters to be selected - */ - public void setSelectionRange(int pos, int length) { - selectionPosition = pos; - selectionLength = length; - focus(); - requestRepaint(); - } - - /** - * Sets the cursor position in the field. As a side effect the field will - * become focused. - * - * @since 6.4 - * - * @param pos - * the position for the cursor - * */ - public void setCursorPosition(int pos) { - setSelectionRange(pos, 0); - lastKnownCursorPosition = pos; - } - - /** - * Returns the last known cursor position of the field. - * - *

- * Note that due to the client server nature or the GWT terminal, Vaadin - * cannot provide the exact value of the cursor position in most situations. - * The value is updated only when the client side terminal communicates to - * TextField, like on {@link ValueChangeEvent}s and {@link TextChangeEvent} - * s. This may change later if a deep push integration is built to Vaadin. - * - * @return the cursor position - */ - public int getCursorPosition() { - return lastKnownCursorPosition; - } - - @Override - public void addListener(FocusListener listener) { - addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, - FocusListener.focusMethod); - } - - @Override - public void removeListener(FocusListener listener) { - removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener); - } - - @Override - public void addListener(BlurListener listener) { - addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, - BlurListener.blurMethod); - } - - @Override - public void removeListener(BlurListener listener) { - removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); - } - -} diff --git a/src/com/vaadin/ui/Accordion.java b/src/com/vaadin/ui/Accordion.java deleted file mode 100644 index b937c7bc2b..0000000000 --- a/src/com/vaadin/ui/Accordion.java +++ /dev/null @@ -1,19 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -/** - * An accordion is a component similar to a {@link TabSheet}, but with a - * vertical orientation and the selected component presented between tabs. - * - * Closable tabs are not supported by the accordion. - * - * The {@link Accordion} can be styled with the .v-accordion, .v-accordion-item, - * .v-accordion-item-first and .v-accordion-item-caption styles. - * - * @see TabSheet - */ -public class Accordion extends TabSheet { - -} diff --git a/src/com/vaadin/ui/Alignment.java b/src/com/vaadin/ui/Alignment.java deleted file mode 100644 index 0d73da8504..0000000000 --- a/src/com/vaadin/ui/Alignment.java +++ /dev/null @@ -1,158 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -import java.io.Serializable; - -import com.vaadin.shared.ui.AlignmentInfo.Bits; - -/** - * Class containing information about alignment of a component. Use the - * pre-instantiated classes. - */ -@SuppressWarnings("serial") -public final class Alignment implements Serializable { - - public static final Alignment TOP_RIGHT = new Alignment(Bits.ALIGNMENT_TOP - + Bits.ALIGNMENT_RIGHT); - public static final Alignment TOP_LEFT = new Alignment(Bits.ALIGNMENT_TOP - + Bits.ALIGNMENT_LEFT); - public static final Alignment TOP_CENTER = new Alignment(Bits.ALIGNMENT_TOP - + Bits.ALIGNMENT_HORIZONTAL_CENTER); - public static final Alignment MIDDLE_RIGHT = new Alignment( - Bits.ALIGNMENT_VERTICAL_CENTER + Bits.ALIGNMENT_RIGHT); - public static final Alignment MIDDLE_LEFT = new Alignment( - Bits.ALIGNMENT_VERTICAL_CENTER + Bits.ALIGNMENT_LEFT); - public static final Alignment MIDDLE_CENTER = new Alignment( - Bits.ALIGNMENT_VERTICAL_CENTER + Bits.ALIGNMENT_HORIZONTAL_CENTER); - public static final Alignment BOTTOM_RIGHT = new Alignment( - Bits.ALIGNMENT_BOTTOM + Bits.ALIGNMENT_RIGHT); - public static final Alignment BOTTOM_LEFT = new Alignment( - Bits.ALIGNMENT_BOTTOM + Bits.ALIGNMENT_LEFT); - public static final Alignment BOTTOM_CENTER = new Alignment( - Bits.ALIGNMENT_BOTTOM + Bits.ALIGNMENT_HORIZONTAL_CENTER); - - private final int bitMask; - - public Alignment(int bitMask) { - this.bitMask = bitMask; - } - - /** - * Returns a bitmask representation of the alignment value. Used internally - * by terminal. - * - * @return the bitmask representation of the alignment value - */ - public int getBitMask() { - return bitMask; - } - - /** - * Checks if component is aligned to the top of the available space. - * - * @return true if aligned top - */ - public boolean isTop() { - return (bitMask & Bits.ALIGNMENT_TOP) == Bits.ALIGNMENT_TOP; - } - - /** - * Checks if component is aligned to the bottom of the available space. - * - * @return true if aligned bottom - */ - public boolean isBottom() { - return (bitMask & Bits.ALIGNMENT_BOTTOM) == Bits.ALIGNMENT_BOTTOM; - } - - /** - * Checks if component is aligned to the left of the available space. - * - * @return true if aligned left - */ - public boolean isLeft() { - return (bitMask & Bits.ALIGNMENT_LEFT) == Bits.ALIGNMENT_LEFT; - } - - /** - * Checks if component is aligned to the right of the available space. - * - * @return true if aligned right - */ - public boolean isRight() { - return (bitMask & Bits.ALIGNMENT_RIGHT) == Bits.ALIGNMENT_RIGHT; - } - - /** - * Checks if component is aligned middle (vertically center) of the - * available space. - * - * @return true if aligned bottom - */ - public boolean isMiddle() { - return (bitMask & Bits.ALIGNMENT_VERTICAL_CENTER) == Bits.ALIGNMENT_VERTICAL_CENTER; - } - - /** - * Checks if component is aligned center (horizontally) of the available - * space. - * - * @return true if aligned center - */ - public boolean isCenter() { - return (bitMask & Bits.ALIGNMENT_HORIZONTAL_CENTER) == Bits.ALIGNMENT_HORIZONTAL_CENTER; - } - - /** - * Returns string representation of vertical alignment. - * - * @return vertical alignment as CSS value - */ - public String getVerticalAlignment() { - if (isBottom()) { - return "bottom"; - } else if (isMiddle()) { - return "middle"; - } - return "top"; - } - - /** - * Returns string representation of horizontal alignment. - * - * @return horizontal alignment as CSS value - */ - public String getHorizontalAlignment() { - if (isRight()) { - return "right"; - } else if (isCenter()) { - return "center"; - } - return "left"; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if ((obj == null) || (obj.getClass() != this.getClass())) { - return false; - } - Alignment a = (Alignment) obj; - return bitMask == a.bitMask; - } - - @Override - public int hashCode() { - return bitMask; - } - - @Override - public String toString() { - return String.valueOf(bitMask); - } - -} diff --git a/src/com/vaadin/ui/Audio.java b/src/com/vaadin/ui/Audio.java deleted file mode 100644 index ac2ee869a6..0000000000 --- a/src/com/vaadin/ui/Audio.java +++ /dev/null @@ -1,55 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import com.vaadin.terminal.Resource; - -/** - * The Audio component translates into an HTML5 <audio> element and as - * such is only supported in browsers that support HTML5 media markup. Browsers - * that do not support HTML5 display the text or HTML set by calling - * {@link #setAltText(String)}. - * - * A flash-player fallback can be implemented by setting HTML content allowed ( - * {@link #setHtmlContentAllowed(boolean)} and calling - * {@link #setAltText(String)} with the flash player markup. An example of flash - * fallback can be found at the Mozilla Developer Network. - * - * Multiple sources can be specified. Which of the sources is used is selected - * by the browser depending on which file formats it supports. See wikipedia for a - * table of formats supported by different browsers. - * - * @author Vaadin Ltd - * @since 6.7.0 - */ -public class Audio extends AbstractMedia { - - public Audio() { - this("", null); - } - - /** - * @param caption - * The caption of the audio component. - */ - public Audio(String caption) { - this(caption, null); - } - - /** - * @param caption - * The caption of the audio component - * @param source - * The audio file to play. - */ - public Audio(String caption, Resource source) { - setCaption(caption); - setSource(source); - setShowControls(true); - } -} diff --git a/src/com/vaadin/ui/Button.java b/src/com/vaadin/ui/Button.java deleted file mode 100644 index 0cb667d527..0000000000 --- a/src/com/vaadin/ui/Button.java +++ /dev/null @@ -1,539 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.lang.reflect.Method; - -import com.vaadin.event.Action; -import com.vaadin.event.FieldEvents; -import com.vaadin.event.FieldEvents.BlurEvent; -import com.vaadin.event.FieldEvents.BlurListener; -import com.vaadin.event.FieldEvents.FocusAndBlurServerRpcImpl; -import com.vaadin.event.FieldEvents.FocusEvent; -import com.vaadin.event.FieldEvents.FocusListener; -import com.vaadin.event.ShortcutAction; -import com.vaadin.event.ShortcutAction.KeyCode; -import com.vaadin.event.ShortcutAction.ModifierKey; -import com.vaadin.event.ShortcutListener; -import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.button.ButtonServerRpc; -import com.vaadin.shared.ui.button.ButtonState; -import com.vaadin.tools.ReflectTools; -import com.vaadin.ui.Component.Focusable; - -/** - * A generic button component. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class Button extends AbstractComponent implements - FieldEvents.BlurNotifier, FieldEvents.FocusNotifier, Focusable, - Action.ShortcutNotifier { - - private ButtonServerRpc rpc = new ButtonServerRpc() { - - @Override - public void click(MouseEventDetails mouseEventDetails) { - fireClick(mouseEventDetails); - } - - @Override - public void disableOnClick() { - // Could be optimized so the button is not repainted because of - // this (client side has already disabled the button) - setEnabled(false); - } - }; - - FocusAndBlurServerRpcImpl focusBlurRpc = new FocusAndBlurServerRpcImpl(this) { - - @Override - protected void fireEvent(Event event) { - Button.this.fireEvent(event); - } - }; - - /** - * Creates a new push button. - */ - public Button() { - registerRpc(rpc); - registerRpc(focusBlurRpc); - } - - /** - * Creates a new push button with the given caption. - * - * @param caption - * the Button caption. - */ - public Button(String caption) { - this(); - setCaption(caption); - } - - /** - * Creates a new push button with a click listener. - * - * @param caption - * the Button caption. - * @param listener - * the Button click listener. - */ - public Button(String caption, ClickListener listener) { - this(caption); - addListener(listener); - } - - /** - * Click event. This event is thrown, when the button is clicked. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public class ClickEvent extends Component.Event { - - private final MouseEventDetails details; - - /** - * New instance of text change event. - * - * @param source - * the Source of the event. - */ - public ClickEvent(Component source) { - super(source); - details = null; - } - - /** - * Constructor with mouse details - * - * @param source - * The source where the click took place - * @param details - * Details about the mouse click - */ - public ClickEvent(Component source, MouseEventDetails details) { - super(source); - this.details = details; - } - - /** - * Gets the Button where the event occurred. - * - * @return the Source of the event. - */ - public Button getButton() { - return (Button) getSource(); - } - - /** - * Returns the mouse position (x coordinate) when the click took place. - * The position is relative to the browser client area. - * - * @return The mouse cursor x position or -1 if unknown - */ - public int getClientX() { - if (null != details) { - return details.getClientX(); - } else { - return -1; - } - } - - /** - * Returns the mouse position (y coordinate) when the click took place. - * The position is relative to the browser client area. - * - * @return The mouse cursor y position or -1 if unknown - */ - public int getClientY() { - if (null != details) { - return details.getClientY(); - } else { - return -1; - } - } - - /** - * Returns the relative mouse position (x coordinate) when the click - * took place. The position is relative to the clicked component. - * - * @return The mouse cursor x position relative to the clicked layout - * component or -1 if no x coordinate available - */ - public int getRelativeX() { - if (null != details) { - return details.getRelativeX(); - } else { - return -1; - } - } - - /** - * Returns the relative mouse position (y coordinate) when the click - * took place. The position is relative to the clicked component. - * - * @return The mouse cursor y position relative to the clicked layout - * component or -1 if no y coordinate available - */ - public int getRelativeY() { - if (null != details) { - return details.getRelativeY(); - } else { - return -1; - } - } - - /** - * Checks if the Alt key was down when the mouse event took place. - * - * @return true if Alt was down when the event occured, false otherwise - * or if unknown - */ - public boolean isAltKey() { - if (null != details) { - return details.isAltKey(); - } else { - return false; - } - } - - /** - * Checks if the Ctrl key was down when the mouse event took place. - * - * @return true if Ctrl was pressed when the event occured, false - * otherwise or if unknown - */ - public boolean isCtrlKey() { - if (null != details) { - return details.isCtrlKey(); - } else { - return false; - } - } - - /** - * Checks if the Meta key was down when the mouse event took place. - * - * @return true if Meta was pressed when the event occured, false - * otherwise or if unknown - */ - public boolean isMetaKey() { - if (null != details) { - return details.isMetaKey(); - } else { - return false; - } - } - - /** - * Checks if the Shift key was down when the mouse event took place. - * - * @return true if Shift was pressed when the event occured, false - * otherwise or if unknown - */ - public boolean isShiftKey() { - if (null != details) { - return details.isShiftKey(); - } else { - return false; - } - } - } - - /** - * Interface for listening for a {@link ClickEvent} fired by a - * {@link Component}. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface ClickListener extends Serializable { - - public static final Method BUTTON_CLICK_METHOD = ReflectTools - .findMethod(ClickListener.class, "buttonClick", - ClickEvent.class); - - /** - * Called when a {@link Button} has been clicked. A reference to the - * button is given by {@link ClickEvent#getButton()}. - * - * @param event - * An event containing information about the click. - */ - public void buttonClick(ClickEvent event); - - } - - /** - * Adds the button click listener. - * - * @param listener - * the Listener to be added. - */ - public void addListener(ClickListener listener) { - addListener(ClickEvent.class, listener, - ClickListener.BUTTON_CLICK_METHOD); - } - - /** - * Removes the button click listener. - * - * @param listener - * the Listener to be removed. - */ - public void removeListener(ClickListener listener) { - removeListener(ClickEvent.class, listener, - ClickListener.BUTTON_CLICK_METHOD); - } - - /** - * Simulates a button click, notifying all server-side listeners. - * - * No action is taken is the button is disabled. - */ - public void click() { - if (isEnabled() && !isReadOnly()) { - fireClick(); - } - } - - /** - * Fires a click event to all listeners without any event details. - * - * In subclasses, override {@link #fireClick(MouseEventDetails)} instead of - * this method. - */ - protected void fireClick() { - fireEvent(new Button.ClickEvent(this)); - } - - /** - * Fires a click event to all listeners. - * - * @param details - * MouseEventDetails from which keyboard modifiers and other - * information about the mouse click can be obtained. If the - * button was clicked by a keyboard event, some of the fields may - * be empty/undefined. - */ - protected void fireClick(MouseEventDetails details) { - fireEvent(new Button.ClickEvent(this, details)); - } - - @Override - public void addListener(BlurListener listener) { - addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, - BlurListener.blurMethod); - } - - @Override - public void removeListener(BlurListener listener) { - removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); - } - - @Override - public void addListener(FocusListener listener) { - addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, - FocusListener.focusMethod); - } - - @Override - public void removeListener(FocusListener listener) { - removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener); - - } - - /* - * Actions - */ - - protected ClickShortcut clickShortcut; - - /** - * Makes it possible to invoke a click on this button by pressing the given - * {@link KeyCode} and (optional) {@link ModifierKey}s.
- * The shortcut is global (bound to the containing Window). - * - * @param keyCode - * the keycode for invoking the shortcut - * @param modifiers - * the (optional) modifiers for invoking the shortcut, null for - * none - */ - public void setClickShortcut(int keyCode, int... modifiers) { - if (clickShortcut != null) { - removeShortcutListener(clickShortcut); - } - clickShortcut = new ClickShortcut(this, keyCode, modifiers); - addShortcutListener(clickShortcut); - getState().setClickShortcutKeyCode(clickShortcut.getKeyCode()); - } - - /** - * Removes the keyboard shortcut previously set with - * {@link #setClickShortcut(int, int...)}. - */ - public void removeClickShortcut() { - if (clickShortcut != null) { - removeShortcutListener(clickShortcut); - clickShortcut = null; - getState().setClickShortcutKeyCode(0); - } - } - - /** - * A {@link ShortcutListener} specifically made to define a keyboard - * shortcut that invokes a click on the given button. - * - */ - public static class ClickShortcut extends ShortcutListener { - protected Button button; - - /** - * Creates a keyboard shortcut for clicking the given button using the - * shorthand notation defined in {@link ShortcutAction}. - * - * @param button - * to be clicked when the shortcut is invoked - * @param shorthandCaption - * the caption with shortcut keycode and modifiers indicated - */ - public ClickShortcut(Button button, String shorthandCaption) { - super(shorthandCaption); - this.button = button; - } - - /** - * Creates a keyboard shortcut for clicking the given button using the - * given {@link KeyCode} and {@link ModifierKey}s. - * - * @param button - * to be clicked when the shortcut is invoked - * @param keyCode - * KeyCode to react to - * @param modifiers - * optional modifiers for shortcut - */ - public ClickShortcut(Button button, int keyCode, int... modifiers) { - super(null, keyCode, modifiers); - this.button = button; - } - - /** - * Creates a keyboard shortcut for clicking the given button using the - * given {@link KeyCode}. - * - * @param button - * to be clicked when the shortcut is invoked - * @param keyCode - * KeyCode to react to - */ - public ClickShortcut(Button button, int keyCode) { - this(button, keyCode, null); - } - - @Override - public void handleAction(Object sender, Object target) { - button.click(); - } - } - - /** - * Determines if a button is automatically disabled when clicked. See - * {@link #setDisableOnClick(boolean)} for details. - * - * @return true if the button is disabled when clicked, false otherwise - */ - public boolean isDisableOnClick() { - return getState().isDisableOnClick(); - } - - /** - * Determines if a button is automatically disabled when clicked. If this is - * set to true the button will be automatically disabled when clicked, - * typically to prevent (accidental) extra clicks on a button. - * - * @param disableOnClick - * true to disable button when it is clicked, false otherwise - */ - public void setDisableOnClick(boolean disableOnClick) { - getState().setDisableOnClick(disableOnClick); - requestRepaint(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component.Focusable#getTabIndex() - */ - @Override - public int getTabIndex() { - return getState().getTabIndex(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.Component.Focusable#setTabIndex(int) - */ - @Override - public void setTabIndex(int tabIndex) { - getState().setTabIndex(tabIndex); - requestRepaint(); - } - - @Override - public void focus() { - // Overridden only to make public - super.focus(); - } - - @Override - public ButtonState getState() { - return (ButtonState) super.getState(); - } - - /** - * Set whether the caption text is rendered as HTML or not. You might need - * to retheme button to allow higher content than the original text style. - * - * If set to true, the captions are passed to the browser as html and the - * developer is responsible for ensuring no harmful html is used. If set to - * false, the content is passed to the browser as plain text. - * - * @param htmlContentAllowed - * true if caption is rendered as HTML, - * false otherwise - */ - public void setHtmlContentAllowed(boolean htmlContentAllowed) { - if (getState().isHtmlContentAllowed() != htmlContentAllowed) { - getState().setHtmlContentAllowed(htmlContentAllowed); - requestRepaint(); - } - } - - /** - * Return HTML rendering setting - * - * @return true if the caption text is to be rendered as HTML, - * false otherwise - */ - public boolean isHtmlContentAllowed() { - return getState().isHtmlContentAllowed(); - } - -} diff --git a/src/com/vaadin/ui/CheckBox.java b/src/com/vaadin/ui/CheckBox.java deleted file mode 100644 index 30ac9b4626..0000000000 --- a/src/com/vaadin/ui/CheckBox.java +++ /dev/null @@ -1,141 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import com.vaadin.data.Property; -import com.vaadin.event.FieldEvents.BlurEvent; -import com.vaadin.event.FieldEvents.BlurListener; -import com.vaadin.event.FieldEvents.FocusAndBlurServerRpcImpl; -import com.vaadin.event.FieldEvents.FocusEvent; -import com.vaadin.event.FieldEvents.FocusListener; -import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.checkbox.CheckBoxServerRpc; -import com.vaadin.shared.ui.checkbox.CheckBoxState; - -public class CheckBox extends AbstractField { - - private CheckBoxServerRpc rpc = new CheckBoxServerRpc() { - - @Override - public void setChecked(boolean checked, - MouseEventDetails mouseEventDetails) { - if (isReadOnly()) { - return; - } - - final Boolean oldValue = getValue(); - final Boolean newValue = checked; - - if (!newValue.equals(oldValue)) { - // The event is only sent if the switch state is changed - setValue(newValue); - } - - } - }; - - FocusAndBlurServerRpcImpl focusBlurRpc = new FocusAndBlurServerRpcImpl(this) { - @Override - protected void fireEvent(Event event) { - CheckBox.this.fireEvent(event); - } - }; - - /** - * Creates a new checkbox. - */ - public CheckBox() { - registerRpc(rpc); - registerRpc(focusBlurRpc); - setValue(Boolean.FALSE); - } - - /** - * Creates a new checkbox with a set caption. - * - * @param caption - * the Checkbox caption. - */ - public CheckBox(String caption) { - this(); - setCaption(caption); - } - - /** - * Creates a new checkbox with a caption and a set initial state. - * - * @param caption - * the caption of the checkbox - * @param initialState - * the initial state of the checkbox - */ - public CheckBox(String caption, boolean initialState) { - this(caption); - setValue(initialState); - } - - /** - * Creates a new checkbox that is connected to a boolean property. - * - * @param state - * the Initial state of the switch-button. - * @param dataSource - */ - public CheckBox(String caption, Property dataSource) { - this(caption); - setPropertyDataSource(dataSource); - } - - @Override - public Class getType() { - return Boolean.class; - } - - @Override - public CheckBoxState getState() { - return (CheckBoxState) super.getState(); - } - - @Override - protected void setInternalValue(Boolean newValue) { - super.setInternalValue(newValue); - if (newValue == null) { - newValue = false; - } - getState().setChecked(newValue); - } - - public void addListener(BlurListener listener) { - addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, - BlurListener.blurMethod); - } - - public void removeListener(BlurListener listener) { - removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); - } - - public void addListener(FocusListener listener) { - addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, - FocusListener.focusMethod); - } - - public void removeListener(FocusListener listener) { - removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener); - } - - /** - * Get the boolean value of the button state. - * - * @return True iff the button is pressed down or checked. - * - * @deprecated Use {@link #getValue()} instead and, if needed, handle null - * values. - */ - @Deprecated - public boolean booleanValue() { - Boolean value = getValue(); - return (null == value) ? false : value.booleanValue(); - } -} diff --git a/src/com/vaadin/ui/ComboBox.java b/src/com/vaadin/ui/ComboBox.java deleted file mode 100644 index 6286dad124..0000000000 --- a/src/com/vaadin/ui/ComboBox.java +++ /dev/null @@ -1,116 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.util.Collection; - -import com.vaadin.data.Container; -import com.vaadin.terminal.PaintException; -import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.gwt.client.ui.combobox.VFilterSelect; - -/** - * A filtering dropdown single-select. Suitable for newItemsAllowed, but it's - * turned of by default to avoid mistakes. Items are filtered based on user - * input, and loaded dynamically ("lazy-loading") from the server. You can turn - * on newItemsAllowed and change filtering mode (and also turn it off), but you - * can not turn on multi-select mode. - * - */ -@SuppressWarnings("serial") -public class ComboBox extends Select { - - private String inputPrompt = null; - - /** - * If text input is not allowed, the ComboBox behaves like a pretty - * NativeSelect - the user can not enter any text and clicking the text - * field opens the drop down with options - */ - private boolean textInputAllowed = true; - - public ComboBox() { - setNewItemsAllowed(false); - } - - public ComboBox(String caption, Collection options) { - super(caption, options); - setNewItemsAllowed(false); - } - - public ComboBox(String caption, Container dataSource) { - super(caption, dataSource); - setNewItemsAllowed(false); - } - - public ComboBox(String caption) { - super(caption); - setNewItemsAllowed(false); - } - - /** - * Gets the current input prompt. - * - * @see #setInputPrompt(String) - * @return the current input prompt, or null if not enabled - */ - public String getInputPrompt() { - return inputPrompt; - } - - /** - * Sets the input prompt - a textual prompt that is displayed when the - * select would otherwise be empty, to prompt the user for input. - * - * @param inputPrompt - * the desired input prompt, or null to disable - */ - public void setInputPrompt(String inputPrompt) { - this.inputPrompt = inputPrompt; - requestRepaint(); - } - - @Override - public void paintContent(PaintTarget target) throws PaintException { - if (inputPrompt != null) { - target.addAttribute("prompt", inputPrompt); - } - super.paintContent(target); - - if (!textInputAllowed) { - target.addAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT, true); - } - } - - /** - * Sets whether it is possible to input text into the field or whether the - * field area of the component is just used to show what is selected. By - * disabling text input, the comboBox will work in the same way as a - * {@link NativeSelect} - * - * @see #isTextInputAllowed() - * - * @param textInputAllowed - * true to allow entering text, false to just show the current - * selection - */ - public void setTextInputAllowed(boolean textInputAllowed) { - this.textInputAllowed = textInputAllowed; - requestRepaint(); - } - - /** - * Returns true if the user can enter text into the field to either filter - * the selections or enter a new value if {@link #isNewItemsAllowed()} - * returns true. If text input is disabled, the comboBox will work in the - * same way as a {@link NativeSelect} - * - * @return - */ - public boolean isTextInputAllowed() { - return textInputAllowed; - } - -} diff --git a/src/com/vaadin/ui/Component.java b/src/com/vaadin/ui/Component.java deleted file mode 100644 index a2c257ab68..0000000000 --- a/src/com/vaadin/ui/Component.java +++ /dev/null @@ -1,1047 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -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.shared.ComponentState; -import com.vaadin.terminal.ErrorMessage; -import com.vaadin.terminal.Resource; -import com.vaadin.terminal.Sizeable; -import com.vaadin.terminal.VariableOwner; -import com.vaadin.terminal.gwt.server.ClientConnector; - -/** - * {@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. - * @version - * @VERSION@ - * @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 a style name to component. 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.terminal.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 Root the component is attached to. - * - *

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

- * - * @return the Root of the component or null if it is not - * attached to a Root - */ - @Override - public Root getRoot(); - - /** - * 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 #getRoot()}, 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 Root#componentAttached(Component)} to let - * the Root 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(); - - /** - * Returns the current shared state bean for the component. The state (or - * changes to it) is communicated from the server to the client. - * - * Subclasses can use a more specific return type for this method. - * - * @return The state object for the component - * - * @since 7.0 - */ - @Override - public ComponentState getState(); - - /** - * Called before the shared state is sent to the client. Gives the component - * an opportunity to set computed/dynamic state values e.g. state values - * that depend on other component features. - *

- * This method must not alter the component hierarchy in any way. - *

- * - * @since 7.0 - */ - public void updateState(); - - /** - * 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 setDebugId(String id); - - /** - * Get's currently set debug identifier - * - * @return current debug id, null if not set - */ - public String getDebugId(); - - /* 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); - - } - -} diff --git a/src/com/vaadin/ui/ComponentContainer.java b/src/com/vaadin/ui/ComponentContainer.java deleted file mode 100644 index 8182d54b56..0000000000 --- a/src/com/vaadin/ui/ComponentContainer.java +++ /dev/null @@ -1,222 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; - -/** - * Extension to the {@link Component} interface which adds to it the capacity to - * contain other components. All UI elements that can have child elements - * implement this interface. - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -public interface ComponentContainer extends HasComponents { - - /** - * Adds the component into this container. - * - * @param c - * the component to be added. - */ - public void addComponent(Component c); - - /** - * Removes the component from this container. - * - * @param c - * the component to be removed. - */ - public void removeComponent(Component c); - - /** - * Removes all components from this container. - */ - public void removeAllComponents(); - - /** - * Replaces the component in the container with another one without changing - * position. - * - *

- * This method replaces component with another one is such way that the new - * component overtakes the position of the old component. If the old - * component is not in the container, the new component is added to the - * container. If the both component are already in the container, their - * positions are swapped. Component attach and detach events should be taken - * care as with add and remove. - *

- * - * @param oldComponent - * the old component that will be replaced. - * @param newComponent - * the new component to be replaced. - */ - public void replaceComponent(Component oldComponent, Component newComponent); - - /** - * Gets the number of children this {@link ComponentContainer} has. This - * must be symmetric with what {@link #getComponentIterator()} returns. - * - * @return The number of child components this container has. - * @since 7.0.0 - */ - public int getComponentCount(); - - /** - * Moves all components from an another container into this container. The - * components are removed from source. - * - * @param source - * the container which contains the components that are to be - * moved to this container. - */ - public void moveComponentsFrom(ComponentContainer source); - - /** - * Listens the component attach events. - * - * @param listener - * the listener to add. - */ - public void addListener(ComponentAttachListener listener); - - /** - * Stops the listening component attach events. - * - * @param listener - * the listener to removed. - */ - public void removeListener(ComponentAttachListener listener); - - /** - * Listens the component detach events. - */ - public void addListener(ComponentDetachListener listener); - - /** - * Stops the listening component detach events. - */ - public void removeListener(ComponentDetachListener listener); - - /** - * Component attach listener interface. - */ - public interface ComponentAttachListener extends Serializable { - - /** - * A new component is attached to container. - * - * @param event - * the component attach event. - */ - public void componentAttachedToContainer(ComponentAttachEvent event); - } - - /** - * Component detach listener interface. - */ - public interface ComponentDetachListener extends Serializable { - - /** - * A component has been detached from container. - * - * @param event - * the component detach event. - */ - public void componentDetachedFromContainer(ComponentDetachEvent event); - } - - /** - * Component attach event sent when a component is attached to container. - */ - @SuppressWarnings("serial") - public class ComponentAttachEvent extends Component.Event { - - private final Component component; - - /** - * Creates a new attach event. - * - * @param container - * the component container the component has been detached - * to. - * @param attachedComponent - * the component that has been attached. - */ - public ComponentAttachEvent(ComponentContainer container, - Component attachedComponent) { - super(container); - component = attachedComponent; - } - - /** - * Gets the component container. - * - * @param the - * component container. - */ - public ComponentContainer getContainer() { - return (ComponentContainer) getSource(); - } - - /** - * Gets the attached component. - * - * @param the - * attach component. - */ - public Component getAttachedComponent() { - return component; - } - } - - /** - * Component detach event sent when a component is detached from container. - */ - @SuppressWarnings("serial") - public class ComponentDetachEvent extends Component.Event { - - private final Component component; - - /** - * Creates a new detach event. - * - * @param container - * the component container the component has been detached - * from. - * @param detachedComponent - * the component that has been detached. - */ - public ComponentDetachEvent(ComponentContainer container, - Component detachedComponent) { - super(container); - component = detachedComponent; - } - - /** - * Gets the component container. - * - * @param the - * component container. - */ - public ComponentContainer getContainer() { - return (ComponentContainer) getSource(); - } - - /** - * Gets the detached component. - * - * @return the detached component. - */ - public Component getDetachedComponent() { - return component; - } - } - -} diff --git a/src/com/vaadin/ui/ConnectorTracker.java b/src/com/vaadin/ui/ConnectorTracker.java deleted file mode 100644 index e3d1bf86db..0000000000 --- a/src/com/vaadin/ui/ConnectorTracker.java +++ /dev/null @@ -1,320 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -import java.io.Serializable; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.vaadin.terminal.AbstractClientConnector; -import com.vaadin.terminal.gwt.client.ServerConnector; -import com.vaadin.terminal.gwt.server.ClientConnector; - -/** - * A class which takes care of book keeping of {@link ClientConnector}s for a - * Root. - *

- * Provides {@link #getConnector(String)} which can be used to lookup a - * connector from its id. This is for framework use only and should not be - * needed in applications. - *

- *

- * Tracks which {@link ClientConnector}s are dirty so they can be updated to the - * client when the following response is sent. A connector is dirty when an - * operation has been performed on it on the server and as a result of this - * operation new information needs to be sent to its {@link ServerConnector}. - *

- * - * @author Vaadin Ltd - * @version @VERSION@ - * @since 7.0.0 - * - */ -public class ConnectorTracker implements Serializable { - - private final HashMap connectorIdToConnector = new HashMap(); - private Set dirtyConnectors = new HashSet(); - - private Root root; - - /** - * Gets a logger for this class - * - * @return A logger instance for logging within this class - * - */ - public static Logger getLogger() { - return Logger.getLogger(ConnectorTracker.class.getName()); - } - - /** - * Creates a new ConnectorTracker for the given root. A tracker is always - * attached to a root and the root cannot be changed during the lifetime of - * a {@link ConnectorTracker}. - * - * @param root - * The root to attach to. Cannot be null. - */ - public ConnectorTracker(Root root) { - this.root = root; - } - - /** - * Register the given connector. - *

- * The lookup method {@link #getConnector(String)} only returns registered - * connectors. - *

- * - * @param connector - * The connector to register. - */ - public void registerConnector(ClientConnector connector) { - String connectorId = connector.getConnectorId(); - ClientConnector previouslyRegistered = connectorIdToConnector - .get(connectorId); - if (previouslyRegistered == null) { - connectorIdToConnector.put(connectorId, connector); - getLogger().fine( - "Registered " + connector.getClass().getSimpleName() + " (" - + connectorId + ")"); - } else if (previouslyRegistered != connector) { - throw new RuntimeException("A connector with id " + connectorId - + " is already registered!"); - } else { - getLogger().warning( - "An already registered connector was registered again: " - + connector.getClass().getSimpleName() + " (" - + connectorId + ")"); - } - - } - - /** - * Unregister the given connector. - * - *

- * The lookup method {@link #getConnector(String)} only returns registered - * connectors. - *

- * - * @param connector - * The connector to unregister - */ - public void unregisterConnector(ClientConnector connector) { - String connectorId = connector.getConnectorId(); - if (!connectorIdToConnector.containsKey(connectorId)) { - getLogger().warning( - "Tried to unregister " - + connector.getClass().getSimpleName() + " (" - + connectorId + ") which is not registered"); - return; - } - if (connectorIdToConnector.get(connectorId) != connector) { - throw new RuntimeException("The given connector with id " - + connectorId - + " is not the one that was registered for that id"); - } - - getLogger().fine( - "Unregistered " + connector.getClass().getSimpleName() + " (" - + connectorId + ")"); - connectorIdToConnector.remove(connectorId); - } - - /** - * Gets a connector by its id. - * - * @param connectorId - * The connector id to look for - * @return The connector with the given id or null if no connector has the - * given id - */ - public ClientConnector getConnector(String connectorId) { - return connectorIdToConnector.get(connectorId); - } - - /** - * Cleans the connector map from all connectors that are no longer attached - * to the application. This should only be called by the framework. - */ - public void cleanConnectorMap() { - // remove detached components from paintableIdMap so they - // can be GC'ed - Iterator iterator = connectorIdToConnector.keySet().iterator(); - - while (iterator.hasNext()) { - String connectorId = iterator.next(); - ClientConnector connector = connectorIdToConnector.get(connectorId); - if (getRootForConnector(connector) != root) { - // If connector is no longer part of this root, - // remove it from the map. If it is re-attached to the - // application at some point it will be re-added through - // registerConnector(connector) - - // This code should never be called as cleanup should take place - // in detach() - getLogger() - .warning( - "cleanConnectorMap unregistered connector " - + getConnectorAndParentInfo(connector) - + "). This should have been done when the connector was detached."); - iterator.remove(); - } - } - - } - - /** - * Finds the root that the connector is attached to. - * - * @param connector - * The connector to lookup - * @return The root the connector is attached to or null if it is not - * attached to any root. - */ - private Root getRootForConnector(ClientConnector connector) { - if (connector == null) { - return null; - } - if (connector instanceof Component) { - return ((Component) connector).getRoot(); - } - - return getRootForConnector(connector.getParent()); - } - - /** - * Mark the connector as dirty. - * - * @see #getDirtyConnectors() - * - * @param connector - * The connector that should be marked clean. - */ - public void markDirty(ClientConnector connector) { - if (getLogger().isLoggable(Level.FINE)) { - if (!dirtyConnectors.contains(connector)) { - getLogger().fine( - getConnectorAndParentInfo(connector) + " " - + "is now dirty"); - } - } - - dirtyConnectors.add(connector); - } - - /** - * Mark the connector as clean. - * - * @param connector - * The connector that should be marked clean. - */ - public void markClean(ClientConnector connector) { - if (getLogger().isLoggable(Level.FINE)) { - if (dirtyConnectors.contains(connector)) { - getLogger().fine( - getConnectorAndParentInfo(connector) + " " - + "is no longer dirty"); - } - } - - dirtyConnectors.remove(connector); - } - - /** - * Returns {@link #getConnectorString(ClientConnector)} for the connector - * and its parent (if it has a parent). - * - * @param connector - * The connector - * @return A string describing the connector and its parent - */ - private String getConnectorAndParentInfo(ClientConnector connector) { - String message = getConnectorString(connector); - if (connector.getParent() != null) { - message += " (parent: " + getConnectorString(connector.getParent()) - + ")"; - } - return message; - } - - /** - * Returns a string with the connector name and id. Useful mostly for - * debugging and logging. - * - * @param connector - * The connector - * @return A string that describes the connector - */ - private String getConnectorString(ClientConnector connector) { - if (connector == null) { - return "(null)"; - } - - String connectorId; - try { - connectorId = connector.getConnectorId(); - } catch (RuntimeException e) { - // This happens if the connector is not attached to the application. - // SHOULD not happen in this case but theoretically can. - connectorId = "@" + Integer.toHexString(connector.hashCode()); - } - return connector.getClass().getName() + "(" + connectorId + ")"; - } - - /** - * Mark all connectors in this root as dirty. - */ - public void markAllConnectorsDirty() { - markConnectorsDirtyRecursively(root); - getLogger().fine("All connectors are now dirty"); - } - - /** - * Mark all connectors in this root as clean. - */ - public void markAllConnectorsClean() { - dirtyConnectors.clear(); - getLogger().fine("All connectors are now clean"); - } - - /** - * Marks all visible connectors dirty, starting from the given connector and - * going downwards in the hierarchy. - * - * @param c - * The component to start iterating downwards from - */ - private void markConnectorsDirtyRecursively(ClientConnector c) { - if (c instanceof Component && !((Component) c).isVisible()) { - return; - } - markDirty(c); - for (ClientConnector child : AbstractClientConnector - .getAllChildrenIterable(c)) { - markConnectorsDirtyRecursively(child); - } - } - - /** - * Returns a collection of all connectors which have been marked as dirty. - *

- * The state and pending RPC calls for dirty connectors are sent to the - * client in the following request. - *

- * - * @return A collection of all dirty connectors for this root. This list may - * contain invisible connectors. - */ - public Collection getDirtyConnectors() { - return dirtyConnectors; - } - -} diff --git a/src/com/vaadin/ui/CssLayout.java b/src/com/vaadin/ui/CssLayout.java deleted file mode 100644 index 356f0a3843..0000000000 --- a/src/com/vaadin/ui/CssLayout.java +++ /dev/null @@ -1,308 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -import java.util.Iterator; -import java.util.LinkedList; - -import com.vaadin.event.LayoutEvents.LayoutClickEvent; -import com.vaadin.event.LayoutEvents.LayoutClickListener; -import com.vaadin.event.LayoutEvents.LayoutClickNotifier; -import com.vaadin.shared.Connector; -import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.csslayout.CssLayoutServerRpc; -import com.vaadin.shared.ui.csslayout.CssLayoutState; -import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler; - -/** - * CssLayout is a layout component that can be used in browser environment only. - * It simply renders components and their captions into a same div element. - * Component layout can then be adjusted with css. - *

- * In comparison to {@link HorizontalLayout} and {@link VerticalLayout} - *

    - *
  • rather similar server side api - *
  • no spacing, alignment or expand ratios - *
  • much simpler DOM that can be styled by skilled web developer - *
  • no abstraction of browser differences (developer must ensure that the - * result works properly on each browser) - *
  • different kind of handling for relative sizes (that are set from server - * side) (*) - *
  • noticeably faster rendering time in some situations as we rely more on - * the browser's rendering engine. - *
- *

- * With {@link CustomLayout} one can often achieve similar results (good looking - * layouts with web technologies), but with CustomLayout developer needs to work - * with fixed templates. - *

- * By extending CssLayout one can also inject some css rules straight to child - * components using {@link #getCss(Component)}. - * - *

- * (*) Relative sizes (set from server side) are treated bit differently than in - * other layouts in Vaadin. In cssLayout the size is calculated relatively to - * CSS layouts content area which is pretty much as in html and css. In other - * layouts the size of component is calculated relatively to the "slot" given by - * layout. - *

- * Also note that client side framework in Vaadin modifies inline style - * properties width and height. This happens on each update to component. If one - * wants to set component sizes with CSS, component must have undefined size on - * server side (which is not the default for all components) and the size must - * be defined with class styles - not by directly injecting width and height. - * - * @since 6.1 brought in from "FastLayouts" incubator project - * - */ -public class CssLayout extends AbstractLayout implements LayoutClickNotifier { - - private CssLayoutServerRpc rpc = new CssLayoutServerRpc() { - - @Override - public void layoutClick(MouseEventDetails mouseDetails, - Connector clickedConnector) { - fireEvent(LayoutClickEvent.createEvent(CssLayout.this, - mouseDetails, clickedConnector)); - } - }; - /** - * Custom layout slots containing the components. - */ - protected LinkedList components = new LinkedList(); - - public CssLayout() { - registerRpc(rpc); - } - - /** - * Add a component into this container. The component is added to the right - * or under the previous component. - * - * @param c - * the component to be added. - */ - @Override - public void addComponent(Component c) { - // Add to components before calling super.addComponent - // so that it is available to AttachListeners - components.add(c); - try { - super.addComponent(c); - requestRepaint(); - } catch (IllegalArgumentException e) { - components.remove(c); - throw e; - } - } - - /** - * Adds a component into this container. The component is added to the left - * or on top of the other components. - * - * @param c - * the component to be added. - */ - public void addComponentAsFirst(Component c) { - // If c is already in this, we must remove it before proceeding - // see ticket #7668 - if (c.getParent() == this) { - removeComponent(c); - } - components.addFirst(c); - try { - super.addComponent(c); - requestRepaint(); - } catch (IllegalArgumentException e) { - components.remove(c); - throw e; - } - } - - /** - * Adds a component into indexed position in this container. - * - * @param c - * the component to be added. - * @param index - * the index of the component position. The components currently - * in and after the position are shifted forwards. - */ - public void addComponent(Component c, int index) { - // If c is already in this, we must remove it before proceeding - // see ticket #7668 - if (c.getParent() == this) { - // When c is removed, all components after it are shifted down - if (index > getComponentIndex(c)) { - index--; - } - removeComponent(c); - } - components.add(index, c); - try { - super.addComponent(c); - requestRepaint(); - } catch (IllegalArgumentException e) { - components.remove(c); - throw e; - } - } - - /** - * Removes the component from this container. - * - * @param c - * the component to be removed. - */ - @Override - public void removeComponent(Component c) { - components.remove(c); - super.removeComponent(c); - requestRepaint(); - } - - /** - * Gets the component container iterator for going trough all the components - * in the container. - * - * @return the Iterator of the components inside the container. - */ - @Override - public Iterator getComponentIterator() { - return components.iterator(); - } - - /** - * Gets the number of contained components. Consistent with the iterator - * returned by {@link #getComponentIterator()}. - * - * @return the number of contained components - */ - @Override - public int getComponentCount() { - return components.size(); - } - - @Override - public void updateState() { - super.updateState(); - getState().getChildCss().clear(); - for (Iterator ci = getComponentIterator(); ci.hasNext();) { - Component child = ci.next(); - String componentCssString = getCss(child); - if (componentCssString != null) { - getState().getChildCss().put(child, componentCssString); - } - - } - } - - @Override - public CssLayoutState getState() { - return (CssLayoutState) super.getState(); - } - - /** - * Returns styles to be applied to given component. Override this method to - * inject custom style rules to components. - * - *

- * Note that styles are injected over previous styles before actual child - * rendering. Previous styles are not cleared, but overridden. - * - *

- * Note that one most often achieves better code style, by separating - * styling to theme (with custom theme and {@link #addStyleName(String)}. - * With own custom styles it is also very easy to break browser - * compatibility. - * - * @param c - * the component - * @return css rules to be applied to component - */ - protected String getCss(Component c) { - return null; - } - - /* Documented in superclass */ - @Override - public void replaceComponent(Component oldComponent, Component newComponent) { - - // Gets the locations - int oldLocation = -1; - int newLocation = -1; - int location = 0; - for (final Iterator i = components.iterator(); i.hasNext();) { - final Component component = i.next(); - - if (component == oldComponent) { - oldLocation = location; - } - if (component == newComponent) { - newLocation = location; - } - - location++; - } - - if (oldLocation == -1) { - addComponent(newComponent); - } else if (newLocation == -1) { - removeComponent(oldComponent); - addComponent(newComponent, oldLocation); - } else { - if (oldLocation > newLocation) { - components.remove(oldComponent); - components.add(newLocation, oldComponent); - components.remove(newComponent); - components.add(oldLocation, newComponent); - } else { - components.remove(newComponent); - components.add(oldLocation, newComponent); - components.remove(oldComponent); - components.add(newLocation, oldComponent); - } - - requestRepaint(); - } - } - - @Override - public void addListener(LayoutClickListener listener) { - addListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER, - LayoutClickEvent.class, listener, - LayoutClickListener.clickMethod); - } - - @Override - public void removeListener(LayoutClickListener listener) { - removeListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER, - LayoutClickEvent.class, listener); - } - - /** - * Returns the index of the given component. - * - * @param component - * The component to look up. - * @return The index of the component or -1 if the component is not a child. - */ - public int getComponentIndex(Component component) { - return components.indexOf(component); - } - - /** - * Returns the component at the given position. - * - * @param index - * The position of the component. - * @return The component at the given index. - * @throws IndexOutOfBoundsException - * If the index is out of range. - */ - public Component getComponent(int index) throws IndexOutOfBoundsException { - return components.get(index); - } - -} diff --git a/src/com/vaadin/ui/CustomComponent.java b/src/com/vaadin/ui/CustomComponent.java deleted file mode 100644 index 40b5dcd636..0000000000 --- a/src/com/vaadin/ui/CustomComponent.java +++ /dev/null @@ -1,189 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.util.Iterator; - -/** - * Custom component provides simple implementation of Component interface for - * creation of new UI components by composition of existing components. - *

- * The component is used by inheriting the CustomComponent class and setting - * composite root inside the Custom component. The composite root itself can - * contain more components, but their interfaces are hidden from the users. - *

- * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class CustomComponent extends AbstractComponentContainer { - - /** - * The root component implementing the custom component. - */ - private Component root = null; - - /** - * Constructs a new custom component. - * - *

- * The component is implemented by wrapping the methods of the composition - * root component given as parameter. The composition root must be set - * before the component can be used. - *

- */ - public CustomComponent() { - // expand horizontally by default - setWidth(100, UNITS_PERCENTAGE); - } - - /** - * Constructs a new custom component. - * - *

- * The component is implemented by wrapping the methods of the composition - * root component given as parameter. The composition root must not be null - * and can not be changed after the composition. - *

- * - * @param compositionRoot - * the root of the composition component tree. - */ - public CustomComponent(Component compositionRoot) { - this(); - setCompositionRoot(compositionRoot); - } - - /** - * Returns the composition root. - * - * @return the Component Composition root. - */ - protected Component getCompositionRoot() { - return root; - } - - /** - * Sets the compositions root. - *

- * The composition root must be set to non-null value before the component - * can be used. The composition root can only be set once. - *

- * - * @param compositionRoot - * the root of the composition component tree. - */ - protected void setCompositionRoot(Component compositionRoot) { - if (compositionRoot != root) { - if (root != null) { - // remove old component - super.removeComponent(root); - } - if (compositionRoot != null) { - // set new component - super.addComponent(compositionRoot); - } - root = compositionRoot; - requestRepaint(); - } - } - - /* Basic component features ------------------------------------------ */ - - private class ComponentIterator implements Iterator, - Serializable { - boolean first = getCompositionRoot() != null; - - @Override - public boolean hasNext() { - return first; - } - - @Override - public Component next() { - first = false; - return root; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - - @Override - public Iterator getComponentIterator() { - return new ComponentIterator(); - } - - /** - * Gets the number of contained components. Consistent with the iterator - * returned by {@link #getComponentIterator()}. - * - * @return the number of contained components (zero or one) - */ - @Override - public int getComponentCount() { - return (root != null ? 1 : 0); - } - - /** - * This method is not supported by CustomComponent. - * - * @see com.vaadin.ui.ComponentContainer#replaceComponent(com.vaadin.ui.Component, - * com.vaadin.ui.Component) - */ - @Override - public void replaceComponent(Component oldComponent, Component newComponent) { - throw new UnsupportedOperationException(); - } - - /** - * This method is not supported by CustomComponent. Use - * {@link CustomComponent#setCompositionRoot(Component)} to set - * CustomComponents "child". - * - * @see com.vaadin.ui.AbstractComponentContainer#addComponent(com.vaadin.ui.Component) - */ - @Override - public void addComponent(Component c) { - throw new UnsupportedOperationException(); - } - - /** - * This method is not supported by CustomComponent. - * - * @see com.vaadin.ui.AbstractComponentContainer#moveComponentsFrom(com.vaadin.ui.ComponentContainer) - */ - @Override - public void moveComponentsFrom(ComponentContainer source) { - throw new UnsupportedOperationException(); - } - - /** - * This method is not supported by CustomComponent. - * - * @see com.vaadin.ui.AbstractComponentContainer#removeAllComponents() - */ - @Override - public void removeAllComponents() { - throw new UnsupportedOperationException(); - } - - /** - * This method is not supported by CustomComponent. - * - * @see com.vaadin.ui.AbstractComponentContainer#removeComponent(com.vaadin.ui.Component) - */ - @Override - public void removeComponent(Component c) { - throw new UnsupportedOperationException(); - } - -} diff --git a/src/com/vaadin/ui/CustomField.java b/src/com/vaadin/ui/CustomField.java deleted file mode 100644 index ab3797a58c..0000000000 --- a/src/com/vaadin/ui/CustomField.java +++ /dev/null @@ -1,237 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.Iterator; - -import com.vaadin.data.Property; - -/** - * A {@link Field} whose UI content can be constructed by the user, enabling the - * creation of e.g. form fields by composing Vaadin components. Customization of - * both the visual presentation and the logic of the field is possible. - * - * Subclasses must implement {@link #getType()} and {@link #initContent()}. - * - * Most custom fields can simply compose a user interface that calls the methods - * {@link #setInternalValue(Object)} and {@link #getInternalValue()} when - * necessary. - * - * It is also possible to override {@link #validate()}, - * {@link #setInternalValue(Object)}, {@link #commit()}, - * {@link #setPropertyDataSource(Property)}, {@link #isEmpty()} and other logic - * of the field. Methods overriding {@link #setInternalValue(Object)} should - * also call the corresponding superclass method. - * - * @param - * field value type - * - * @since 7.0 - */ -public abstract class CustomField extends AbstractField implements - ComponentContainer { - - /** - * The root component implementing the custom component. - */ - private Component root = null; - - /** - * Constructs a new custom field. - * - *

- * The component is implemented by wrapping the methods of the composition - * root component given as parameter. The composition root must be set - * before the component can be used. - *

- */ - public CustomField() { - // expand horizontally by default - setWidth(100, Unit.PERCENTAGE); - } - - /** - * Constructs the content and notifies it that the {@link CustomField} is - * attached to a window. - * - * @see com.vaadin.ui.Component#attach() - */ - @Override - public void attach() { - // First call super attach to notify all children (none if content has - // not yet been created) - super.attach(); - - // If the content has not yet been created, we create and attach it at - // this point. - if (root == null) { - // Ensure content is created and its parent is set. - // The getContent() call creates the content and attaches the - // content - fireComponentAttachEvent(getContent()); - } - } - - /** - * Returns the content (UI) of the custom component. - * - * @return Component - */ - protected Component getContent() { - if (null == root) { - root = initContent(); - root.setParent(this); - } - return root; - } - - /** - * Create the content component or layout for the field. Subclasses of - * {@link CustomField} should implement this method. - * - * Note that this method is called when the CustomField is attached to a - * layout or when {@link #getContent()} is called explicitly for the first - * time. It is only called once for a {@link CustomField}. - * - * @return {@link Component} representing the UI of the CustomField - */ - protected abstract Component initContent(); - - // Size related methods - // TODO might not be necessary to override but following the pattern from - // AbstractComponentContainer - - @Override - public void setHeight(float height, Unit unit) { - super.setHeight(height, unit); - requestRepaintAll(); - } - - @Override - public void setWidth(float height, Unit unit) { - super.setWidth(height, unit); - requestRepaintAll(); - } - - // ComponentContainer methods - - private class ComponentIterator implements Iterator, - Serializable { - boolean first = (root != null); - - @Override - public boolean hasNext() { - return first; - } - - @Override - public Component next() { - first = false; - return getContent(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } - - @Override - public Iterator getComponentIterator() { - return new ComponentIterator(); - } - - @Override - public Iterator iterator() { - return getComponentIterator(); - } - - @Override - public int getComponentCount() { - return (null != getContent()) ? 1 : 0; - } - - /** - * Fires the component attached event. This should be called by the - * addComponent methods after the component have been added to this - * container. - * - * @param component - * the component that has been added to this container. - */ - protected void fireComponentAttachEvent(Component component) { - fireEvent(new ComponentAttachEvent(this, component)); - } - - // TODO remove these methods when ComponentContainer interface is cleaned up - - @Override - public void addComponent(Component c) { - throw new UnsupportedOperationException(); - } - - @Override - public void removeComponent(Component c) { - throw new UnsupportedOperationException(); - } - - @Override - public void removeAllComponents() { - throw new UnsupportedOperationException(); - } - - @Override - public void replaceComponent(Component oldComponent, Component newComponent) { - throw new UnsupportedOperationException(); - } - - @Override - public void moveComponentsFrom(ComponentContainer source) { - throw new UnsupportedOperationException(); - } - - private static final Method COMPONENT_ATTACHED_METHOD; - - static { - try { - COMPONENT_ATTACHED_METHOD = ComponentAttachListener.class - .getDeclaredMethod("componentAttachedToContainer", - new Class[] { ComponentAttachEvent.class }); - } catch (final java.lang.NoSuchMethodException e) { - // This should never happen - throw new java.lang.RuntimeException( - "Internal error finding methods in CustomField"); - } - } - - @Override - public void addListener(ComponentAttachListener listener) { - addListener(ComponentContainer.ComponentAttachEvent.class, listener, - COMPONENT_ATTACHED_METHOD); - } - - @Override - public void removeListener(ComponentAttachListener listener) { - removeListener(ComponentContainer.ComponentAttachEvent.class, listener, - COMPONENT_ATTACHED_METHOD); - } - - @Override - public void addListener(ComponentDetachListener listener) { - // content never detached - } - - @Override - public void removeListener(ComponentDetachListener listener) { - // content never detached - } - - @Override - public boolean isComponentVisible(Component childComponent) { - return true; - } -} diff --git a/src/com/vaadin/ui/CustomLayout.java b/src/com/vaadin/ui/CustomLayout.java deleted file mode 100644 index d7830603f0..0000000000 --- a/src/com/vaadin/ui/CustomLayout.java +++ /dev/null @@ -1,329 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import com.vaadin.shared.ui.customlayout.CustomLayoutState; -import com.vaadin.terminal.PaintException; -import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.Vaadin6Component; -import com.vaadin.terminal.gwt.server.JsonPaintTarget; - -/** - *

- * A container component with freely designed layout and style. The layout - * consists of items with textually represented locations. Each item contains - * one sub-component, which can be any Vaadin component, such as a layout. The - * adapter and theme are responsible for rendering the layout with a given style - * by placing the items in the defined locations. - *

- * - *

- * The placement of the locations is not fixed - different themes can define the - * locations in a way that is suitable for them. One typical example would be to - * create visual design for a web site as a custom layout: the visual design - * would define locations for "menu", "body", and "title", for example. The - * layout would then be implemented as an XHTML template for each theme. - *

- * - *

- * The default theme handles the styles that are not defined by drawing the - * subcomponents just as in OrderedLayout. - *

- * - * @author Vaadin Ltd. - * @author Duy B. Vo (devduy@gmail.com) - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class CustomLayout extends AbstractLayout implements Vaadin6Component { - - private static final int BUFFER_SIZE = 10000; - - /** - * Custom layout slots containing the components. - */ - private final HashMap slots = new HashMap(); - - /** - * Default constructor only used by subclasses. Subclasses are responsible - * for setting the appropriate fields. Either - * {@link #setTemplateName(String)}, that makes layout fetch the template - * from theme, or {@link #setTemplateContents(String)}. - */ - protected CustomLayout() { - setWidth(100, UNITS_PERCENTAGE); - } - - /** - * Constructs a custom layout with the template given in the stream. - * - * @param templateStream - * Stream containing template data. Must be using UTF-8 encoding. - * To use a String as a template use for instance new - * ByteArrayInputStream("