Wednesday, May 6, 2015

GWT - SelectActionCell. ActionCell with options menu

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import org.gwtbootstrap3.client.ui.constants.ButtonSize;
import org.gwtbootstrap3.client.ui.constants.ButtonType;

import java.util.*;

public class SelectActionCell<T> extends AbstractCell<T> {
  
    private static final String ACTION_LIST = "Action List";
    private static Template template;
    private final Map<String, ActionItem<T>> actionItemMap;
    private final ButtonType type;
    private final ButtonSize size;
    private final String buttonLabel;

    public SelectActionCell(List<ActionItem<T>> options, String buttonLabel, ButtonType type, ButtonSize size) {
        super(BrowserEvents.CLICK);
        if (template == null) {
            template = GWT.create(Template.class);
        }
        this.actionItemMap = createActionItemMap(options);
        this.buttonLabel = buttonLabel;
        this.type = type;
        this.size = size;
    }

    public SelectActionCell(List<ActionItem<T>> options, String buttonLabel, ButtonType type) {
        this(options, buttonLabel, type, ButtonSize.DEFAULT);
    }

    public SelectActionCell(List<ActionItem<T>> options, String buttonLabel) {
        this(options, buttonLabel, ButtonType.INFO);
    }

    public SelectActionCell(List<ActionItem<T>> options) {
        this(options, ACTION_LIST);
    }

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

        super.onBrowserEvent(context, parent, value, event, valueUpdater);

        if (BrowserEvents.CLICK.equals(event.getType())) {
            EventTarget eventTarget = event.getEventTarget();
            if (!Element.is(eventTarget)) {
                return;
            }
            Element targetElement = Element.as(eventTarget);
            ActionItem<T> actionItem = actionItemMap.get(targetElement.getId());
            if (actionItem != null && actionItem.getDelegate() != null) {
                actionItem.getDelegate().execute(value);
            }
        }
    }

    @Override
    public void render(Context context, T value, SafeHtmlBuilder sb) {
        String cssClasses = "btn" + " " + type.getCssName() + " " + size.getCssName() + " " + "dropdown-toggle";

        sb.appendHtmlConstant("<div class=\"btn-group\">");

        sb.appendHtmlConstant("<button type=\"button\" class=\"" + cssClasses + "\"data-toggle=\"dropdown\">");
        sb.appendHtmlConstant(buttonLabel + " <span class=\"caret\"></span>");
        sb.appendHtmlConstant("</button>");
        sb.appendHtmlConstant("<ul class=\"dropdown-menu\">");

        addAvailableActions(value, sb);

        sb.appendHtmlConstant("</ul>");
        sb.appendHtmlConstant("</div>");
    }

    private void addAvailableActions(T value, SafeHtmlBuilder sb) {
        for (Map.Entry<String, ActionItem<T>> entry : actionItemMap.entrySet()) {
            ActionDelegate<T> actionDelegate = entry.getValue().getDelegate();
            if (actionDelegate.isActive(value)) {
                sb.append(template.selectItem(entry.getKey(), entry.getValue().getLabel()));
            }
        }
    }

    private Map<String, ActionItem<T>> createActionItemMap(List<ActionItem<T>> actionItems) {
        Map<String, ActionItem<T>> map = new HashMap<String, ActionItem<T>>(actionItems.size());
        for (ActionItem<T> actionItem : actionItems) {
            map.put(actionItem.getLabel(), actionItem);
        }
        return map;
    }

    interface Template extends SafeHtmlTemplates {
        @Template("<li><a id =\"{0}\">{1}</a></li>")
        SafeHtml selectItem(String id, String value);
    }
}

========================= ACTION_DELEGATE ========================

public interface ActionDelegate<T> {

    /**
     * Perform the desired action on the given object.
     *
     * @param object the object to be acted upon
     */
    void execute(T object);

    /**
     * Check the object of access to action.
     *
     * @param object the object to be acted upon
     * @return access
     */
    boolean isActive(T object);
}

==================== ACTION_ITEM ========================

public class ActionItem<T> {

    private final String label;
    private final ActionDelegate<T> delegate;

    public ActionItem(String label, ActionDelegate<T> delegate) {
        this.label = label;
        this.delegate = delegate;
    }

    public String getLabel() {
        return label;
    }

    public ActionDelegate<T> getDelegate() {
        return delegate;
    }
}


No comments: