com.google.gwt.cell.client.AbstractInputCell.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.cell.client.AbstractInputCell.java

Source

/*
 * Copyright 2010 Google Inc.
 * 
 * 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.google.gwt.cell.client;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;

import java.util.HashSet;
import java.util.Set;

/**
 * An {@link AbstractCell} used to render input elements that can receive focus.
 * 
 * @param <C> the type that this Cell represents
 * @param <V> the data type of the view data state
 */
public abstract class AbstractInputCell<C, V> extends AbstractEditableCell<C, V> {

    /**
     * Get the events consumed by the input cell.
     * 
     * @param userEvents the events consumed by the subclass
     * @return the events
     */
    private static Set<String> getConsumedEventsImpl(Set<String> userEvents) {
        Set<String> events = new HashSet<String>();
        events.add("focus");
        events.add("blur");
        events.add("keydown");
        if (userEvents != null && userEvents.size() > 0) {
            events.addAll(userEvents);
        }
        return events;
    }

    /**
     * Get the events consumed by the input cell.
     * 
     * @param userEvents the events consumed by the subclass
     * @return the events
     */
    private static Set<String> getConsumedEventsImpl(String... consumedEvents) {
        Set<String> userEvents = new HashSet<String>();
        if (consumedEvents != null) {
            for (String event : consumedEvents) {
                userEvents.add(event);
            }
        }
        return getConsumedEventsImpl(userEvents);
    }

    /**
     * The currently focused value key. Only one key can be focused at any time.
     */
    private Object focusedKey;

    /**
     * Construct a new {@link AbstractInputCell} with the specified consumed
     * events.
     * 
     * @param consumedEvents the events that this cell consumes
     */
    public AbstractInputCell(String... consumedEvents) {
        super(getConsumedEventsImpl(consumedEvents));
    }

    /**
     * Construct a new {@link AbstractInputCell} with the specified consumed
     * events.
     * 
     * @param consumedEvents the events that this cell consumes
     */
    public AbstractInputCell(Set<String> consumedEvents) {
        super(getConsumedEventsImpl(consumedEvents));
    }

    @Override
    public boolean isEditing(Context context, Element parent, C value) {
        return focusedKey != null && focusedKey.equals(context.getKey());
    }

    @Override
    public void onBrowserEvent(Context context, Element parent, C value, NativeEvent event,
            ValueUpdater<C> valueUpdater) {
        super.onBrowserEvent(context, parent, value, event, valueUpdater);

        // Ignore events that don't target the input.
        Element target = event.getEventTarget().cast();
        if (!getInputElement(parent).isOrHasChild(target)) {
            return;
        }

        String eventType = event.getType();
        if ("focus".equals(eventType)) {
            focusedKey = context.getKey();
        } else if ("blur".equals(eventType)) {
            focusedKey = null;
        }
    }

    @Override
    public boolean resetFocus(Context context, Element parent, C value) {
        if (isEditing(context, parent, value)) {
            getInputElement(parent).focus();
            return true;
        }
        return false;
    }

    /**
     * Call this method when editing is complete.
     * 
     * @param parent the parent Element
     * @param value the value associated with the cell
     * @param key the unique key associated with the row object
     * @param valueUpdater the value update to fire
     */
    protected void finishEditing(Element parent, C value, Object key, ValueUpdater<C> valueUpdater) {
        focusedKey = null;
        getInputElement(parent).blur();
    }

    /**
     * Get the input element.
     * 
     * @param parent the cell parent element
     * @return the input element
     */
    protected Element getInputElement(Element parent) {
        return parent.getFirstChildElement();
    }

    @Override
    protected void onEnterKeyDown(Context context, Element parent, C value, NativeEvent event,
            ValueUpdater<C> valueUpdater) {
        Element input = getInputElement(parent);
        Element target = event.getEventTarget().cast();
        Object key = context.getKey();
        if (getInputElement(parent).isOrHasChild(target)) {
            finishEditing(parent, value, key, valueUpdater);
        } else {
            focusedKey = key;
            input.focus();
        }
    }
}