Java tutorial
/******************************************************************************* * 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); } }