Use of Calendar requires two tasks after creating a
Calendar
instance: setting a time range for it and
providing the calendar events. The time range controls its view mode; whether
it is a daily, weekly, or monthly view.
The view mode is controlled by the date range of the calendar. The weekly view is the default view mode. You can change the range by setting start and end dates for the calendar. The range must be between one and 60 days.
In the following, we set the calendar to show only one day, which is the current day.
cal.setStartDate(new Date()); cal.setEndDate(new Date());
Notice that although the range we set above is actually zero time long, the calendar still renders the time from 00:00 to 23:59. This is normal, as the Vaadin Calendar is guaranteed to render at least the date range provided, but may expand it. This behaviour is important to notice when we implement our own event providers.
The first thing the you will probably notice about the Calendar is that it is rather empty at first. The Calendar allows three different ways to add events:
Calendar
object using
the addEvent()
Container
as a data source
The easiest way to add and manage events in a calendar is to use the basic
event management API in the Calendar
. You can add
events with addEvent()
and remove them with the
removeEvent()
. These methods will use the
underlying event provider to write the modifications to the data source.
For example, the following adds a two-hour event starting from the current
time. The standard Java GregorianCalendar
provides
various ways to manipulate date and time.
// Add a short event GregorianCalendar start = new GregorianCalendar(); GregorianCalendar end = new GregorianCalendar(); end.add(java.util.Calendar.HOUR, 2); calendar.addEvent(new BasicEvent("Calendar study", "Learning how to use Vaadin Calendar", start.getTime(), end.getTime()));
Calendar uses by default a BasicEventProvider
,
which keeps the events in memory in an internal reprensetation.
This adds a new event that lasts for 3 hours. As the BasicEventProvider and BasicEvent implement some optional event interfaces provided by the calendar package, there is no need to refresh the calendar. Just create events, set their properties and add them to the Event Provider.
You can use any Vaadin Container
that
implements the Indexed
interface as the
data source for calendar events. The Calendar
will
listen to change events from the container as well as write changes to the
container. You can attach a container to a Calendar
with setContainerDataSource()
.
In the following example, we bind a
BeanItemContainer
that contains built-in
BasicEvent
events to a calendar.
// Create the calendar Calendar calendar = new Calendar("Bound Calendar"); // Use a container of built-in BasicEvents final BeanItemContainer<BasicEvent> container = new BeanItemContainer<BasicEvent>(BasicEvent.class); // Create a meeting in the container container.addBean(new BasicEvent("The Event", "Single Event", new GregorianCalendar(2012,1,14,12,00).getTime(), new GregorianCalendar(2012,1,14,14,00).getTime())); // The container must be ordered by the start time. You // have to sort the BIC every time after you have added // or modified events. container.sort(new Object[]{"start"}, new boolean[]{true}); calendar.setContainerDataSource(container, "caption", "description", "start", "end", "styleName");
The container must either use the default property IDs for event data, as
defined in the CalendarEvent
interface, or
provide them as parameters for the
setContainerDataSource()
method, as we did in the
example above.
The events in the container must be kept ordered by their start date/time. Failing to do so may and will result in the events not showing in the calendar properly.
Ordering depends on the container. With some containers, such as
BeanItemContainer
, you have to sort the
container explicitly every time after you have added or modified
events, usually with the sort()
method, as we
did in the example above. Some container, such as
JPAContainer
, keep the in container
automatically order if you provide a sorting rule.
For example, you could order a JPAContainer
by
the following rule, assuming that the start date/time is held in the
startDate
property:
// The container must be ordered by start date. For JPAContainer // we can just set up sorting once and it will stay ordered. container.sort(new String[]{"startDate"}, new boolean[]{true});
Setting a container as the calendar data source with
setContainerDataSource()
automatically switches
to ContainerEventProvider
. You can manipulate the
event data through the API in Calendar
and the user
can move and resize event through the user interface. The event provider
delegates all such calendar operations to the container.
If you add events through the Calendar
API,
notice that you may be unable to create events of the type held in the
container or adding them requires some container-specific
operations. In such case, you may need to customize the
addEvent()
method.
For example, JPAContainer
requires adding new
items with addEntity()
. You could first add
the entity to the container or entity manager directly and then pass
it to the addEvent()
. That does not, however,
work if the entity class does not implement
CalendarEvent
. This is actually the
case always if the property names differ from the ones defined in the
interface. You could handle creating the underlying entity objects in
the addEvent()
as follows:
// Create a JPAContainer final JPAContainer<MyCalendarEvent> container = JPAContainerFactory.make(MyCalendarEvent.class, "book-examples"); // Customize the event provider for adding events // as entities ContainerEventProvider cep = new ContainerEventProvider(container) { @Override public void addEvent(CalendarEvent event) { MyCalendarEvent entity = new MyCalendarEvent( event.getCaption(), event.getDescription(), event.getStart(), event.getEnd(), event.getStyleName()); container.addEntity(entity); } } // Set the container as the data source calendar.setEventProvider(cep); // Now we can add events to the database through the calendar BasicEvent event = new BasicEvent("The Event", "Single Event", new GregorianCalendar(2012,1,15,12,00).getTime(), new GregorianCalendar(2012,1,15,14,00).getTime()); calendar.addEvent(event);