com.googlesource.gerrit.plugins.emoticons.client.OnEditEnabler.java Source code

Java tutorial

Introduction

Here is the source code for com.googlesource.gerrit.plugins.emoticons.client.OnEditEnabler.java

Source

// Copyright (C) 2010 The Android Open Source Project
//
// 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.googlesource.gerrit.plugins.emoticons.client;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBoxBase;
import com.google.gwt.user.client.ui.ValueBoxBase;

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

/** Enables a FocusWidget (e.g. a Button) if an edit is detected from any
 *  registered input widget.
 */
public class OnEditEnabler
        implements KeyPressHandler, KeyDownHandler, MouseUpHandler, ChangeHandler, ValueChangeHandler<Object> {

    private final FocusWidget widget;
    private Map<TextBoxBase, String> strings = new HashMap<>();
    private String originalValue;

    // The first parameter to the constructors must be the FocusWidget to enable,
    // subsequent parameters are widgets to listenTo.

    public OnEditEnabler(FocusWidget w, TextBoxBase tb) {
        this(w);
        originalValue = tb.getValue().trim();
        listenTo(tb);
    }

    public OnEditEnabler(FocusWidget w, ListBox lb) {
        this(w);
        listenTo(lb);
    }

    public OnEditEnabler(FocusWidget w, CheckBox cb) {
        this(w);
        listenTo(cb);
    }

    public OnEditEnabler(FocusWidget w) {
        widget = w;
    }

    // Register input widgets to be listened to

    public void listenTo(final TextBoxBase tb) {
        strings.put(tb, tb.getText().trim());
        tb.addKeyPressHandler(this);

        // Is there another way to capture middle button X11 pastes in browsers
        // which do not yet support ONPASTE events (Firefox)?
        tb.addMouseUpHandler(this);

        // Resetting the "original text" on focus ensures that we are
        // up to date with non-user updates of the text (calls to
        // setText()...) and also up to date with user changes which
        // occured after enabling "widget".
        tb.addFocusHandler(new FocusHandler() {
            @Override
            public void onFocus(FocusEvent event) {
                strings.put(tb, tb.getText().trim());
            }
        });

        // CTRL-V Pastes in Chrome seem only detectable via BrowserEvents or
        // KeyDownEvents, the latter is better.
        tb.addKeyDownHandler(this);
    }

    public void listenTo(ListBox lb) {
        lb.addChangeHandler(this);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void listenTo(CheckBox cb) {
        cb.addValueChangeHandler((ValueChangeHandler) this);
    }

    // Handlers

    @Override
    public void onKeyPress(KeyPressEvent e) {
        on(e);
    }

    @Override
    public void onKeyDown(KeyDownEvent e) {
        on(e);
    }

    @Override
    public void onMouseUp(MouseUpEvent e) {
        on(e);
    }

    @Override
    public void onChange(ChangeEvent e) {
        on(e);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public void onValueChange(ValueChangeEvent e) {
        on(e);
    }

    private void on(GwtEvent<?> e) {
        if (widget.isEnabled() || !(e.getSource() instanceof FocusWidget)
                || !((FocusWidget) e.getSource()).isEnabled()) {
            if (e.getSource() instanceof ValueBoxBase) {
                final TextBoxBase box = ((TextBoxBase) e.getSource());
                Scheduler.get().scheduleDeferred(new ScheduledCommand() {
                    @Override
                    public void execute() {
                        if (box.getValue().trim().equals(originalValue)) {
                            widget.setEnabled(false);
                        }
                    }
                });
            }
            return;
        }

        if (e.getSource() instanceof TextBoxBase) {
            onTextBoxBase((TextBoxBase) e.getSource());
        } else {
            // For many widgets, we can assume that a change is an edit. If
            // a widget does not work that way, it should be special cased
            // above.
            widget.setEnabled(true);
        }
    }

    private void onTextBoxBase(final TextBoxBase tb) {
        // The text appears to not get updated until the handlers complete.
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
            @Override
            public void execute() {
                String orig = strings.get(tb);
                if (orig == null) {
                    orig = "";
                }
                if (!orig.equals(tb.getText().trim())) {
                    widget.setEnabled(true);
                }
            }
        });
    }
}