package rmblworx.tools.timey.gui; import java.io.File; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.ResourceBundle; import javafx.application.Platform; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.DatePicker; import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; import javafx.stage.FileChooser; import javafx.stage.Stage; import javafx.util.StringConverter; import rmblworx.tools.timey.gui.component.TimePicker; /* * Copyright 2014-2015 Christian Raue * MIT License http://opensource.org/licenses/mit-license.php */ /** * Controller für den Dialog zum Bearbeiten eines Alarms. * @see <a href="http://code.makery.ch/java/javafx-2-tutorial-part3/">JavaFX 2 Tutorial - Part 3: Interacting with the User</a> * @author Christian Raue {@literal <christian.raue@gmail.com>} */ public class AlarmEditDialogController extends Controller { /** * Fenster des Dialogs. */ private Stage dialogStage; /** * Bereits existierende Alarme. */ private List<Alarm> existingAlarms; /** * Der zu bearbeitende Alarm. */ private Alarm alarm; /** * Der gewählte Klingelton. */ private final SimpleStringProperty ringtone = new SimpleStringProperty(""); /** * Ob der Alarm geändert wurde. */ private boolean changed = false; @FXML private ResourceBundle resources; @FXML private CheckBox alarmEnabledCheckbox; @FXML private DatePicker alarmDatePicker; @FXML private TimePicker alarmTimePicker; @FXML private TextField alarmDescriptionTextField; @FXML private Button alarmSelectSoundButton; @FXML private Button alarmNoSoundButton; @FXML private Button alarmPlaySoundButton; @FXML private void initialize() { alarmDatePicker.setPromptText(resources.getString("alarmEdit.datePicker.placeholder")); alarmDatePicker.setConverter(new StringConverter<LocalDate>() { private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); public LocalDate fromString(final String string) { if (string != null && !string.isEmpty()) { return LocalDate.parse(string, dateFormatter); } return null; } public String toString(final LocalDate date) { if (date != null) { return dateFormatter.format(date); } return ""; } }); ringtone.addListener(new ChangeListener<String>() { public void changed(final ObservableValue<? extends String> property, final String oldValue, final String newValue) { alarmSelectSoundButton.setText(newValue == null ? resources.getString("sound.noSoundSelected.text") : newValue); alarmSelectSoundButton.setTooltip(newValue == null ? null : new Tooltip(newValue)); alarmNoSoundButton.setDisable(newValue == null); alarmPlaySoundButton.setDisable(newValue == null); } }); ringtone.set(null); } public void setDialogStage(final Stage dialogStage) { this.dialogStage = dialogStage; } /** * @param existingAlarms bereits existierende Alarme */ public void setExistingAlarms(final List<Alarm> existingAlarms) { this.existingAlarms = existingAlarms; } /** * Setzt den Alarm und überträgt dessen Werte auf die Steuerelemente. * @param alarm Alarm */ public void setAlarm(final Alarm alarm) { this.alarm = alarm; Platform.runLater(new Runnable() { public void run() { alarmEnabledCheckbox.setSelected(alarm.isEnabled()); alarmDatePicker.setValue(DateTimeUtil.getDatePart(alarm.getDateTime())); alarmTimePicker.setValue(DateTimeUtil.getTimePart(alarm.getDateTime())); alarmDescriptionTextField.setText(alarm.getDescription()); ringtone.set(alarm.getSound()); } }); } public void setRingtone(final String aRingtone) { Platform.runLater(new Runnable() { public void run() { ringtone.set(aRingtone); } }); } /** * @return ob der Alarm geändert wurde */ public final boolean isChanged() { return changed; } /** * Aktion bei Klick auf Sound-Auswahl-Schaltfläche. */ @FXML private void handleSelectSoundButtonClick() { final FileChooser fileChooser = new FileChooser(); fileChooser.setTitle(resources.getString("sound.selectSound.title")); fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); fileChooser.getExtensionFilters().addAll( new FileChooser.ExtensionFilter("Sound", "*.aac", "*.aif", "*.aiff", "*.m3u8", "*.m4a", "*.mp3", "*.wav") ); final File file = fileChooser.showOpenDialog(dialogStage); if (file != null) { ringtone.set(file.getPath()); } } /** * Aktion bei Klick auf Sound-Löschen-Schaltfläche. */ @FXML private void handleNoSoundButtonClick() { ringtone.set(null); } /** * Aktion bei Klick auf Sound-Abspielen-Schaltfläche. */ @FXML private void handlePlaySoundButtonClick() { getGuiHelper().playSoundInThread(ringtone.get(), resources); } /** * Aktion bei Klick auf Speichern-Schaltfläche. */ @FXML private void handleSaveButtonClick() { if (isInputValid()) { alarm.setEnabled(alarmEnabledCheckbox.isSelected()); alarm.setDateTime(getDateTimeFromPickers()); alarm.setDescription(alarmDescriptionTextField.getText()); alarm.setSound(ringtone.get()); changed = true; if (dialogStage != null) { dialogStage.close(); } } } /** * Aktion bei Klick auf Abbrechen-Schaltfläche. */ @FXML private void handleCancelButtonClick() { if (dialogStage != null) { dialogStage.close(); } } /** * @return kombinierter Zeitstempel aus DatePicker und TimePicker */ private LocalDateTime getDateTimeFromPickers() { return LocalDateTime.of(alarmDatePicker.getValue(), alarmTimePicker.getValue()); } /** * @return ob die Daten gültig sind */ private boolean isInputValid() { final StringBuilder errors = new StringBuilder(); if (alarmDatePicker.getValue() == null) { errors.append(resources.getString("alarmEdit.date.empty")); errors.append('\n'); } if (alarmDatePicker.getValue() != null) { final LocalDateTime selectedDateTime = getDateTimeFromPickers(); if (alarmEnabledCheckbox.isSelected() && selectedDateTime.isBefore(LocalDateTime.now())) { errors.append(resources.getString("alarmEdit.alarmTimestampMustBeInFuture")); errors.append('\n'); } if (existingAlarms != null) { for (final Alarm existingAlarm : existingAlarms) { if (alarm != existingAlarm && selectedDateTime.equals(existingAlarm.getDateTime())) { errors.append(resources.getString("alarmEdit.otherAlarmWithSameTimestampAlreadyExists")); errors.append('\n'); break; } } } } if (errors.length() > 0) { // Fehlermeldungen anzeigen getGuiHelper().showDialogMessage(resources.getString("messageDialog.error.title"), errors.toString(), resources); return false; } return true; } }