/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2014, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotoolkit.gui.javafx.util; import java.io.File; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.logging.Level; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; import javafx.stage.FileChooser; import org.geotoolkit.internal.Loggers; /** * Allow user to specify a file path using an auto-completed text field. * He can also choose a path using a system dialog, which open thanks to a button * on the right of the text field. Another button allow to open the chosen file * with a system application. * * User can specify a relative path if the {@link #rootPath} is initialized with * the base path to use. * * Note : It's not its purpose, but you can also use distant URL as text field * content. No completion will be proposed, but you will be able to use system * browser to visit specified URI. * * @author Alexis Manin (Geomatys) */ public class FXFileTextField extends AbstractPathTextField { /** * A root path from which auto-completor will base on to display possible values to user. */ public final SimpleStringProperty rootPath = new SimpleStringProperty(); public FXFileTextField() { rootPath.addListener(this::updateRoot); } /** * Update completor root path when {@link #rootPath} is updated. * @param obs * @param oldValue * @param newValue */ private void updateRoot(final ObservableValue<? extends String> obs, final String oldValue, final String newValue) { if (newValue == null || newValue.isEmpty()) { completor.root = null; } else { completor.root = Paths.get(newValue); } } /** * Open a file chooser from root path (or user home if the root is null), to * allow user to specify its path using system tools. * @return The file path chosen by the user, or null. */ @Override protected String chooseInputContent() { final FileChooser chooser = new FileChooser(); try { URI uriForText = getURIForText(getText()); final Path basePath = Paths.get(uriForText); if (Files.isDirectory(basePath)) { chooser.setInitialDirectory(basePath.toFile()); } else if (Files.isDirectory(basePath.getParent())) { chooser.setInitialDirectory(basePath.getParent().toFile()); } } catch (Exception e) { Loggers.JAVAFX.log(Level.FINE, "Root path cannot be decoded.", e); } File returned = chooser.showOpenDialog(null); if (returned == null) { return null; } else { return (completor.root != null)? completor.root.relativize(returned.toPath()).toString() : returned.getAbsolutePath(); } } @Override protected URI getURIForText(String inputText) throws Exception { if (rootPath.get() == null) { return inputText.matches("[A-Za-z]+://.+")? new URI(inputText) : Paths.get(inputText).toUri(); } else { return Paths.get(rootPath.get(), inputText == null? "" : inputText).toUri(); } } }