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

com.vaadin.client.ui.textfield.AbstractTextFieldConnector Maven / Gradle / Ivy

There is a newer version: 8.26.0
Show newest version
/*
 * Copyright 2000-2018 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.client.ui.textfield;

import com.google.gwt.event.dom.client.HasBlurHandlers;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.DeferredWorker;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.ui.AbstractFieldConnector;
import com.vaadin.client.ui.AbstractTextFieldWidget;
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler;
import com.vaadin.shared.ui.textfield.AbstractTextFieldClientRpc;
import com.vaadin.shared.ui.textfield.AbstractTextFieldServerRpc;
import com.vaadin.shared.ui.textfield.AbstractTextFieldState;
import com.vaadin.ui.AbstractTextField;

/**
 * Connector class for AbstractTextField.
 *
 * @since 8.0
 */
public abstract class AbstractTextFieldConnector extends AbstractFieldConnector
        implements ValueChangeHandler.Owner, DeferredWorker {

    private class AbstractTextFieldClientRpcImpl
            implements AbstractTextFieldClientRpc {
        @Override
        public void selectRange(int start, int length) {
            int textLength = getAbstractTextField().getValue().length();
            // Enable setting cursor position after the last character
            start = restrictTo(start, 0,
                    length == 0 ? textLength : (textLength - 1));
            length = restrictTo(length, 0, textLength - start);
            getAbstractTextField().setSelectionRange(start, length);
        }

        private int restrictTo(int value, int min, int max) {
            if (value < min) {
                value = min;
            }
            if (value > max) {
                value = max;
            }

            return value;
        }

        @Override
        public void selectAll() {
            getAbstractTextField().selectAll();
        }
    }

    private int lastSentCursorPosition = -1;
    private ValueChangeHandler valueChangeHandler;

    @Override
    protected void init() {
        registerRpc(AbstractTextFieldClientRpc.class,
                new AbstractTextFieldClientRpcImpl());
        ConnectorFocusAndBlurHandler.addHandlers(this);
        valueChangeHandler = new ValueChangeHandler(this);

        // Ensures that the cursor position is sent when leaving the field
        // (if it has changed)
        if (getWidget() instanceof HasBlurHandlers) {
            ((HasBlurHandlers) getWidget())
                    .addBlurHandler(event -> sendValueChange());
        }
    }

    protected ValueChangeHandler getValueChangeHandler() {
        return valueChangeHandler;
    }

    /**
     * Helper to cast {@link #getWidget()} to {@link AbstractTextField}. The
     * method exists only because getWidget() must return a {@link Widget} and
     * not an interface.
     *
     * @return the widget as an AbstractTextFieldWidget
     */
    private AbstractTextFieldWidget getAbstractTextField() {
        return (AbstractTextFieldWidget) getWidget();
    }

    @Override
    public AbstractTextFieldState getState() {
        return (AbstractTextFieldState) super.getState();
    }

    @OnStateChange("valueChangeMode")
    private void updateValueChangeMode() {
        valueChangeHandler.setValueChangeMode(getState().valueChangeMode);
    }

    @OnStateChange("valueChangeTimeout")
    private void updateValueChangeTimeout() {
        valueChangeHandler.setValueChangeTimeout(getState().valueChangeTimeout);
    }

    @OnStateChange("readOnly")
    private void updateReadOnly() {
        getAbstractTextField().setReadOnly(getState().readOnly);
    }

    private boolean hasStateChanged() {
        boolean textChanged = !getAbstractTextField().getValue()
                .equals(getState().text);
        boolean cursorPosChanged = getAbstractTextField()
                .getCursorPos() != lastSentCursorPosition;
        return textChanged || cursorPosChanged;
    }

    /**
     * Sends the updated value and cursor position to the server, if either one
     * has changed.
     */
    @Override
    public void sendValueChange() {
        if (!hasStateChanged()) {
            return;
        }

        lastSentCursorPosition = getAbstractTextField().getCursorPos();
        getRpcProxy(AbstractTextFieldServerRpc.class).setText(
                getAbstractTextField().getValue(), lastSentCursorPosition);
        getState().text = getAbstractTextField().getValue();
    }

    @Override
    public void flush() {
        super.flush();
        sendValueChange();
    }

    /**
     * {@inheritDoc}
     *
     * @since 8.0
     */
    @Override
    public boolean isWorkPending() {
        return getValueChangeHandler().isScheduled();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy