com.dawg6.gwt.client.widgets.AbstractSearchable.java Source code

Java tutorial

Introduction

Here is the source code for com.dawg6.gwt.client.widgets.AbstractSearchable.java

Source

/*******************************************************************************
 * Copyright (c) 2014, 2015 Scott Clarke (scott@dawg6.com).
 *
 * This file is part of Dawg6's Common GWT Libary.
 *
 * Dawg6's Common GWT Libary is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Dawg6's Common GWT Libary is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package com.dawg6.gwt.client.widgets;

import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import com.dawg6.gwt.common.util.Filter;
import com.dawg6.gwt.common.util.ValueFactory;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.google.gwt.view.client.SingleSelectionModel;

public abstract class AbstractSearchable<T> extends Composite {

    private final CellList<T> listBox;
    private final List<T> list;
    private final ValueFactory<T> factory;
    private Filter<T> filter;
    private final Comparator<T> sorter;
    private final TextBox suggestBox;
    private final CaptionPanel captionPanel;
    private final SingleSelectionModel<T> selectionModel;
    private final ListDataProvider<T> dataProvider;
    private SelectionChangedHandler<T> handler = new SelectionChangedHandler<T>() {

        @Override
        public void selectionChanged(T value) {

            if (value != null) {
                int pos = scroll.getHorizontalScrollPosition();
                int index = dataProvider.getList().indexOf(value);

                if (index >= 0) {
                    Element rowElement = listBox.getRowElement(index);
                    rowElement.scrollIntoView();
                }

                scroll.setHorizontalScrollPosition(pos);
            }
        }
    };
    private final ScrollPanel scroll;

    public interface SelectionChangedHandler<T> {
        void selectionChanged(T value);
    }

    protected AbstractSearchable(ValueFactory<T> factory, Comparator<T> sorter) {

        captionPanel = new CaptionPanel("Caption");
        initWidget(captionPanel);

        VerticalPanel verticalPanel_5 = new VerticalPanel();
        captionPanel.setContentWidget(verticalPanel_5);
        verticalPanel_5.setSize("5cm", "3cm");

        HorizontalPanel row = new HorizontalPanel();
        row.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
        row.setSpacing(5);
        verticalPanel_5.add(row);

        Label label = new Label("Filter:");
        row.add(label);

        suggestBox = new TextBox();
        row.add(suggestBox);
        suggestBox.setVisibleLength(20);

        suggestBox.addKeyUpHandler(new KeyUpHandler() {

            @Override
            public void onKeyUp(KeyUpEvent event) {
                setFilter();
            }
        });

        Button button = new Button("Clear");
        row.add(button);
        button.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                suggestBox.setText("");
                setFilter();
            }
        });

        listBox = new CellList<T>(getCell());

        scroll = new ScrollPanel();
        scroll.setWidget(listBox);

        this.list = new Vector<T>();
        this.dataProvider = new ListDataProvider<T>();
        this.dataProvider.addDataDisplay(listBox);
        verticalPanel_5.add(scroll);
        listBox.setPageSize(Integer.MAX_VALUE);

        listBox.setSize("300px", "300px");
        selectionModel = new SingleSelectionModel<T>();
        listBox.setSelectionModel(selectionModel);

        selectionModel.addSelectionChangeHandler(new Handler() {

            @Override
            public void onSelectionChange(SelectionChangeEvent event) {
                selectionChanged(getSelectedValue());

            }
        });

        this.factory = factory;
        this.sorter = sorter;
    }

    protected void selectionChanged(T selectedValue) {
        handler.selectionChanged(selectedValue);
    }

    public void addSelectionChangedHandler(final SelectionChangedHandler<T> handler) {

        final SelectionChangedHandler<T> prev = this.handler;

        this.handler = new SelectionChangedHandler<T>() {

            @Override
            public void selectionChanged(T value) {
                prev.selectionChanged(value);
                handler.selectionChanged(value);
            }
        };
    }

    protected abstract Cell<T> getCell();

    public void setFilter(String text) {
        if ((text == null) || (text.length() == 0))
            setFilter((Filter<T>) null);
        else {
            final String lowerCase = text.toLowerCase();
            setFilter(new Filter<T>() {

                @Override
                public boolean match(T item) {
                    return factory.getDisplayString(item).toLowerCase().contains(lowerCase);
                }
            });
        }
    }

    protected void setFilter() {
        final String text = suggestBox.getText();
        setFilter(text);
    }

    public CellList<T> getListBox() {
        return listBox;
    }

    public String getCaption() {
        return captionPanel.getCaptionText();
    }

    public void setCaption(String text) {
        captionPanel.setCaptionText(text);
    }

    public void add(T item) {
        if (!list.contains(item))
            addItem(item);
    }

    public void remove(T item) {
        if (list.contains(item))
            removeItem(item);
    }

    private void removeItem(T item) {
        list.remove(item);

        int i = dataProvider.getList().indexOf(item);

        if (i >= 0) {
            dataProvider.getList().remove(i);

            int n = Math.min(i, dataProvider.getList().size() - 1);

            if (n >= 0) {
                T sel = dataProvider.getList().get(n);
                selectionModel.setSelected(sel, true);
            }
        }
    }

    private void addItem(T item) {
        list.add(item);

        if ((filter == null) || filter.match(item)) {

            int i = 0;
            Iterator<T> iter = dataProvider.getList().iterator();

            while (iter.hasNext()) {
                T j = iter.next();

                if (sorter.compare(j, item) > 0) {
                    break;
                }

                i++;
            }

            dataProvider.getList().add(i, item);
            this.selectionModel.setSelected(item, true);
        }
    }

    public void setFilter(Filter<T> filter) {

        this.dataProvider.getList().clear();
        this.filter = filter;

        for (T item : list) {

            if ((filter == null) || filter.match(item)) {
                dataProvider.getList().add(item);
            }
        }
    }

    public void clear() {
        this.dataProvider.getList().clear();
        this.list.clear();
        this.selectionChanged(null);
    }

    public T getSelectedValue() {
        return this.selectionModel.getSelectedObject();
    }

    public List<T> getDisplayed() {
        return new Vector<T>(dataProvider.getList());
    }

    public void addAll(List<T> list) {

        for (T t : list)
            add(t);
    }

    public void remove(List<T> list) {
        for (T t : list)
            remove(t);
    }

}