You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vaadin FullCalendar插件addEntry功能失效问题求助

Vaadin FullCalendar 添加事件无效的解决方案

核心问题分析

你的代码存在两个关键问题导致事件无法正常添加:

  • 类型不匹配:初始化的是InMemoryEntryProvider<ResourceEntry>,但创建的事件对象是Entry类型,两者泛型类型不兼容,Provider无法正确处理非指定类型的对象。
  • 重复复用同一事件实例:始终修改同一个entryCustom对象并重复添加,Provider无法识别为新事件,甚至会引发重复引用问题。

修正后的代码实现

1. 统一事件对象类型

将Entry entryCustom = new Entry();改为ResourceEntry entryCustom = new ResourceEntry();,确保与Provider的泛型类型一致。

2. 优化Update按钮逻辑

根据需求分为两种场景处理:

场景1:每次点击添加新事件

InMemoryEntryProvider<ResourceEntry> entryProvider = new InMemoryEntryProvider<>();
calendar.setEntryProvider(entryProvider);
  
// 事件控制布局
HorizontalLayout entryControlsLayout = new HorizontalLayout();
entryControlsLayout.setSpacing(true);
entryControlsLayout.setAlignItems(Alignment.BASELINE);

Select<String> selectTitle = new Select<>();
DatePicker datePickerStart = new DatePicker("inzio");
DatePicker datePickerEnd = new DatePicker("fine");
TimePicker timePicker = new TimePicker("Select Time");
TimePicker timePickerEnd = new TimePicker("Select Time");
datePickerStart.setValue(LocalDate.now());
datePickerEnd.setValue(LocalDate.now());
timePicker.setValue(LocalTime.now());
timePickerEnd.setValue(LocalTime.now());
selectTitle.setLabel("Ordina Come");
selectTitle.setItems("Primo più recente", "Rating: high to low", "Rating: low to high", "Price: high to low", "Price: low to high");
selectTitle.setValue("Primo più recente");

Button updateButton = new Button("Update", e -> {
   // 每次点击创建新的事件实例
   ResourceEntry newEntry = new ResourceEntry();
   newEntry.setTitle(selectTitle.getValue());
   newEntry.setColor("#ff3333");
   newEntry.setStartEditable(true);
   
   // 处理时间,确保结束时间不早于开始时间
   LocalDateTime start = datePickerStart.getValue().atTime(timePicker.getValue());
   LocalDateTime end = datePickerEnd.getValue().atTime(timePickerEnd.getValue());
   if (end.isBefore(start)) {
       end = start.plusHours(1);
   }
   
   newEntry.setStart(start);
   newEntry.setEnd(end);
   // 使用提前定义的entryProvider,避免重复类型转换
   entryProvider.addEntries(newEntry);
});

Button removeButton = new Button("Remove", e -> {
   // 如果需要删除选中事件,可结合事件选中监听实现(见场景2)
   // 此处示例为删除最后添加的事件,或根据业务逻辑调整
});

entryControlsLayout.add(selectTitle, datePickerStart, datePickerEnd, timePicker, timePickerEnd, updateButton, removeButton );

场景2:编辑选中的现有事件

如果需要支持编辑日历中已选中的事件,添加事件选中监听:

// 跟踪当前编辑的事件
ResourceEntry currentEditingEntry = null;

// 监听日历事件选中
calendar.addEntrySelectedListener(event -> {
   currentEditingEntry = event.getEntry();
   // 将选中事件的信息填充到表单
   selectTitle.setValue(currentEditingEntry.getTitle());
   datePickerStart.setValue(currentEditingEntry.getStart().toLocalDate());
   timePicker.setValue(currentEditingEntry.getStart().toLocalTime());
   datePickerEnd.setValue(currentEditingEntry.getEnd().toLocalDate());
   timePickerEnd.setValue(currentEditingEntry.getEnd().toLocalTime());
});

// 修改Update按钮逻辑为编辑模式
Button updateButton = new Button("Update", e -> {
   if (currentEditingEntry != null) {
       // 更新现有事件
       currentEditingEntry.setTitle(selectTitle.getValue());
       LocalDateTime start = datePickerStart.getValue().atTime(timePicker.getValue());
       LocalDateTime end = datePickerEnd.getValue().atTime(timePickerEnd.getValue());
       if (end.isBefore(start)) {
           end = start.plusHours(1);
       }
       currentEditingEntry.setStart(start);
       currentEditingEntry.setEnd(end);
       // 通知Provider更新事件
       entryProvider.refreshEntry(currentEditingEntry);
   } else {
       // 无选中事件则添加新事件
       ResourceEntry newEntry = new ResourceEntry();
       newEntry.setTitle(selectTitle.getValue());
       newEntry.setColor("#ff3333");
       newEntry.setStartEditable(true);
       LocalDateTime start = datePickerStart.getValue().atTime(timePicker.getValue());
       LocalDateTime end = datePickerEnd.getValue().atTime(timePickerEnd.getValue());
       if (end.isBefore(start)) {
           end = start.plusHours(1);
       }
       newEntry.setStart(start);
       newEntry.setEnd(end);
       entryProvider.addEntries(newEntry);
   }
});

// 修改Remove按钮逻辑
Button removeButton = new Button("Remove", e -> {
   if (currentEditingEntry != null) {
       entryProvider.removeEntries(currentEditingEntry);
       currentEditingEntry = null;
       // 清空表单
       selectTitle.setValue("Primo più recente");
       datePickerStart.setValue(LocalDate.now());
       datePickerEnd.setValue(LocalDate.now());
       timePicker.setValue(LocalTime.now());
       timePickerEnd.setValue(LocalTime.now());
   }
});

其他注意事项

  • 直接使用初始化的entryProvider变量,避免每次调用calendar.getEntryProvider().asInMemory(),减少类型转换风险。
  • 确保事件结束时间不早于开始时间,否则FullCalendar可能无法正确渲染事件。
  • 原样式设置代码无问题,可保留原有逻辑。

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:17:06