/* * 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.hints; import javafx.collections.FXCollections; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; import javafx.scene.control.TextInputControl; import javafx.util.Callback; import java.io.File; import java.io.FilenameFilter; /** * {@code FileIntelliHints} is a concrete implementation of {@link IntelliHints}. It * allows user to type in a file patch quickly by providing them the hints based on what is existed on file system. You * can use {@link #setFolderOnly(boolean)} to control if the hints contain only the folders, or folders and files. */ @SuppressWarnings("Convert2Lambda") public class FileIntelliHints extends AbstractListIntelliHints<String> { private boolean _folderOnly = false; private boolean _showFullPath = true; private FilenameFilter _filter; public FileIntelliHints(TextInputControl comp) { super(comp); } /** * If the hints contain the folder names only. * * @return true if the hints contain the folder names only. */ public boolean isFolderOnly() { return _folderOnly; } /** * Sets the property of folder only. If true, the hints will only show the folder names. Otherwise, both folder and * file names will be shown in the hints. * * @param folderOnly only provide hints for the folders. */ public void setFolderOnly(boolean folderOnly) { _folderOnly = folderOnly; } /** * If the hints contain the full path. * * @return true if the hints contain the full path. */ public boolean isShowFullPath() { return _showFullPath; } /** * Sets the property of showing full path. If true, the hints will show the full path. Otherwise, it will only show * the path after user typed in so far. * * @param showFullPath whether show the full path. */ public void setShowFullPath(boolean showFullPath) { _showFullPath = showFullPath; } public boolean updateHints(Object value) { if (value == null) { return false; } String s = value.toString(); if (s.length() == 0) { return false; } int index1 = s.lastIndexOf('\\'); int index2 = s.lastIndexOf('/'); int index = Math.max(index1, index2); if (index == -1) return false; final String dir = s.substring(0, index + 1); final String prefix = index == s.length() - 1 ? null : s.substring(index + 1).toLowerCase(); String[] files = new File(dir).list(new FilenameFilter() { public boolean accept(File dir, String name) { if (isFolderOnly()) { if (new File(dir.getAbsolutePath() + File.separator + name).isFile()) { return false; } } boolean result = prefix == null || name.toLowerCase().startsWith(prefix); if (result && getFilter() != null) { return getFilter().accept(dir, name); } return result; } }); if (files == null || files.length == 0 || (files.length == 1 && files[0].equalsIgnoreCase(prefix))) { setAvailableHints(null); return false; } else { if (isShowFullPath()) { getListView().setCellFactory(new Callback<ListView<String>, ListCell<String>>() { @Override public ListCell<String> call(ListView<String> param) { return new ListCell<String>() { @Override protected void updateItem(String item, boolean empty) { super.updateItem(item, empty); setText(item == null ? "" : dir + item); } }; } }); } setAvailableHints(FXCollections.<String>observableArrayList(files)); return true; } } @Override public void acceptHint(String selected) { if (selected == null) return; String selectedValue = "" + selected; String value = getTextInputControl().getText(); int caretPosition = getTextInputControl().getCaretPosition(); int index1 = value.lastIndexOf('\\', caretPosition); int index2 = value.lastIndexOf('/', caretPosition); int index = Math.max(index1, index2); if (index == -1) { return; } int prefixLength = caretPosition - index - 1; getTextInputControl().insertText(caretPosition, selectedValue.substring(prefixLength)); } /** * Get FilenameFilter configured to this hints. * <p> * By default, it returns null. You could set this field to let the IntelliHints only show the files meet your * criteria. * * @return the FilenameFilter in use. */ public FilenameFilter getFilter() { return _filter; } /** * Set FilenameFilter to this hints. * * @param filter the FilenameFilter in use. * @see #getFilter() */ public void setFilter(FilenameFilter filter) { _filter = filter; } }