All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vaadin.ui.AbstractTextField Maven / Gradle / Ivy

There is a newer version: 8.27.1
Show newest version
/*
 * Copyright 2000-2014 Vaadin Ltd.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.vaadin.ui;

import java.util.Collection;
import java.util.Map;

import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Element;

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.server.PaintException;
import com.vaadin.server.PaintTarget;
import com.vaadin.shared.ui.textfield.AbstractTextFieldState;
import com.vaadin.shared.ui.textfield.TextFieldConstants;
import com.vaadin.ui.declarative.DesignAttributeHandler;
import com.vaadin.ui.declarative.DesignContext;

public abstract class AbstractTextField extends AbstractField implements
        BlurNotifier, FocusNotifier, TextChangeNotifier, LegacyComponent {

    /**
     * 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
    protected AbstractTextFieldState getState() {
        return (AbstractTextFieldState) super.getState();
    }

    @Override
    protected AbstractTextFieldState getState(boolean markAsDirty) {
        return (AbstractTextFieldState) super.getState(markAsDirty);
    }

    @Override
    public void beforeClientResponse(boolean initial) {
        super.beforeClientResponse(initial);

        String value = getValue();
        if (value == null) {
            value = getNullRepresentation();
        }
        getState().text = 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(TextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE,
                    getTextChangeEventMode().toString());
            target.addAttribute(TextFieldConstants.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(
                        TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS,
                        true);
            }
        }

    }

    @Override
    public void changeVariables(Object source, Map variables) {
        changingVariables = true;

        try {

            // Sets the height set by the user when resize the