This example demonstrates all events exposed by Timeline.
<style>
    /* Custom styles for the Timeline */
    div.timeline-frame {
        border-color: #5D99C3;
        border-radius: 5px;
    }
    div.timeline-axis {
        border-color: #5D99C3;
        background-color: #5D99C3;
        filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5D99C3', endColorstr='#3A6DA0') alpha(opacity=100);
        background: -webkit-gradient(linear, left top, left bottom, from(#5D99C3), to(#3A6DA0));
        background: -moz-linear-gradient(top, #5D99C3, #3A6DA0);
        -khtml-opacity: 1;
        -moz-opacity: 1;
        opacity: 1;
    }
    div.timeline-groups-axis {
        border-color: #5D99C3;
    }
    div.timeline-groups-axis-onleft {
        border-style: none solid none none;
    }
    div.timeline-axis-text {
        color: white;
    }
    div.timeline-event {
        color: white !important;
        border-radius: 5px !important;
    }
    div.timeline-event-content {
        padding: 5px;
        text-shadow: none;
    }
    div.unavailable {
        background: #F03030 none !important; /* red */
        border-color: #bd2828 !important; /* red */
    }
    div.available {
        background: #1AA11A none !important; /* green */
        border-color: #136e13 !important; /* green */
    }
    div.maybe {
        background: #FFA500 none !important; /* orange */
        border-color: #cc8100 !important; /* orange */
    }
    div.timeline-event-selected {
        background: #BECEFE none !important;
        border-color: #97B0F8 !important;
    }
</style>
<h:form id="form">
    <p:growl id="growl" showSummary="true" showDetail="true"
        keepAlive="true" life="3000">
        <p:autoUpdate />
    </p:growl>
    <div class="card">
        <p:timeline id="timeline" value="#{allEventsTimelineView.model}"
            editable="true" eventMargin="10" eventMarginAxis="0"
            start="#{allEventsTimelineView.start}"
            end="#{allEventsTimelineView.end}" 
            stackEvents="false">
            <p:ajax event="add" listener="#{allEventsTimelineView.onAdd}" />
            <p:ajax event="changed" listener="#{allEventsTimelineView.onChanged}" />
            <p:ajax event="edit" listener="#{allEventsTimelineView.onEdit}" />
            <p:ajax event="delete" listener="#{allEventsTimelineView.onDelete}" />
            <p:ajax event="select" listener="#{allEventsTimelineView.onSelect}" />
            <p:ajax event="rangechanged" listener="#{allEventsTimelineView.onRangeChanged}" />
            <p:ajax event="lazyload" listener="#{allEventsTimelineView.onLazyLoad}" />
            <p:ajax event="drop" listener="#{allEventsTimelineView.onDrop}" />
        </p:timeline>
    </div>
</h:form>
package org.primefaces.showcase.view.data.timeline;
import org.primefaces.event.timeline.TimelineAddEvent;
import org.primefaces.event.timeline.TimelineDragDropEvent;
import org.primefaces.event.timeline.TimelineLazyLoadEvent;
import org.primefaces.event.timeline.TimelineModificationEvent;
import org.primefaces.event.timeline.TimelineRangeEvent;
import org.primefaces.event.timeline.TimelineSelectEvent;
import org.primefaces.model.timeline.TimelineEvent;
import org.primefaces.model.timeline.TimelineModel;
import org.primefaces.showcase.domain.Event;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
@Named("allEventsTimelineView")
@ViewScoped
public class AllEventsTimelineView implements Serializable {
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
    private TimelineModel<String, ?> model;
    private LocalDateTime start;
    private LocalDateTime end;
    @PostConstruct
    public void init() {
        // set initial start / end dates for the axis of the timeline
        start = LocalDateTime.now().minusHours(4);
        end = LocalDateTime.now().plusHours(8);
        // groups
        String[] names = new String[]{"User 1", "User 2", "User 3", "User 4", "User 5", "User 6"};
        // create timeline model
        model = new TimelineModel<>();
        for (String name : names) {
            LocalDateTime end = LocalDateTime.now().minusHours(12).withMinute(0).withSecond(0).withNano(0);
            for (int i = 0; i < 5; i++) {
                LocalDateTime start = end.plusHours(Math.round(Math.random() * 5));
                end = start.plusHours(4 + Math.round(Math.random() * 5));
                long r = Math.round(Math.random() * 2);
                String availability = (r == 0 ? "Unavailable" : (r == 1 ? "Available" : "Maybe"));
                // create an event with content, start / end dates, editable flag, group name and custom style class
                TimelineEvent event = TimelineEvent.builder()
                        .data(availability)
                        .startDate(start)
                        .endDate(end)
                        .editable(true)
                        .group(name)
                        .styleClass(availability.toLowerCase())
                        .build();
                model.add(event);
            }
        }
    }
    public void onAdd(TimelineAddEvent e) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        String dates =  e.getStartDate().format(FORMATTER);
        if (e.getEndDate() != null) {
            dates += " - " + e.getEndDate().format(FORMATTER);
        }
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "add", dates));
    }
    public void onChange(TimelineModificationEvent<String> e) {
        TimelineEvent<String> timelineEvent = e.getTimelineEvent();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "change",
                timelineEvent.getData() + ": " + timelineEvent.getStartDate().format(FORMATTER)
                + " - " + timelineEvent.getEndDate().format(FORMATTER)));
    }
    public void onChanged(TimelineModificationEvent<String> e) {
        TimelineEvent<String> timelineEvent = e.getTimelineEvent();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "changed",
                timelineEvent.getData() + ": " + timelineEvent.getStartDate().format(FORMATTER)
                + " - " + timelineEvent.getEndDate().format(FORMATTER)));
    }
    public void onEdit(TimelineModificationEvent<String> e) {
        TimelineEvent<String> timelineEvent = e.getTimelineEvent();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "edit",
                timelineEvent.getData() + ": " + timelineEvent.getStartDate().format(FORMATTER)
                + " - " + timelineEvent.getEndDate().format(FORMATTER)));
    }
    public void onDelete(TimelineModificationEvent<String> e) {
        TimelineEvent<String> timelineEvent = e.getTimelineEvent();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "delete",
                timelineEvent.getData() + ": " + timelineEvent.getStartDate().format(FORMATTER)
                + " - " + timelineEvent.getEndDate().format(FORMATTER)));
    }
    public void onSelect(TimelineSelectEvent<String> e) {
        TimelineEvent<String> timelineEvent = e.getTimelineEvent();
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "select",
                timelineEvent.getData() + ": " + timelineEvent.getStartDate().format(FORMATTER)
                + " - " + timelineEvent.getEndDate().format(FORMATTER)));
    }
    public void onRangeChange(TimelineRangeEvent e) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "rangechange",
                e.getStartDate().format(FORMATTER) + " - " + e.getEndDate().format(FORMATTER)));
    }
    public void onRangeChanged(TimelineRangeEvent e) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "rangechanged",
                e.getStartDate().format(FORMATTER) + " - " + e.getEndDate().format(FORMATTER)));
    }
    public void onLazyLoad(TimelineLazyLoadEvent e) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "lazyload",
                e.getStartDate().format(FORMATTER) + " - " + e.getEndDate().format(FORMATTER)));
    }
    public void onDrop(TimelineDragDropEvent<Event> e) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "drop",
                e.getData().getStart().format(FORMATTER) + " - " + e.getData().getEnd().format(FORMATTER)));
    }
    public TimelineModel<String, ?> getModel() {
        return model;
    }
    public LocalDateTime getStart() {
        return start;
    }
    public LocalDateTime getEnd() {
        return end;
    }
}