org.springframework.ide.eclipse.boot.wizard.guides.ChooseOneSectionTable.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.boot.wizard.guides.ChooseOneSectionTable.java

Source

/*******************************************************************************
 * Copyright (c) 2013 GoPivotal, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    GoPivotal, Inc. - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.boot.wizard.guides;

import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.internal.misc.StringMatcher;
import org.eclipse.ui.internal.misc.StringMatcher.Position;
import org.springframework.ide.eclipse.boot.wizard.content.Describable;
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
import org.springsource.ide.eclipse.commons.livexp.core.SelectionModel;
import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult;
import org.springsource.ide.eclipse.commons.livexp.ui.ChooseOneSectionCombo;
import org.springsource.ide.eclipse.commons.livexp.ui.IPageWithSections;

/**
 * Wizard section to choose one element from list of elements. Uses a table viewer to allow selecting
 * an element.
 * <p>
 * This class is very similar in functionality (from client's point of view) to {@link ChooseOneSectionCombo}.
 * It should be possible to use either one of these classes as functional replacements for one another.
 */
@SuppressWarnings("restriction")
public class ChooseOneSectionTable<T> extends ChooseOneSection {

    private class ChoicesFilter extends ViewerFilter {

        private StringMatcher matcher = null;

        public ChoicesFilter() {
            if (searchBox != null) {
                setSearchTerm(searchBox.getText());
            }
        }

        public void setSearchTerm(String text) {
            matcher = new StringMatcher(text, true, false);
        }

        @Override
        public boolean select(Viewer viewer, Object parentElement, Object element) {
            if (matcher == null) {
                return true;
            } else {
                String label = labelProvider.getText(element);
                if (match(label)) {
                    return true;
                } else if (element instanceof Describable) {
                    String description = ((Describable) element).getDescription();
                    return match(description);
                }
                return false;
            }
        }

        private boolean match(String text) {
            if (matcher == null) {
                return true; // Search term not set... anything is acceptable.
            } else {
                Position x = matcher.find(text, 0, text.length());
                return x != null;
            }
        }

    }

    private SelectionModel<T> selection;
    private String label; //Descriptive Label for this section
    private T[] options; //The elements to choose from
    private Text searchBox;
    private ChoicesFilter filter;

    public ChooseOneSectionTable(IPageWithSections owner, String label, SelectionModel<T> selection, T[] options) {
        super(owner);
        this.label = label;
        this.selection = selection;
        this.options = options;
    }

    @Override
    public LiveExpression<ValidationResult> getValidator() {
        return selection.validator;
    }

    @Override
    public void createContents(Composite page) {
        Composite field = new Composite(page, SWT.NONE);
        int cols = label == null ? 1 : 2;
        GridLayout layout = GridLayoutFactory.fillDefaults().numColumns(cols).create();
        field.setLayout(layout);

        searchBox = new Text(field, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL);
        GridDataFactory.fillDefaults().grab(true, false).applyTo(searchBox);

        Label fieldNameLabel = null;
        if (label != null) {
            fieldNameLabel = new Label(field, SWT.NONE);
            fieldNameLabel.setText(label);
        }

        final TableViewer tv = new TableViewer(field, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL);
        tv.addFilter(filter = new ChoicesFilter());
        tv.setLabelProvider(labelProvider);
        tv.setContentProvider(ArrayContentProvider.getInstance());
        tv.setInput(options);

        if (fieldNameLabel != null) {
            GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(fieldNameLabel);
        }
        GridDataFactory grab = GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 150);
        grab.applyTo(field);
        grab.applyTo(tv.getTable());

        whenVisible(tv.getControl(), new Runnable() {
            public void run() {
                T preSelect = selection.selection.getValue();
                if (preSelect != null) {
                    tv.setSelection(new StructuredSelection(preSelect), true);
                } else {
                    tv.setSelection(StructuredSelection.EMPTY, true);
                }
            }
        });

        tv.addSelectionChangedListener(new ISelectionChangedListener() {
            @SuppressWarnings("unchecked")
            public void selectionChanged(SelectionChangedEvent event) {
                ISelection sel = tv.getSelection();
                if (sel.isEmpty()) {
                    selection.selection.setValue(null);
                } else if (sel instanceof IStructuredSelection) {
                    IStructuredSelection ss = (IStructuredSelection) sel;
                    selection.selection.setValue((T) ss.getFirstElement());
                }
            }
        });

        searchBox.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                filter.setSearchTerm(searchBox.getText());
                tv.refresh();
            }
        });
    }

    private void whenVisible(final Control control, final Runnable runnable) {
        PaintListener l = new PaintListener() {
            public void paintControl(PaintEvent e) {
                runnable.run();
                control.removePaintListener(this);
            }
        };
        control.addPaintListener(l);
    }

    //   private String[] getLabels() {
    //      String[] labels = new String[options.length];
    //      for (int i = 0; i < labels.length; i++) {
    //         labels[i] = labelProvider.getText(options[i]);
    //      }
    //      return labels;
    //   }

}