com.google.devtools.depan.platform.eclipse.ui.widgets.MapChoiceControl.java Source code

Java tutorial

Introduction

Here is the source code for com.google.devtools.depan.platform.eclipse.ui.widgets.MapChoiceControl.java

Source

/*
 * Copyright 2016 The Depan Project Authors
 *
 * 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.devtools.depan.platform.eclipse.ui.widgets;

import com.google.devtools.depan.platform.AlphabeticSorter;
import com.google.devtools.depan.platform.ViewerObjectToString;

import com.google.common.collect.Lists;

import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Provide a ComboViewer dropdown control for a {@link Map} of values.
 * The keys from the map provide the labels, and 
 * 
 * @author <a href="leeca@pnambic.com">Lee Carver</a>
 */
public abstract class MapChoiceControl<T> extends Composite {

    private static ControlLabelProvider CONTROL_LABEL_PROVIDER = new ControlLabelProvider();

    private final ComboViewer viewer;

    private ControlSelectionChangedListener listener;

    /**
     * Derived types must override this class to cast a proposed result to the
     * concrete type specified by {@code <T>}.  (Generic type erasure cannot
     * coerce instances to their concrete types.)
     */
    protected abstract T coerceResult(Object obj);

    public MapChoiceControl(Composite parent) {
        super(parent, SWT.NONE);
        setLayout(new FillLayout());

        viewer = new ComboViewer(this, SWT.READ_ONLY | SWT.FLAT);
        viewer.setContentProvider(new ControlContentProvider());
        viewer.setLabelProvider(CONTROL_LABEL_PROVIDER);
        viewer.setComparator(new AlphabeticSorter(new ViewerObjectToString() {

            @Override
            public String getString(Object object) {
                return CONTROL_LABEL_PROVIDER.getText(object);
            }
        }));

        listener = new ControlSelectionChangedListener();
        viewer.addSelectionChangedListener(listener);
    }

    public void setInput(T selection, Map<String, T> contributions) {
        viewer.setInput(contributions);
        StructuredSelection selector = buildSelection(selection, contributions);
        setSelection(selector);
    }

    /**
     * Derived classes use this to implement type-specific selection.
     */
    protected void setSelection(StructuredSelection selector) {
        viewer.setSelection(selector);
    }

    protected StructuredSelection buildSelection(T selection, Map<String, ? extends T> contributions) {
        if (null == selection) {
            return null;
        }
        for (Entry<String, ? extends T> item : contributions.entrySet()) {
            if (selection == item.getValue()) {
                return (new StructuredSelection(item));
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public T getChoice() {
        Map.Entry<String, T> choice = (Map.Entry<String, T>) listener.getChoice();
        if (null != choice) {
            return coerceResult(choice.getValue());
        }
        return null;
    }

    private static class ControlLabelProvider extends LabelProvider {
        @SuppressWarnings("unchecked")
        @Override
        public String getText(Object element) {
            if (element instanceof Map.Entry<?, ?>) {
                Entry<String, ?> item = (Map.Entry<String, ?>) element;
                return item.getKey();
            }

            // Not what was expected.
            return null;
        }
    }

    private class ControlContentProvider implements IStructuredContentProvider {

        @Override
        public void dispose() {
        }

        @Override
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }

        @SuppressWarnings("unchecked")
        @Override
        public Object[] getElements(Object inputElement) {
            if (inputElement instanceof Map<?, ?>) {
                Map<String, T> input = (Map<String, T>) inputElement;
                List<Map.Entry<String, T>> result = Lists.newArrayListWithExpectedSize(input.size());
                result.addAll(input.entrySet());
                return result.toArray();
            }

            // Not what was expected.
            return null;
        }
    }

    private class ControlSelectionChangedListener implements ISelectionChangedListener {

        private Object choice;

        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            ISelection selection = event.getSelection();
            choice = Selections.getFirstElement(selection, Object.class);
        }

        public Object getChoice() {
            return choice;
        }
    }
}