com.google.testing.testify.risk.frontend.client.view.widgets.LabelWidget.java Source code

Java tutorial

Introduction

Here is the source code for com.google.testing.testify.risk.frontend.client.view.widgets.LabelWidget.java

Source

// Copyright 2010 Google Inc. All Rights Reseved.
//
// 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.testing.testify.risk.frontend.client.view.widgets;

import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay;

import java.util.Collection;

/**
 * Displays a label with a little delete X as well.  You can click the X to delete the label.
 *
 * @author jimr@google.com (Jim Reardon)
 */
public class LabelWidget extends Composite implements HasValue<String>, HasValueChangeHandlers<String> {

    private HorizontalPanel contentPanel = new HorizontalPanel();
    private Image image = new Image();
    // The deck panel will have to entries -- the view mode, and the edit mode.  DeckPanel will
    // only make one visible at a time.
    private DeckPanel deckPanel = new DeckPanel();
    private MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(" -");
    private SuggestBox inputBox = new SuggestBox(oracle);
    private Label label = new Label();

    private static final int VIEW_MODE = 0;
    private static final int EDIT_MODE = 1;

    private boolean canEdit = false;

    public LabelWidget(String text) {
        this(text, false);
    }

    /**
     * Constructs a label for a given object, allowing customized styling.  The constructed
     * label will use styles:
     *   tty-GenericLabel
     *   tty-GenericLabelRemoveLabelImage
     * @param text the textual representation for this label.
     * @param isAddWidget true if this is a "new label..." widget, false if not.
     */
    public LabelWidget(String text, final boolean isAddWidget) {
        DefaultSuggestionDisplay suggestionDisplay = (DefaultSuggestionDisplay) inputBox.getSuggestionDisplay();
        suggestionDisplay.setPopupStyleName("tty-SuggestBoxPopup");
        contentPanel.addStyleName("tty-RemovableLabel");

        if (isAddWidget) {
            // Craft a little plus image.
            image.setStyleName("tty-RemovableLabelAddImage");
            image.setUrl("images/collapsed_12.png");
            image.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    switchMode(EDIT_MODE);
                }
            });
            contentPanel.add(image);
        }

        // Craft the view mode.
        label.setText(text);
        label.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent arg0) {
                switchMode(EDIT_MODE);
            }
        });
        deckPanel.add(label);

        // Craft the edit mode.
        if (!isAddWidget) {
            inputBox.setText(text);
        }
        inputBox.getTextBox().addBlurHandler(new BlurHandler() {
            @Override
            public void onBlur(BlurEvent arg0) {
                switchMode(VIEW_MODE);
            }
        });
        inputBox.getTextBox().addKeyDownHandler(new KeyDownHandler() {
            @Override
            public void onKeyDown(KeyDownEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    switchMode(VIEW_MODE);
                } else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
                    if (isAddWidget) {
                        inputBox.setText("");
                    } else {
                        inputBox.setText(label.getText());
                    }
                    switchMode(VIEW_MODE);
                }
            }
        });
        // Explicitly does not call switchMode to avoid logic inside that function that would think
        // we have switched from edit mode to view mode.
        deckPanel.showWidget(VIEW_MODE);
        deckPanel.add(inputBox);

        contentPanel.add(deckPanel);

        if (!isAddWidget) {
            // Craft the delete button.
            image.setStyleName("tty-RemovableLabelDeleteImage");
            image.setUrl("images/x.png");
            image.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    setValue(null, true);
                }
            });
            contentPanel.add(image);
        }

        // Set some alignments to make the widget pretty.
        contentPanel.setCellVerticalAlignment(label, HasVerticalAlignment.ALIGN_MIDDLE);
        contentPanel.setCellVerticalAlignment(image, HasVerticalAlignment.ALIGN_MIDDLE);
        initWidget(contentPanel);
    }

    private void switchMode(int mode) {
        // Just keep them in view mode if they can't edit this widget.
        if (!canEdit) {
            deckPanel.showWidget(VIEW_MODE);
            return;
        }
        if (mode == VIEW_MODE) {
            String text = inputBox.getText();
            if (!text.equals(label.getText())) {
                // Don't save an empty label.
                if (!"".equals(text)) {
                    // We have updates to save.
                    setValue(inputBox.getText(), true);
                }
            }
        }
        int width = label.getOffsetWidth();
        deckPanel.showWidget(mode);
        if (mode == EDIT_MODE) {
            inputBox.setWidth(String.valueOf(String.valueOf(width)) + "px");
            inputBox.setFocus(true);
        }
    }

    public void setEditable(boolean canEdit) {
        this.canEdit = canEdit;
        image.setVisible(canEdit);
    }

    /**
     * Sets the list of suggestions for the autocomplete box.
     * @param suggestions list of items to suggest off of.
     */
    public void setLabelSuggestions(Collection<String> suggestions) {
        oracle.clear();
        oracle.addAll(suggestions);
    }

    @Override
    public String getValue() {
        return label.getText();
    }

    @Override
    public void setValue(String value) {
        setValue(value, false);
    }

    @Override
    public void setValue(String value, boolean fireEvents) {
        String old = label.getText();
        label.setText(value);
        inputBox.setText(value);
        if (fireEvents) {
            ValueChangeEvent.fireIfNotEqual(this, old, value);
        }
    }

    /**
     * Will fire when value of text changes or delete is clicked (the value will be null if deleted).
     */
    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
        return addHandler(handler, ValueChangeEvent.getType());
    }
}