/* @ITMillApache2LicenseForJavaFiles@ */ package com.vaadin.ui; import java.util.Map; import com.vaadin.data.Property; import com.vaadin.event.FieldEvents; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.gwt.client.ui.VTextField; import com.vaadin.ui.ClientWidget.LoadStyle; /** *
* A text editor component that can be bound to any bindable Property. The text * editor supports both multiline and single line modes, default is one-line * mode. *
* *
* Since TextField
extends AbstractField
it implements
* the {@link com.vaadin.data.Buffered} interface. A TextField
is
* in write-through mode by default, so
* {@link com.vaadin.ui.AbstractField#setWriteThrough(boolean)} must be called
* to enable buffering.
*
TextField
with no caption.
*/
public TextField() {
setValue("");
}
/**
* Constructs an empty TextField
with given caption.
*
* @param caption
* the caption String
for the editor.
*/
public TextField(String caption) {
this();
setCaption(caption);
}
/**
* Constructs a new TextField
that's bound to the specified
* Property
and has no caption.
*
* @param dataSource
* the Property to be edited with this editor.
*/
public TextField(Property dataSource) {
setPropertyDataSource(dataSource);
}
/**
* Constructs a new TextField
that's bound to the specified
* Property
and has the given caption String
.
*
* @param caption
* the caption String
for the editor.
* @param dataSource
* the Property to be edited with this editor.
*/
public TextField(String caption, Property dataSource) {
this(dataSource);
setCaption(caption);
}
/**
* Constructs a new TextField
with the given caption and
* initial text contents. The editor constructed this way will not be bound
* to a Property unless
* {@link com.vaadin.data.Property.Viewer#setPropertyDataSource(Property)}
* is called to bind it.
*
* @param caption
* the caption String
for the editor.
* @param text
* the initial text content of the editor.
*/
public TextField(String caption, String value) {
setValue(value);
setCaption(caption);
}
/**
* Gets the secret property on and off. If a field is used to enter
* secretinformation the information is not echoed to display.
*
* @return true
if the field is used to enter secret
* information, false
otherwise.
*
* @deprecated in 6.5 use {@link PasswordField} instead
*/
@Deprecated
public boolean isSecret() {
return secret;
}
/**
* Sets the secret property on and off. If a field is used to enter
* secretinformation the information is not echoed to display.
*
* @param secret
* the value specifying if the field is used to enter secret
* information.
* @deprecated in 6.5 use {@link PasswordField} instead
*/
@Deprecated
public void setSecret(boolean secret) {
if (this.secret != secret) {
this.secret = secret;
requestRepaint();
}
}
@Override
public void paintContent(PaintTarget target) throws PaintException {
if (isSecret()) {
target.addAttribute("secret", true);
}
// Adds the number of column and rows
final int columns = getColumns();
if (columns != 0) {
target.addAttribute("cols", String.valueOf(columns));
}
final int rows = getRows();
if (rows != 0) {
target.addAttribute("rows", String.valueOf(rows));
target.addAttribute("multiline", true);
// For backward compatibility; to be moved to TextArea
target.addAttribute("wordwrap", isWordwrap());
}
if (getInputPrompt() != null) {
target.addAttribute("prompt", getInputPrompt());
}
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());
}
super.paintContent(target);
}
/**
* Gets the number of rows in the editor. If the number of rows is set to 0,
* the actual number of displayed rows is determined implicitly by the
* adapter.
*
* @return number of explicitly set rows.
* @deprecated use {@link TextArea} component and the same method there.
* This method will be removed from TextField that is to be used
* for one line text input only in the next versions.
*
*/
@Deprecated
public int getRows() {
return rows;
}
/**
* Sets the number of rows in the editor.
*
* @param rows
* the number of rows for this editor.
*
* @deprecated in 6.5 use {@link TextArea} component and the same method
* there. This method will be removed from TextField that is to
* be used for one line text input only in the next versions.
*/
@Deprecated
public void setRows(int rows) {
if (rows < 0) {
rows = 0;
}
if (this.rows != rows) {
this.rows = rows;
requestRepaint();
}
}
/**
* Tests if the editor is in word-wrap mode.
*
* @return true
if the component is in the word-wrap mode,
* false
if not.
* @deprecated in 6.5 use {@link TextArea} component and the same method
* there. This method will be removed from TextField that is to
* be used for one line text input only in the next versions.
*/
@Deprecated
public boolean isWordwrap() {
return wordwrap;
}
/**
* Sets the editor's word-wrap mode on or off.
*
* @param wordwrap
* the boolean value specifying if the editor should be in
* word-wrap mode after the call or not.
*
* @deprecated in 6.5 use {@link TextArea} component and the same method
* there. This method will be removed from TextField that is to
* be used for one line text input only in the next versions.
*/
@Deprecated
public void setWordwrap(boolean wordwrap) {
if (this.wordwrap != wordwrap) {
this.wordwrap = wordwrap;
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 columns;
}
/**
* 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;
}
this.columns = columns;
requestRepaint();
}
/**
* 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 field
* would otherwise be empty, to prompt the user for input.
*
* @param inputPrompt
*/
public void setInputPrompt(String inputPrompt) {
this.inputPrompt = inputPrompt;
requestRepaint();
}
/**
* 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; } /** * Gets the current (or the last known) text content in the field. *
* Note the text returned by this method is not necessary the same what 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();
}
}
@Override
public void changeVariables(Object source, Map
* 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
}
public void addListener(TextChangeListener listener) {
addListener(TextChangeListener.EVENT_ID, TextChangeEvent.class,
listener, TextChangeListener.EVENT_METHOD);
}
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;
}
/**
* 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 TextField tf) {
super(tf);
curText = tf.getCurrentTextContent();
cursorPosition = tf.getCursorPosition();
}
@Override
public TextField getComponent() {
return (TextField) super.getComponent();
}
@Override
public String getText() {
return curText;
}
@Override
public int getCursorPosition() {
return cursorPosition;
}
}
}