/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2015, 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.parameter; import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Date; import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.scene.Node; import org.apache.sis.util.UnconvertibleObjectException; import org.geotoolkit.gui.javafx.util.FXDateField; /** * * @author Alexis Manin (Geomatys) */ public class FXDateEditor extends FXValueEditor { static final Class[] SUPPORTED_CLASSES = new Class[]{Date.class, LocalDate.class, LocalDateTime.class}; private final SimpleObjectProperty dateProperty = new SimpleObjectProperty(); private final FXDateField editor = new FXDateField(); public FXDateEditor(final Spi spi) { super(spi); dateProperty.addListener((ObservableValue observable, Object oldValue, Object newValue) -> { if (editor.valueProperty().isBound()) return; // Do not throw exception, because user has set editor property as a target for one of his own property. if (newValue == null) editor.valueProperty().set(null); else if (newValue instanceof LocalDateTime) editor.valueProperty().set((LocalDateTime)newValue); else if (newValue instanceof LocalDate) editor.valueProperty().set(((LocalDate)newValue).atStartOfDay()); else if (newValue instanceof Date) { editor.valueProperty().set(new Timestamp(((Date)newValue).getTime()).toLocalDateTime()); } else throw new UnconvertibleObjectException("Cannot convert from "+newValue.getClass() + " to "+LocalDateTime.class); }); editor.valueProperty().addListener((ObservableValue<? extends LocalDateTime> observable, LocalDateTime oldValue, LocalDateTime newValue) -> { if (dateProperty.isBound()) return; // Do not throw exception, because user has set exposed property as a target for one of his own property. if (newValue == null) { dateProperty.set(null); } else { Class valueClass = getValueClass(); if (valueClass == null) dateProperty.set(newValue); // TODO : throw an exception ? editor has not been configured, but user already started to work with it. else if (LocalDateTime.class.isAssignableFrom(valueClass)) dateProperty.set(newValue); else if (LocalDate.class.isAssignableFrom(valueClass)) dateProperty.set(newValue.toLocalDate()); else if (Date.class.isAssignableFrom(valueClass)) dateProperty.set(Timestamp.valueOf(newValue)); } }); } @Override public Property valueProperty() { return dateProperty; } @Override public Node getComponent() { return editor; } /** * SPI */ public static final class Spi extends FXValueEditorSpi { @Override public boolean canHandle(Class binding) { for (final Class c : SUPPORTED_CLASSES) { if (c.isAssignableFrom(binding)) return true; } return false; } @Override public FXValueEditor createEditor() { return new FXDateEditor(this); } } }