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

com.vaadin.client.widgets.ChildFocusAwareFlowPanel Maven / Gradle / Ivy

Go to download

Vaadin is a web application framework for Rich Internet Applications (RIA). Vaadin enables easy development and maintenance of fast and secure rich web applications with a stunning look and feel and a wide browser support. It features a server-side architecture with the majority of the logic running on the server. Ajax technology is used at the browser-side to ensure a rich and interactive user experience.

There is a newer version: 8.27.1
Show newest version
/*
 * Copyright 2000-2016 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.widgets;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Style.OutlineStyle;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.HasAllFocusHandlers;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Focusable;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ui.FocusableFlowPanel;

/**
 * Focusable flow panel which fires focus/blur events if it or any of its child
 * is focused/blured, but doesn't fire events if it happens between its content
 * (child) elements.
 *
 * @author Vaadin Ltd
 * @since 8.0
 */
public class ChildFocusAwareFlowPanel extends FocusableFlowPanel
        implements HasAllFocusHandlers {

    private class FocusBlurHandler implements BlurHandler, FocusHandler {

        private boolean blurOccured;

        @Override
        public void onBlur(BlurEvent event) {
            blurOccured = true;
            Scheduler.get().scheduleDeferred(() -> fireBlurEvent(event));
        }

        @Override
        public void onFocus(FocusEvent event) {
            if (!blurOccured) {
                // no blur occured before this focus event
                eventBus.fireEvent(event);
            } else {
                // blur occured before this focus event
                // another component inside the panel was
                // blurred => do not fire the focus and set blurOccured to
                // false, so
                // blur will not be fired, too
                blurOccured = false;
            }
        }

        private void fireBlurEvent(BlurEvent event) {
            if (blurOccured) {
                eventBus.fireEvent(event);
                blurOccured = false;
            }
        }
    }

    private final HandlerManager eventBus;

    private final FocusBlurHandler handler = new FocusBlurHandler();

    private final Map focusRegistrations = new HashMap<>();
    private final Map blurRegistrations = new HashMap<>();

    /**
     * Creates a new panel instance.
     */
    public ChildFocusAwareFlowPanel() {
        eventBus = new HandlerManager(this);
        getElement().getStyle().setOutlineStyle(OutlineStyle.NONE);
        super.addFocusHandler(handler);
        super.addBlurHandler(handler);
    }

    @Override
    public void add(Widget widget) {
        super.add(widget);
        addHandlers(widget);
    }

    @Override
    public void clear() {
        super.clear();
        focusRegistrations.clear();
        blurRegistrations.clear();
    }

    @Override
    public void insert(Widget widget, int beforeIndex) {
        super.insert(widget, beforeIndex);
        addHandlers(widget);
    }

    @Override
    public boolean remove(int index) {
        Widget widget = getWidget(index);
        boolean isRemoved = super.remove(index);
        if (isRemoved) {
            removeHandlers(widget);
        }
        return isRemoved;
    }

    @Override
    public boolean remove(Widget widget) {
        boolean isRemoved = super.remove(widget);
        if (isRemoved) {
            removeHandlers(widget);
        }
        return isRemoved;
    }

    @Override
    public HandlerRegistration addFocusHandler(FocusHandler handler) {
        return eventBus.addHandler(FocusEvent.getType(), handler);
    }

    @Override
    public HandlerRegistration addBlurHandler(BlurHandler handler) {
        return eventBus.addHandler(BlurEvent.getType(), handler);
    }

    @Override
    public void focus() {
        Iterator iterator = iterator();
        if (iterator.hasNext()) {
            Widget widget = iterator.next();
            if (widget instanceof Focusable) {
                ((Focusable) widget).setFocus(true);
            }
        }
    }

    private void addHandlers(Widget widget) {
        if (focusRegistrations.containsKey(widget)) {
            assert blurRegistrations.containsKey(widget);
            return;
        }
        if (widget instanceof FocusWidget) {
            HandlerRegistration focusRegistration = ((FocusWidget) widget)
                    .addFocusHandler(handler);
            HandlerRegistration blurRegistration = ((FocusWidget) widget)
                    .addBlurHandler(handler);
            focusRegistrations.put(widget, focusRegistration);
            blurRegistrations.put(widget, blurRegistration);
        }
    }

    private void removeHandlers(Widget widget) {
        HandlerRegistration focusRegistration = focusRegistrations
                .remove(widget);
        if (focusRegistration != null) {
            focusRegistration.removeHandler();
        }
        HandlerRegistration blurRegistration = blurRegistrations.remove(widget);
        if (blurRegistration != null) {
            blurRegistration.removeHandler();
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy