refactor: simplified dayCellFactory for date selector

Instead of generating a list of dates for every single visible date and checking if it is contained in that list, we now use a (admittedly scary-looking) predicate to compare the date to the start and enddates
This commit is contained in:
David Guler
2022-11-15 15:25:51 +01:00
parent 05e7bcc2e8
commit 90d2de65de
4 changed files with 62 additions and 63 deletions
@@ -7,7 +7,7 @@ import javafx.scene.control.*;
import javafx.util.Callback;
import java.time.LocalDate;
import java.util.List;
import java.time.MonthDay;
public class SelectSowDayController {
private Plant selectedPlant;
@@ -61,36 +61,49 @@ public class SelectSowDayController {
/**
* date picker disable/enable dates according to selected plant: sow or harvest day
*
* @return cellFactory of datePicker
*/
private Callback<DatePicker, DateCell> getDayCellFactory() {
return (datePicker) -> new DateCell() {
private final LocalDate today = LocalDate.now();
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
setDisable(true);
setStyle("-fx-background-color: #ffc0cb;");
List<LocalDate> dates;
LocalDate today = LocalDate.now();
if (harvest_radio.isSelected()) {
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.HARVEST);
} else {
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.SOW);
}
for (LocalDate date : dates) {
if (item.getMonth() == date.getMonth()
&& item.getDayOfMonth() == date.getDayOfMonth()
&& item.compareTo(today) > 0) {
if (item.compareTo(today) > 0 && (!harvest_radio.isSelected() || selectedPlant.sowDateFromHarvestDate(item, 0).compareTo(today) >= 0)) {
GrowthPhaseType selectedPhase = harvest_radio.isSelected() ? GrowthPhaseType.HARVEST : GrowthPhaseType.SOW;
MonthDay minDate = selectedPlant.getMinDateForGrowthPhase(selectedPhase);
MonthDay maxDate = selectedPlant.getMaxDateForGrowthPhase(selectedPhase);
if (dateInRange(item, minDate, maxDate)) {
setDisable(false);
setStyle("-fx-background-color: #32CD32;");
}
}
if ((harvest_radio.isSelected() && selectedPlant.sowDateFromHarvestDate(item, 0).compareTo(today) < 0)) {
setDisable(true);
setStyle("-fx-background-color: #ffc0cb;");
}
}
};
}
/**
* Checks if the given {@link LocalDate} is within the given {@link MonthDay} range.
* (regardless of year)
*
* @param subject The date to check
* @param min The start of the date-range
* @param max The end of the date-range
* @return Whether the subject is within the range.
*/
private boolean dateInRange(LocalDate subject, MonthDay min, MonthDay max) {
return subject.getMonth().compareTo(min.getMonth()) >= 0 &&
subject.getMonth().compareTo(max.getMonth()) <= 0 &&
// if the day is less than the minimum day, the minimum month must not be equal
(subject.getDayOfMonth() >= min.getDayOfMonth() || !subject.getMonth().equals(min.getMonth())) &&
// if the day is greater than the maximum day, the maximum month must not be equal
(subject.getDayOfMonth() <= max.getDayOfMonth() || !subject.getMonth().equals(max.getMonth()));
}
}