diff options
author | Artur Signell <artur@vaadin.com> | 2012-08-13 18:34:33 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2012-08-13 19:18:33 +0300 |
commit | e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569 (patch) | |
tree | 9ab6f13f7188cab44bbd979b1cf620f15328a03f /server/src/com/vaadin/ui/Label.java | |
parent | 14dd4d0b28c76eb994b181a4570f3adec53342e6 (diff) | |
download | vaadin-framework-e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569.tar.gz vaadin-framework-e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569.zip |
Moved server files to a server src folder (#9299)
Diffstat (limited to 'server/src/com/vaadin/ui/Label.java')
-rw-r--r-- | server/src/com/vaadin/ui/Label.java | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/com/vaadin/ui/Label.java new file mode 100644 index 0000000000..7e50a37805 --- /dev/null +++ b/server/src/com/vaadin/ui/Label.java @@ -0,0 +1,483 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.ui; + +import java.lang.reflect.Method; +import java.util.logging.Logger; + +import com.vaadin.data.Property; +import com.vaadin.data.util.converter.Converter; +import com.vaadin.data.util.converter.ConverterUtil; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.shared.ui.label.LabelState; + +/** + * Label component for showing non-editable short texts. + * + * The label content can be set to the modes specified by {@link ContentMode} + * + * <p> + * The contents of the label may contain simple formatting: + * <ul> + * <li><b><b></b> Bold + * <li><b><i></b> Italic + * <li><b><u></b> Underlined + * <li><b><br/></b> Linebreak + * <li><b><ul><li>item 1</li><li>item 2</li></ul></b> List of + * items + * </ul> + * The <b>b</b>,<b>i</b>,<b>u</b> and <b>li</b> tags can contain all the tags in + * the list recursively. + * </p> + * + * @author Vaadin Ltd. + * @version + * @VERSION@ + * @since 3.0 + */ +@SuppressWarnings("serial") +public class Label extends AbstractComponent implements Property<String>, + Property.Viewer, Property.ValueChangeListener, + Property.ValueChangeNotifier, Comparable<Label> { + + private static final Logger logger = Logger + .getLogger(Label.class.getName()); + + /** + * @deprecated From 7.0, use {@link ContentMode#TEXT} instead + */ + @Deprecated + public static final ContentMode CONTENT_TEXT = ContentMode.TEXT; + + /** + * @deprecated From 7.0, use {@link ContentMode#PREFORMATTED} instead + */ + @Deprecated + public static final ContentMode CONTENT_PREFORMATTED = ContentMode.PREFORMATTED; + + /** + * @deprecated From 7.0, use {@link ContentMode#XHTML} instead + */ + @Deprecated + public static final ContentMode CONTENT_XHTML = ContentMode.XHTML; + + /** + * @deprecated From 7.0, use {@link ContentMode#XML} instead + */ + @Deprecated + public static final ContentMode CONTENT_XML = ContentMode.XML; + + /** + * @deprecated From 7.0, use {@link ContentMode#RAW} instead + */ + @Deprecated + public static final ContentMode CONTENT_RAW = ContentMode.RAW; + + /** + * @deprecated From 7.0, use {@link ContentMode#TEXT} instead + */ + @Deprecated + public static final ContentMode CONTENT_DEFAULT = ContentMode.TEXT; + + /** + * A converter used to convert from the data model type to the field type + * and vice versa. Label type is always String. + */ + private Converter<String, Object> converter = null; + + private Property<String> dataSource = null; + + /** + * Creates an empty Label. + */ + public Label() { + this(""); + } + + /** + * Creates a new instance of Label with text-contents. + * + * @param content + */ + public Label(String content) { + this(content, ContentMode.TEXT); + } + + /** + * Creates a new instance of Label with text-contents read from given + * datasource. + * + * @param contentSource + */ + public Label(Property contentSource) { + this(contentSource, ContentMode.TEXT); + } + + /** + * Creates a new instance of Label with text-contents. + * + * @param content + * @param contentMode + */ + public Label(String content, ContentMode contentMode) { + setValue(content); + setContentMode(contentMode); + setWidth(100, Unit.PERCENTAGE); + } + + /** + * Creates a new instance of Label with text-contents read from given + * datasource. + * + * @param contentSource + * @param contentMode + */ + public Label(Property contentSource, ContentMode contentMode) { + setPropertyDataSource(contentSource); + setContentMode(contentMode); + setWidth(100, Unit.PERCENTAGE); + } + + @Override + public LabelState getState() { + return (LabelState) super.getState(); + } + + /** + * Gets the value of the label. + * <p> + * The value of the label is the text that is shown to the end user. + * Depending on the {@link ContentMode} it is plain text or markup. + * </p> + * + * @return the value of the label. + */ + @Override + public String getValue() { + if (getPropertyDataSource() == null) { + // Use internal value if we are running without a data source + return getState().getText(); + } + return ConverterUtil.convertFromModel(getPropertyDataSource() + .getValue(), String.class, getConverter(), getLocale()); + } + + /** + * Set the value of the label. Value of the label is the XML contents of the + * label. + * + * @param newStringValue + * the New value of the label. + */ + @Override + public void setValue(Object newStringValue) { + if (newStringValue != null && newStringValue.getClass() != String.class) { + throw new Converter.ConversionException("Value of type " + + newStringValue.getClass() + " cannot be assigned to " + + String.class.getName()); + } + if (getPropertyDataSource() == null) { + getState().setText((String) newStringValue); + requestRepaint(); + } else { + throw new IllegalStateException( + "Label is only a Property.Viewer and cannot update its data source"); + } + } + + /** + * Returns the value displayed by this label. + * + * @see java.lang.Object#toString() + * @deprecated As of 7.0.0, use {@link #getValue()} to get the value of the + * label or {@link #getPropertyDataSource()} .getValue() to get + * the value of the data source. + */ + @Deprecated + @Override + public String toString() { + logger.warning("You are using Label.toString() to get the value for a " + + getClass().getSimpleName() + + ". This is not recommended and will not be supported in future versions."); + return getValue(); + } + + /** + * Gets the type of the Property. + * + * @see com.vaadin.data.Property#getType() + */ + @Override + public Class<String> getType() { + return String.class; + } + + /** + * Gets the viewing data-source property. + * + * @return the data source property. + * @see com.vaadin.data.Property.Viewer#getPropertyDataSource() + */ + @Override + public Property getPropertyDataSource() { + return dataSource; + } + + /** + * Sets the property as data-source for viewing. + * + * @param newDataSource + * the new data source Property + * @see com.vaadin.data.Property.Viewer#setPropertyDataSource(com.vaadin.data.Property) + */ + @Override + public void setPropertyDataSource(Property newDataSource) { + // Stops listening the old data source changes + if (dataSource != null + && Property.ValueChangeNotifier.class + .isAssignableFrom(dataSource.getClass())) { + ((Property.ValueChangeNotifier) dataSource).removeListener(this); + } + + if (!ConverterUtil.canConverterHandle(getConverter(), String.class, + newDataSource.getType())) { + // Try to find a converter + Converter<String, ?> c = ConverterUtil.getConverter(String.class, + newDataSource.getType(), getApplication()); + setConverter(c); + } + dataSource = newDataSource; + + // Listens the new data source if possible + if (dataSource != null + && Property.ValueChangeNotifier.class + .isAssignableFrom(dataSource.getClass())) { + ((Property.ValueChangeNotifier) dataSource).addListener(this); + } + requestRepaint(); + } + + /** + * Gets the content mode of the Label. + * + * @return the Content mode of the label. + * + * @see ContentMode + */ + public ContentMode getContentMode() { + return getState().getContentMode(); + } + + /** + * Sets the content mode of the Label. + * + * @param contentMode + * the New content mode of the label. + * + * @see ContentMode + */ + public void setContentMode(ContentMode contentMode) { + if (contentMode == null) { + throw new IllegalArgumentException("Content mode can not be null"); + } + + getState().setContentMode(contentMode); + requestRepaint(); + } + + /* 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 Label"); + } + } + + /** + * Value change event + * + * @author Vaadin Ltd. + * @version + * @VERSION@ + * @since 3.0 + */ + public static class ValueChangeEvent extends Component.Event implements + Property.ValueChangeEvent { + + /** + * New instance of text change event + * + * @param source + * the Source of the event. + */ + public ValueChangeEvent(Label source) { + super(source); + } + + /** + * Gets the Property that has been modified. + * + * @see com.vaadin.data.Property.ValueChangeEvent#getProperty() + */ + @Override + public Property getProperty() { + return (Property) getSource(); + } + } + + /** + * Adds the value change listener. + * + * @param listener + * the Listener to be added. + * @see com.vaadin.data.Property.ValueChangeNotifier#addListener(com.vaadin.data.Property.ValueChangeListener) + */ + @Override + public void addListener(Property.ValueChangeListener listener) { + addListener(Label.ValueChangeEvent.class, listener, VALUE_CHANGE_METHOD); + } + + /** + * Removes the value change listener. + * + * @param listener + * the Listener to be removed. + * @see com.vaadin.data.Property.ValueChangeNotifier#removeListener(com.vaadin.data.Property.ValueChangeListener) + */ + @Override + public void removeListener(Property.ValueChangeListener listener) { + removeListener(Label.ValueChangeEvent.class, listener, + VALUE_CHANGE_METHOD); + } + + /** + * Emits the options change event. + */ + protected void fireValueChange() { + // Set the error message + fireEvent(new Label.ValueChangeEvent(this)); + } + + /** + * Listens the value change events from data source. + * + * @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent) + */ + @Override + public void valueChange(Property.ValueChangeEvent event) { + // Update the internal value from the data source + getState().setText(getValue()); + requestRepaint(); + + fireValueChange(); + } + + private String getComparableValue() { + String stringValue = getValue(); + if (stringValue == null) { + stringValue = ""; + } + + if (getContentMode() == ContentMode.XHTML + || getContentMode() == ContentMode.XML) { + return stripTags(stringValue); + } else { + return stringValue; + } + + } + + /** + * Compares the Label to other objects. + * + * <p> + * Labels can be compared to other labels for sorting label contents. This + * is especially handy for sorting table columns. + * </p> + * + * <p> + * In RAW, PREFORMATTED and TEXT modes, the label contents are compared as + * is. In XML, UIDL and XHTML modes, only CDATA is compared and tags + * ignored. If the other object is not a Label, its toString() return value + * is used in comparison. + * </p> + * + * @param other + * the Other object to compare to. + * @return a negative integer, zero, or a positive integer as this object is + * less than, equal to, or greater than the specified object. + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + @Override + public int compareTo(Label other) { + + String thisValue = getComparableValue(); + String otherValue = other.getComparableValue(); + + return thisValue.compareTo(otherValue); + } + + /** + * Strips the tags from the XML. + * + * @param xml + * the String containing a XML snippet. + * @return the original XML without tags. + */ + private String stripTags(String xml) { + + final StringBuffer res = new StringBuffer(); + + int processed = 0; + final int xmlLen = xml.length(); + while (processed < xmlLen) { + int next = xml.indexOf('<', processed); + if (next < 0) { + next = xmlLen; + } + res.append(xml.substring(processed, next)); + if (processed < xmlLen) { + next = xml.indexOf('>', processed); + if (next < 0) { + next = xmlLen; + } + processed = next + 1; + } + } + + return res.toString(); + } + + /** + * Gets the converter used to convert the property data source value to the + * label value. + * + * @return The converter or null if none is set. + */ + public Converter<String, Object> getConverter() { + return converter; + } + + /** + * Sets the converter used to convert the label value to the property data + * source type. The converter must have a presentation type of String. + * + * @param converter + * The new converter to use. + */ + public void setConverter(Converter<String, ?> converter) { + this.converter = (Converter<String, Object>) converter; + requestRepaint(); + } + +} |