/* * Copyright (c) 2002-2015, JIDE Software Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package jidefx.scene.control.searchable; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.scene.control.ListView; import javafx.scene.control.SelectionMode; /** * {@code ListViewSearchable} is an concrete implementation of {@link Searchable} that enables the search function * on ListView. <p>It's very simple to use it. Assuming you have a ListView, all you need to do is to call * <pre>{@code * ListView list = ....; * ListViewSearchable searchable = new ListViewSearchable(list); * }</pre> * Now the ListView will have the search function. * <p> * There is very little customization you need to do to ListViewSearchable. The only thing you might need is when the * element in the ListView needs a special conversion to convert to string. If so, you can override * convertElementToString() to provide you own algorithm to do the conversion. * <pre>{@code * ListView list = ....; * ListViewSearchable searchable = new ListViewSearchable(list) { * protected String convertElementToString(Object object) { * ... * } * }; * }</pre> * <p> * * @param <T> the element type in the ListView. */ @SuppressWarnings({"Convert2Lambda", "unchecked"}) public class ListViewSearchable<T> extends Searchable<T> { private ListChangeListener<T> _listChangeListener; private ChangeListener<ObservableList<T>> _itemsChangeListener; public ListViewSearchable(ListView<T> listView) { super(listView); } @Override public void installListeners() { super.installListeners(); if (_listChangeListener == null) { _listChangeListener = new ListChangeListener<T>() { @Override public void onChanged(Change<? extends T> c) { hidePopup(); } }; } ((ListView<T>) _node).getItems().addListener(_listChangeListener); if (_itemsChangeListener == null) { _itemsChangeListener = new ChangeListener<ObservableList<T>>() { @Override public void changed(ObservableValue<? extends ObservableList<T>> observable, ObservableList<T> oldValue, ObservableList<T> newValue) { hidePopup(); } }; } ((ListView<T>) _node).itemsProperty().addListener(_itemsChangeListener); } @Override public void uninstallListeners() { if (_listChangeListener != null) { ((ListView<T>) _node).getItems().removeListener(_listChangeListener); _listChangeListener = null; } if (_itemsChangeListener != null) { ((ListView<T>) _node).itemsProperty().removeListener(_itemsChangeListener); _itemsChangeListener = null; } super.uninstallListeners(); } @Override protected int getSelectedIndex() { return ((ListView<T>) _node).getSelectionModel().getSelectedIndex(); } @Override protected void setSelectedIndex(int index, boolean incremental) { ListView<T> listView = (ListView<T>) _node; if (incremental) { listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); listView.getSelectionModel().select(index); listView.scrollTo(index); } else { listView.getSelectionModel().clearSelection(index); listView.getSelectionModel().select(index); listView.scrollTo(index); } } @Override protected int getElementCount() { return ((ListView<T>) _node).getItems().size(); } @Override protected T getElementAt(int index) { return ((ListView<T>) _node).getItems().get(index); } @Override protected String convertElementToString(T element) { return element != null ? element.toString() : ""; } }