package de.saring.sportstracker.gui.dialogs; import java.time.LocalTime; import javafx.application.Platform; import javafx.fxml.FXML; import javafx.scene.control.DatePicker; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.control.TextFormatter; import javafx.stage.Window; import javax.inject.Inject; import org.controlsfx.validation.Validator; import de.saring.sportstracker.data.Note; import de.saring.sportstracker.gui.STContext; import de.saring.sportstracker.gui.STDocument; import de.saring.util.gui.javafx.TimeToStringConverter; /** * Controller (MVC) class of the Note dialog for editing / adding Note entries. * * @author Stefan Saring */ public class NoteDialogController extends AbstractDialogController { private final STDocument document; @FXML private DatePicker dpDate; @FXML private TextField tfTime; @FXML private TextArea taText; /** ViewModel of the edited Note. */ private NoteViewModel noteViewModel; /** * Standard c'tor for dependency injection. * * @param context the SportsTracker UI context * @param document the SportsTracker model/document */ @Inject public NoteDialogController(final STContext context, final STDocument document) { super(context); this.document = document; } /** * Displays the Note dialog for the passed Note instance. * * @param parent parent window of the dialog * @param note Note to be edited */ public void show(final Window parent, final Note note) { this.noteViewModel = new NoteViewModel(note); final String dlgTitleKey = note.getComment() == null ? "st.dlg.note.title.add" : "st.dlg.note.title"; final String dlgTitle = context.getResources().getString(dlgTitleKey); showEditDialog("/fxml/dialogs/NoteDialog.fxml", parent, dlgTitle); } @Override protected void setupDialogControls() { // setup binding between view model and the UI controls dpDate.valueProperty().bindBidirectional(noteViewModel.date); // use text formatter for time values => makes sure that the value is also valid final TextFormatter<LocalTime> timeTextFormatter = new TextFormatter<>(new TimeToStringConverter()); timeTextFormatter.valueProperty().bindBidirectional(noteViewModel.time); tfTime.setTextFormatter(timeTextFormatter); taText.textProperty().bindBidirectional(noteViewModel.comment); // setup validation of the UI controls // => due to a ControlsFX bug the validation setup must be executed after the dialog has been shown // (see https://bitbucket.org/controlsfx/controlsfx/issues/539/multiple-dialog-fields-with-validation ) Platform.runLater(() -> { validationSupport.registerValidator(dpDate, // Validator.createEmptyValidator(context.getResources().getString("st.dlg.note.error.date"))); validationSupport.registerValidator(tfTime, // Validator.createEmptyValidator(context.getResources().getString("st.dlg.note.error.time"))); validationSupport.registerValidator(taText, // Validator.createEmptyValidator(context.getResources().getString("st.dlg.note.error.no_text"))); }); } @Override protected boolean validateAndStore() { // store the new Note, no further validation needed final Note newNote = noteViewModel.getNote(); document.getNoteList().set(newNote); return true; } }