Domanda È disponibile un selettore di data e ora per javaFx?


Sono nuovo di Java e ho iniziato a sviluppare applicazioni in java usando javaFx. ha cercato molto ma non è riuscito a trovare alcun selettore di data e ora in javaFx. Anche io ho provato JFxtras ma non funziona. Tra l'altro sto usando javafx 2.2.3 e java 7. Qualsiasi aiuto sarebbe molto apprezzato.


10
2018-02-13 05:31


origine


risposte:


Ecco una versione Java del controllo DateTimePicker sopra, leggermente migliorata.

Questo codice è ora parte di TornadoFX Controls e puoi dare un'occhiata all'ultima versione di DateTimePicker.java nel GitHub Repo. Il controllo è disponibile anche in Maven Central sotto queste coordinate:

<dependency>
    <groupId>no.tornado</groupId>
    <artifactId>tornadofx-controls</artifactId>
    <version>1.0.3</version>
</dependency>

L'implementazione in questo momento:

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.DatePicker;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.util.StringConverter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * A DateTimePicker with configurable datetime format where both date and time can be changed
 * via the text field and the date can additionally be changed via the JavaFX default date picker.
 */
@SuppressWarnings("unused")
public class DateTimePicker extends DatePicker {
    public static final String DefaultFormat = "yyyy-MM-dd HH:mm";

    private DateTimeFormatter formatter;
    private ObjectProperty<LocalDateTime> dateTimeValue = new SimpleObjectProperty<>(LocalDateTime.now());
    private ObjectProperty<String> format = new SimpleObjectProperty<String>() {
        public void set(String newValue) {
            super.set(newValue);
            formatter = DateTimeFormatter.ofPattern(newValue);
        }
    };

    public DateTimePicker() {
        getStyleClass().add("datetime-picker");
        setFormat(DefaultFormat);
        setConverter(new InternalConverter());

        // Syncronize changes to the underlying date value back to the dateTimeValue
        valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                dateTimeValue.set(null);
            } else {
                if (dateTimeValue.get() == null) {
                    dateTimeValue.set(LocalDateTime.of(newValue, LocalTime.now()));
                } else {
                    LocalTime time = dateTimeValue.get().toLocalTime();
                    dateTimeValue.set(LocalDateTime.of(newValue, time));
                }
            }
        });

        // Syncronize changes to dateTimeValue back to the underlying date value
        dateTimeValue.addListener((observable, oldValue, newValue) -> {
            setValue(newValue == null ? null : newValue.toLocalDate());
        });

        // Persist changes onblur
        getEditor().focusedProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue)
                simulateEnterPressed();
        });

    }

    private void simulateEnterPressed() {
        getEditor().fireEvent(new KeyEvent(getEditor(), getEditor(), KeyEvent.KEY_PRESSED, null, null, KeyCode.ENTER, false, false, false, false));
    }

    public LocalDateTime getDateTimeValue() {
        return dateTimeValue.get();
    }

    public void setDateTimeValue(LocalDateTime dateTimeValue) {
        this.dateTimeValue.set(dateTimeValue);
    }

    public ObjectProperty<LocalDateTime> dateTimeValueProperty() {
        return dateTimeValue;
    }

    public String getFormat() {
        return format.get();
    }

    public ObjectProperty<String> formatProperty() {
        return format;
    }

    public void setFormat(String format) {
        this.format.set(format);
    }

    class InternalConverter extends StringConverter<LocalDate> {
        public String toString(LocalDate object) {
            LocalDateTime value = getDateTimeValue();
            return (value != null) ? value.format(formatter) : "";
        }

        public LocalDate fromString(String value) {
            if (value == null) {
                dateTimeValue.set(null);
                return null;
            }

            dateTimeValue.set(LocalDateTime.parse(value, formatter));
            return dateTimeValue.get().toLocalDate();
        }
    }
}

Il dateTimeValue proprietà contiene il valore con il tempo e il valueProperty contiene solo il valore della data.

Non ho ancora aggiunto test per questo componente, quindi l'implementazione potrebbe cambiare, controlla GitHub per l'ultima versione.


8
2018-02-25 21:56



Il progetto JFXtras ha una versione funzionante per JavaFX 2.2. Cercare CalendarPicker, CalendarTimePicker, ... al pronti contro termine, sotto il ramo 2.2.

Puoi testarlo scaricando l'ultima versione (2.2-R6-SNAPSHOT) a partire dal jfxtras.org.

Questo breve snippet creerà un calendario per il prelievo di data e ora:

@Override
public void start(Stage primaryStage) {
    CalendarPicker dateTime = new CalendarPicker();
    dateTime.withCalendar(Calendar.getInstance());
    dateTime.withShowTime(Boolean.TRUE);
    dateTime.withLocale(Locale.ENGLISH);
    dateTime.calendarProperty().addListener(new ChangeListener<Calendar>() {

        @Override
        public void changed(ObservableValue<? extends Calendar> ov, Calendar t, Calendar t1) {
            System.out.println("Selected date: "+t1.getTime().toString());
        }
    });
    StackPane root = new StackPane();
    root.getChildren().add(dateTime);

    Scene scene = new Scene(root, 300, 250);
    primaryStage.setTitle("Date & Time from JFXtras 2.2");
    primaryStage.setScene(scene);
    primaryStage.show();
}

Date and Time


5
2018-02-13 10:00



Trovo più comodo inserire l'ora tramite la tastiera invece di cambiarla con i cursori. È abbastanza semplice estendere il DatePicker incluso in questo modo:

DateTimePicker for JavaFX 8

Trovo anche fastidioso che DatePicker non impegni il valore modificato nel campo di testo di onblur, quindi anche il codice seguente risolve il problema.

Lo snippet è scritto in Kotlin per brevità, puoi facilmente convertirlo in Java tramite IntelliJ IDEA:

import javafx.beans.property.SimpleObjectProperty
import javafx.scene.control.DatePicker
import javafx.scene.input.KeyCode
import javafx.scene.input.KeyEvent
import javafx.scene.input.MouseEvent
import javafx.util.StringConverter
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter

class DateTimePicker(val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) : DatePicker() {
    private var dateTimeValue = SimpleObjectProperty<LocalDateTime>(LocalDateTime.now())

    init {
        converter = object : StringConverter<LocalDate>() {
            override fun toString(value: LocalDate?): String {
                return if (dateTimeValue.get() != null) dateTimeValue.get().format(formatter) else ""
            }

            override fun fromString(value: String?): LocalDate? {
                if (value == null) {
                    dateTimeValue.set(null)
                    return null
                }

                dateTimeValue.set(LocalDateTime.parse(value, formatter))
                return dateTimeValue.get().toLocalDate()
            }
        }

        // Syncronize changes to the underlying date value back to the dateTimeValue
        valueProperty().addListener { observable, old, new ->
            if (new == null) {
                dateTimeValue.set(null)
            } else {
                if (dateTimeValue.get() == null) {
                    dateTimeValue.set(LocalDateTime.of(new, LocalTime.now()))
                } else {
                    val time = dateTimeValue.get().toLocalTime()
                    dateTimeValue.set(LocalDateTime.of(new, time))
                }
            }
        }

        // Syncronize changes to dateTimeValue back to the underlying date value
        dateTimeValue.addListener { observable, old, new ->
            valueProperty().set(new?.toLocalDate())
        }

        // Persist changes onblur
        editor.focusedProperty().addListener { observable, old, new ->
            if (!new)
                simulateEnterPressed()
        }

    }

    private fun simulateEnterPressed() =
        editor.fireEvent(KeyEvent(editor, editor, KeyEvent.KEY_PRESSED, null, null, KeyCode.ENTER, false, false, false, false))

    fun dateTimeValueProperty() = dateTimeValue;
}

Associare la proprietà LocalDateTime alla dataTimeValueProperty.


4
2017-11-27 09:11



Versione leggermente "migliorata" (almeno per i miei bisogni) che funziona con NullableTimeStamp ... per poterlo, nullo, annullarlo (per facilità con MySQL) ...

Non so se questo può aiutare nessuno ma eccolo qui:

NullableTimeStamp:

public class NullableTimestamp extends Timestamp {

    public NullableTimestamp() {
        super(0L);
    }
    public NullableTimestamp(long value) {
        super(value);
    }

    @Override
    public String toString() {
        return this.getTime() > 0L ? super.toString() : "";
    }

    public static NullableTimestamp valueOf(LocalDateTime localDateTime) {
        return new NullableTimestamp(Timestamp.valueOf(localDateTime).getTime());
    }
}

e DateTimePicker:

public class DateTimePicker extends DatePicker {
    public static final String DefaultFormat = "yyyy-MM-dd HH:mm";

    private DateTimeFormatter formatter;
    private ObjectProperty<LocalDateTime> dateTimeValue = new SimpleObjectProperty<>(LocalDateTime.now());
    private ObjectProperty<String> format = new SimpleObjectProperty<String>() {
        public void set(String newValue) {
            super.set(newValue);
            formatter = DateTimeFormatter.ofPattern(newValue);
        }
    };

    public DateTimePicker() {
        getStyleClass().add("datetime-picker");
        setFormat(DefaultFormat);
        setConverter(new InternalConverter());

        // Syncronize changes to the underlying date value back to the dateTimeValue
        valueProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                dateTimeValue.set(null);
            } else {
                if (dateTimeValue.get() == null) {
                    dateTimeValue.set(LocalDateTime.of(newValue, LocalTime.now()));
                } else {
                    LocalTime time = dateTimeValue.get().toLocalTime();
                    dateTimeValue.set(LocalDateTime.of(newValue, time));
                }
            }
        });

        // Syncronize changes to dateTimeValue back to the underlying date value
        dateTimeValue.addListener((observable, oldValue, newValue) -> {
            setValue(newValue == null ? null : newValue.toLocalDate());
        });

        // Persist changes onblur
        getEditor().focusedProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue)
                simulateEnterPressed();
        });

    }

    private void simulateEnterPressed() {
        getEditor().fireEvent(new KeyEvent(getEditor(), getEditor(), KeyEvent.KEY_PRESSED, null, null, KeyCode.ENTER, false, false, false, false));
    }

    public LocalDateTime getDateTimeValue() {
        return dateTimeValue.get();
    }

    public void setDateTimeValue(LocalDateTime dateTimeValue) {
        if(dateTimeValue.isAfter(LocalDateTime.of(1971, 6, 30, 12, 00)))
            this.dateTimeValue.set(dateTimeValue);
        else
            this.dateTimeValue.set(null);
    }

    public ObjectProperty<LocalDateTime> dateTimeValueProperty() {
        return dateTimeValue;
    }

    public String getFormat() {
        return format.get();
    }

    public ObjectProperty<String> formatProperty() {
        return format;
    }

    public void setFormat(String format) {
        this.format.set(format);
    }

class InternalConverter extends StringConverter<LocalDate> {
    public String toString(LocalDate object) {

        LocalDateTime value = getDateTimeValue();
        return (value != null) ? value.format(formatter) : "";
    }

    public LocalDate fromString(String value) {
        if (value == null) {
            dateTimeValue.set(null);
            return null;
        }

        dateTimeValue.set(LocalDateTime.parse(value, formatter));
        return dateTimeValue.get().toLocalDate();
        }
    }
}

In pratica maschera il valore 0L Timestamp come se fosse NULL ... spero che questo possa aiutare gli evviva


3
2017-11-12 12:59