I'm using JFXtras CalendarPicker to get dates for multiple days in the calendar. My project is a JavaFX project and I'm using an FXML, in that the CalendarPicker is linked to my Controller class. In details, this is my FXML:
<CalendarPicker fx:id="calendarpicker" mode="MULTIPLE" />
In my controller class, I'm using a EventHandler inside the initialize() method:
public void initialize() {
this.dateFormat = new SimpleDateFormat("yyyy-mm-dd");
calendarpicker.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (event.getButton().equals(MouseButton.PRIMARY)) {
Calendar cal = calendarpicker.getCalendar();
if(cal != null){
String formattedDate = dateFormat.format(cal.getTime());
ObservableList<String> items = listview.getItems();
if (!items.contains(formattedDate)) {
items.add(formattedDate);
} else {
items.remove(formattedDate);
}
listview.setItems(items);
}
}
}
});
}
So in JFXtras the CalendarPicker dates inside the calendar looks like buttons, on one click (you press down the button), but when you release it it doesn't come up. If you click again on the pressed down button it will come up. I have a ListView (named as "listview") what I want to populate with the dates when I click on the calendar day it should add the date to the list. If the date is NOT on the list I want to add it. If it is already on the list (so the button is already pressed down), and I click on it again, it should remove that date from the list.
The problem is that my code doesn't behave as expected, probably because this two stage action (pressing down and pressing again to come up). I have no clue how to fix it, so I kindly ask for help.
There is no need to implement all this yourself. The calendarPicker
exposes an ObservableList<Calendar>
representing all the selected Calendar
instances. Simply use this list as the backing list for your ListView
:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import jfxtras.scene.control.CalendarPicker;
import java.io.IOException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Calendar;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
CalendarPicker calendarPicker = new CalendarPicker();
calendarPicker.setMode(CalendarPicker.Mode.MULTIPLE);
ListView<Calendar> dates = new ListView<>();
dates.setItems(calendarPicker.calendars());
dates.setCellFactory(lv -> new ListCell<>(){
private DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
@Override
protected void updateItem(Calendar item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
} else {
setText(formatter.format(LocalDate.ofInstant(item.toInstant(), ZoneId.systemDefault())));
}
}
});
BorderPane root = new BorderPane(dates);
root.setTop(calendarPicker);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}