dlsc-software-consulting-gmbh / CalendarFX

A Java framework for creating sophisticated calendar views (JavaFX 8, 9, 10, and 11)
http://www.dlsc.com
Apache License 2.0
780 stars 171 forks source link

Event Handlers #207

Open StoicBug opened 8 months ago

StoicBug commented 8 months ago

I'm trying to do CRUD operation with my sql database using CalendarFX, I tried many approaches but still the documentation is not that helpful and I tried a lot, here is my Controller for the CalendarFX:

`java package com.taskhub.taskhub.controllers;

import com.calendarfx.model.*; import com.calendarfx.view.DayView; import com.taskhub.taskhub.dao.EventDao; import com.taskhub.taskhub.dao.EventDaoImpl; import com.taskhub.taskhub.dao.model.Event; import com.taskhub.taskhub.dao.service.IEventsService; import com.taskhub.taskhub.dao.service.IServiceEventsImpl; import javafx.application.Platform; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.layout.StackPane; import com.calendarfx.view.CalendarView; import com.calendarfx.model.Entry;

import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalTime;

public class CalendarController {

@FXML
private StackPane calendarContainer;

private Calendar calendar;

IEventsService eventService = new IServiceEventsImpl(new EventDaoImpl());

public void initialize() {
    calendar = new Calendar("My Calendar");

    // Load existing events from the database
    loadAndDisplayEvents();

    // Set up listeners for event changes
    setUpEventListeners();

    CalendarView calendarView = new CalendarView();
    CalendarSource myCalendarSource = new CalendarSource("My Calendars");
    myCalendarSource.getCalendars().add(calendar);
    calendarView.getCalendarSources().setAll(myCalendarSource);

    StackPane.setMargin(calendarView, javafx.geometry.Insets.EMPTY);
    StackPane.setAlignment(calendarView, javafx.geometry.Pos.CENTER);
    calendarContainer.getChildren().add(calendarView);
}

private void loadAndDisplayEvents() {
    for (com.taskhub.taskhub.dao.model.Event event : eventService.getEvents()) {
        Entry<String> calendarEntry = new Entry<>(event.getTitle());
        calendarEntry.setInterval(event.getStartTime().toLocalDate(), event.getStartTime().toLocalTime(), event.getEndTime().toLocalDate(), event.getEndTime().toLocalTime());
        calendar.addEntry(calendarEntry);
    }
}

private void setUpEventListeners() {
    // Listener for new entries
    /*
    calendar.addEventHandler(CalendarEvent.ENTRY_CALENDAR_CHANGED, evt -> {
        if (evt.isEntryAdded()) {
            Entry<?> newEntry = evt.getEntry();
            // Convert CalendarFX Entry to your Event model and save to database
            Event newEvent = convertToEventModel(newEntry);
            System.out.println("New Event: " + newEvent);
            eventService.addEvent(newEvent);
        }
    });
    */
    // Listener for entry removal
    calendar.addEventHandler(CalendarEvent.ENTRY_CALENDAR_CHANGED, evt -> {
        if (evt.isEntryRemoved()) {
            Entry<?> removedEntry = evt.getEntry();
            // Convert CalendarFX Entry to your Event model and delete from database
            Event removedEvent = convertToEventModel(removedEntry);
            eventService.deleteEvent(removedEvent.getId());
        }
    });
}

private Event convertToEventModel(Entry<?> entry){
    Event event = new Event();
    event.setTitle(entry.getTitle());
    event.setStartTime(Timestamp.valueOf(entry.getStartAsLocalDateTime()).toLocalDateTime());
    event.setEndTime(Timestamp.valueOf(entry.getEndAsLocalDateTime()).toLocalDateTime());
    event.setAllDay(entry.isFullDay());
    if (entry.getRecurrenceRule() != null) {
        event.setRecurrence(entry.getRecurrenceRule().toString());
    } else {
        event.setRecurrence(null);
    }
    return event;
}

}

`

Nyde commented 7 months ago

I have the same issue.

I can see the events firing in the developer console, but none of my handlers is getting called (or at least, the desired action is not performed).

But I'm a bit confused at this point: A CalendarView.addEventHandler takes two arguments, the CalendarEvent and the handler itself. The Calendar.addEventHandler just takes one argument.

But as @dlemmermann stated at #129 , you need to add the event to the calendar, not the view; but at this point I wonder, how do I filter for a specific event, and, what is CalendarView.addEventHandler(CalendarEvent, handler) for then? I tried adding the event handler to the calendar, but it still gets ignored by any events.

urlaub.addEventHandler(evt -> System.out.println(evt));

LoadEvents on the view are working just fine.

StoicBug commented 7 months ago

Yes, I did manage to solve the problem like you mentioned I need to add the event handler to the calendar not the view:

private void setUpEventListeners() {
        EventHandler<CalendarEvent> addHandler = new EventHandler<CalendarEvent>() {
            @Override
            public void handle(CalendarEvent event) {
                if (event.isEntryAdded()) {
                    Entry<?> newEntry = event.getEntry();
                    // Convert CalendarFX Entry to your Event model and save to database
                    Event newEvent = convertToEventModel(newEntry);
                    System.out.println("New Event: " + newEvent);
                    // block code for 7 seconds
                    eventService.addEvent(newEvent);
                }
            }
        };
        calendar.addEventHandler(addHandler);
    }

But still, I didn't find a solution to filter between the types of events (add, delete, update...), I was trying to build functions my self to detect the type of event but it got too complex.

Nyde commented 7 months ago

Yes, I did manage to solve the problem like you mentioned I need to add the event handler to the calendar not the view:

private void setUpEventListeners() {
        EventHandler<CalendarEvent> addHandler = new EventHandler<CalendarEvent>() {
            @Override
            public void handle(CalendarEvent event) {
                if (event.isEntryAdded()) {
                    Entry<?> newEntry = event.getEntry();
                    // Convert CalendarFX Entry to your Event model and save to database
                    Event newEvent = convertToEventModel(newEntry);
                    System.out.println("New Event: " + newEvent);
                    // block code for 7 seconds
                    eventService.addEvent(newEvent);
                }
            }
        };
        calendar.addEventHandler(addHandler);
    }

But still, I didn't find a solution to filter between the types of events (add, delete, update...), I was trying to build functions my self to detect the type of event but it got too complex.

Thank you. I changed it to

EventHandler<CalendarEvent> addHandler = new EventHandler<CalendarEvent>() {
            @Override
            public void handle(CalendarEvent event) {
                if(event.getEventType() == CalendarEvent.ENTRY_TITLE_CHANGED)
                {
                    System.out.println("New title: " + event.getEntry().getTitle()); 
                }
            }
        };

and finally got it working for now.