Как сделать календарь в javafx
Перейти к содержимому

Как сделать календарь в javafx

  • автор:

CalendarFX 8 Developer Manual

This is the CalendarFX developer manual. It aims to contain all the information required to quickly get a calendar UI into your application. If you notice any mistakes or if you are missing vital information then please let us know.

Calendar View

Distribution

CalendarFX is distributed as an archive (ZIP file). Once downloaded double click on the file to extract it. When you open the extracted folder you will see the following content.

Distribution

Contains the calendar.css file used for styling all controls in CalendarFX.

Several executable JAR files — double click to start the demo. If the applications do not start or you encounter problems try starting the demos from the command line like this «java -jar calendar-demo.jar».

The generated JavaDocs / API documentation. The docs are covering everything in great detail. Many screenshots can be found inside of them.

A folder with third-party libraries. ControlsFX is used for providing additional controls (e.g. MasterDetailPane, CustomTextField), some of which are the result of our work on CalendarFX and have been handed over as open source to the community (e.g. PopOver). The second JAR file includes the FontAwesome graphics and API. The third JAR file in the «ext» folder «license4j.jar» is used for supporting the licensing concept behind CalendarFX.

Contains the resource bundles (english, german).

A folder containing the licensing agreements (development, runtime, source code, research).

The CalendarFX JAR files.

Contains this document.

Logging and i18N information and resources.

Two JavaFX apps showing you how to get started with CalendarFX.

Installation

To use CalendarFX for your project, simply add the calendarfx JAR files found in the «lib» folder and all JAR files found in the «ext» folder to the classpath of your application. This is all that is needed, no further configuration required, at least not for the trial period of several months. After this period it will be necessary to set a license key as shown below. For buying options please refer to the website at http://www.calendarfx.com.

Quick Start

The following section shows you how to quickly setup a JavaFX application that will show a complete calendar user interface. It includes a day view, a week view, a month view, a year view, an agenda view, a calendar selection view, and a search UI.

Create the calendar view

Create one or more calendars

Set a style on each calendar (entries will use different colors)

Create a calendar source (e.g. «Google») and add calendars to it

Add calendars to the view

Model

The primary model classes in CalendarFX are «CalendarSource», «Calendar» and «Entry». A calendar source often represents a calendar account, for example an account with «Google Calendar» (http://calendar.google.com). A group consists of a list of calendars and each calendar manages any number of entries. An entry represents an event with a start date / time and an end date / time.

Entry

The «Entry» class encapsulates all information that is required to display an event or an appointment in any of the calendar views included in CalendarFX.

Calendar Entry

The properties of an entry are:

a unique identifier

The title / name of the event or appointment (e.g. «Dentist Appointment»)

The calendar to which the entry belongs.

A complex data type grouping together start date / time, end date / time, and a time zone.

A free text description of a location, for example «Manhatten, New York». This information can be used by Geo services to return coordinates so that the UI can display a map if needed.

A flag used to signal that the event is relevant for the entire day and that the start and end times are not relevant, for example a birthday or a holiday. Full day entries are displayed as shown below.

All Day View

Ensures that the user can not create entries with a duration of less than, for example, 15 minutes.

An arbitrary object which might be responsible for the creation of the entry in the first place.

A text representation of a recurrence pattern according to RFC 2445 («RRULE:FREQ=DAILY»)

This last property is very interesting. It allows the entry to express that it defines a recurence. The entry can specify that it will be repeated over and over again following a given pattern. For example: «every Monday, Tuesday and Wednesday of every week until December 31st». If an entry is indeed a recurring entry then it produces one or more «recurrences». These recurrences are created by the framework by invoking the Entry.createRecurrence() method. The result of this method is another Entry that will be configured with the same values as the source entry.

A flag that expresses whether the entry represents a recurrence or not.

A reference to the original source entry.

If an entry represents a recurrence of a source entry then this property will store an additional ID, normally the date where the recurrence occurs.

In addition to these properties several read-only properties are available for convenience.

Needed y to easily determine if an entry spans multiple days. This information is constantly needed in various places of the framework for display / layout purposes.

The date when the event begins (e.g. 5/12/2015).

The time of day when the event begins (e.g. 2:15pm).

The date when the event ends (e.g. 8/12/2015).

The time of day when the event ends (e.g. 6:45pm).

Calendar

The «Calendar» class is used to store entries in a binary interval tree. This data structure is not exposed to the outside. Instead methods exist on Calendar to add, remove, and find entries.

The following is a description of the main properties of the Calendar class:

The display name of the calendar, shown in several places within the UI.

A short version of the calendar name. By default it is set to be equal to the regular name, but if the application is using the swimlane layout then it might make sense to also define a short name due to limited space.

A flag for controlling whether entries can be added interactively in the UI or not. Setting this flag to false does not prevent the application itself to add entries.

Basically a name prefix for looking up different styles from the CSS file (calendar.css): «style1-«, «style2-«. The «Calendar» class defines a «Style» enumerator that can be used to easily set the value of this property with one of the predefined styles.

Look Ahead / Back Duration

Two properties of type «java.time.Duration» that are used in combination with the current system time in order to create a time interval. The calendar class uses this time interval inside of its findEntries(String searchTerm) method.

Adding and Removing Entries

To add an entry simply call the addEntry() method on calendar. Example:

To remove an entry call the removeEntry() method on calendar.

Alternatively you can simply set the calendar directly on the entry.

To remove the entry from its calendar simply set the calendar to null.

Finding Entries for a Time Interval

The calendar class provides a findEntries() method which receives a start date, an end date, and a time zone. The result of invoking this method is a map where the keys are the dates for which entries were found and the values are lists of entries on that day.

The result does not only contain entries that were previously added by calling the addEntry() method but also recurrence entries that were generated on-the-fly for those entries that define a recurrence rule.

Finding Entries for a Search String

The second findEntries() method accepts a search term as a parameter and is used to find entries that were previously added to the calendar and that match the term.

To find actual matches the method invokes the Entry.matches(String) method on all entries that are found within the time interval defined by the current date, the look back duration, and the look ahead duration.

Calendar Source

A calendar source is used for creating a group of calendars. A very typical scenario would be that a calendar source represents an online calendar account (e.g. Google calendar). Calendars can be added to a source by simply calling mySource.getCalendars().add(myCalendar).

Events

CalendarFX utilizes the JavaFX event model to inform the application about changes made in a calendar, about user interaction that might require loading of new data, and about user interaction that might require showing different views.

Calendar Events

An event type that indicates that a change was made to the data is probably the most obvious type that anyone would expect from a UI framework. In CalendarFX this event type is called CalendarEvent.

ANY : the super event type

CALENDAR_CHANGED : «something» inside the calendar changed, usually causing rebuild of views (example: calendar batch updates finished)

ENTRY_CHANGED : the super type for changes made to an entry

ENTRY_CALENDAR_CHANGED : the entry was assigned to a different calendar

ENTRY_FULL_DAY_CHANGED : the full day flag was changed (from true to false or vice versa)

ENTRY_INTERVAL_CHANGED : the time interval of the entry was changed (start date / time, end date / time)

ENTRY_LOCATION_CHANGED : the location of the entry has changed

ENTRY_RECURRENCE_RULE_CHANGED : the recurrence rule was modified

ENTRY_TITLE_CHANGED : the entry title has changed

ENTRY_USER_OBJECT_CHANGED : a new user object was set on the entry

Listeners for this event type can be added to calendars by calling:

Load Events

Load events are used by the framework to signal to the application that the UI requires data for a specific time interval. This can be very useful for implementing a lazy loading strategy. If the user switches from one month to another then an event of this type will be fired and the time bounds on this event will be the first and the last day of that month. The LoadEvent type only supports a single event type called LOAD.

Listeners for this event type can be registerd on any date control:

Request Events

A somewhat unique event class is RequestEvent. It is used by the controls of the framework to signal to other framework controls that the user wants to «jump» to another view. For example: the user clicks on the date shown for a day in the MonthView then the month view will fire a request event that informs the framework that the user wants to switch to the DayView to see more detail for that day.

DateControl

A calendar user interface hardly ever consists of just a single control. They are composed of several views, some showing a single day or a week or a month. In CalendarFX the CalendarView control consists of dedicated «pages» for a day, a week, a month, or a full year. Each one of these pages consists of one or more subtypes of DateControl. The following image shows a simplified view of the scene graph / the containment hierarchy.

Hierarchy View

To make all of these controls work together in harmony it is important that they share many properties. This is accomplished by JavaFX property binding. The class DateControl features a method called «bind» that ensures the dates and times shown by the controls are synchronized. But also that many of the customization featuers (e.g. node factories) are shared.

The following listing shows the implementation of the DateControl.bind() method to give you an idea how much is bound within CalendarFX.

Class Hierarchy

CalendarFX ships with many built-in views for displaying calendar information. All of these views inherit from DateControl. The class hierarchy can be seen in the following image:

Class Hierarchy

Current Date, Time, and Today

Each DateControl keeps track of the «current date» and «today». The current date is the date that the control is supposed to display to the user. «Today» is the date that the control assumes to be the actual date. «Today» defaults to the current system date (provided by the operating system) but it can be any date.

The «today» and «time» properties do not get updated by themselves. See the daemon thread created in the listing shown in the «Quick Start» section.

DateControl defines utility methods that allow for easy modification of the «current» date.

Adding Calendars / Sources

Even though the DateControl class provides a getCalendars() method this is not the place where calendars are being added. Instead always create calendar sources, add calendars to them, and then add the sources to the control. The «calendars» list is a read-only flat list representation of all calendars in all calendar sources. The «calendars» list gets updated by the framework.

Customizing or Replacing the PopOver

The DateControl class has built-in support for displaying a PopOver control when the user double clicks on a calendar entry. The content node of this PopOver can be replaced. It is normally used to show some basic entry details (e.g. start / end date, title, event location) but applications might have defined specialized entries with custom properties that require additional UI elements. This can be accomplished by the help of the PopOver content node factory.

If an application does not want to use the PopOver at all but instead display a standard dialog then there is a way of doing that, too. Simply register an entry details callback.

These two callbacks normally work hand in hand. The default implementation of the entry details callback is producing a PopOver and sets the content node on the PopOver via the help of the content node callback.

Context Menu Support

A common place for customization are context menus. The DateControl class produces a context menu via specialized callbacks. One callback is used to produce a menu for a given calendar entry, the second callback is used when the user triggers the context menu by clicking in the background of a DateControl.

The context menu callbacks are automatically shared among all date controls that are bound to each other. The same context menu code will execute for different views, the DayView, the MonthView, and so on. This means that the code that builds the context menu will need to check the parameter object that was passed to the callback to configure itself appropriately.

The same is true for basically all callbacks used by the DateControl.

Creating Entries

The user can create new entries by double clicking anywhere inside a DateControl. The actual work of creating a new entry instance is then delegated to a specialized entry factory that can be set on DateControl.

Once the entry factory has returned the new entry it will be added to the calendar that is being returned by the «default calendar» provider. This provider is also customizable via a callback.

Besides the double click creation the application can also programmatically request the DateControl to create a new entry at a given point in time. Two methods are available for this: createEntryAt(ZonedDateTime) and createEntryAt(ZonedDateTime, Calendar). The second method will ensure that the entry will be added to the given calendar while the first method will invoke the default calendar provider.

Creating Calendar Sources

The user might also wish to add another calendar source to the application. In this case the DateControl will invoke the calendar source factory. The default implementation of this factory does nothing more than to create a new instance of the standard CalendarSource class. Applications are free to return a specialization of CalendarSource instead (e.g. GoogleCalendarAccount). A custom factory might even prompt the user first with a dialog, e.g. to request user credentials.

The calendar source factory gets invoked when the method DateControl.createCalendarSource() gets invoked. The CalendarView class already provides a button in its toolbar that will call this method.

Entry Views

Entry views are JavaFX nodes that are representing calendar entries. There are several different types, all extending EntryViewBase:

Shown inside a DayView or WeekDayView control. These views can be customized by subclassing DayEntryViewSkin and overriding the createContent() method.

All Day Entry View

Shown inside the AllDayView control.

Month Entry View

Shown inside the MonthView control.

Calendar Views

The most fundamental views inside CalendarFX are of course the views used to display a day (24 hours), an entire week, a month, and a year.

Shows a 24 hour time period vertically. The control has several options that can be used to influence the layout of the hours. E.g.: it is possible to define hour ranges where the time will be compressed in order to save space on the screen (early and late hours are often not relevant). The view can also specify whether it wants to always show a fixed number of hours or a fixed height for each hour.

Day View

wraps the DayView control with several additional controls: an AllDayView, a TimeScaleView, a CalendarHeaderView, a ScrollBar and and (optional) AgendaView.

Detailed Day View

The name of this control is somewhat misleading, because it can show any number of WeekDayView instances, not just 5 or 7 but also 14 (two weeks) or 21 (three weeks). In this view entries can be easily edited to span multiple days.

Week View

same concept as the DetailedDayView. This view wraps the WeekView and adds several other controls.

Detailed Week View

Shows up to 31 days for the current month plus some days of the previous and the next month.

Month View

Shows several months in a column layout. Weekdays can be aligned so that the same weekdays are always next to each other. A customizable cell factory is used to create the date cells. Several default implementations are included in CalendarFX: simple date cell, usage date cell, badge date cell, detail date cell.

Month Sheet View

Month Sheet View Aligned

Shows twelve YearMonthView instances.

Year View

Sort of a date picker control. 12 instances of this control are used to build up the YearPage control. This control provides many properties for easy customization. The month label, the year label, and the arrow buttons can be hidden. A cell factory can be set to customize the appearance of each day, and so on.

Year Month View

Just like the WeekView this control can also span multiple days. It is being used as a header for the DayView inside the DayPage and also for the WeekView inside the WeekPage. The control displays calendar entries that have their «full day» property set to true.

All Day View

Displays the names of all currently visible calendars, but only when the DateControl has its layout set to SWIMLANE and not to STANDARD.

Calendar Header View

Calendar Pages

Calendar pages are complex controls that are composed of several controls, many of them DateControl instances. All pages provide controls to navigate to different dates or to quickly jump to «Today». Each page also shows a title with the current date shown. The CalendarView class manages one instance of each page type to let the user switch from a day, to a week, to a month, to a year.

Shows an AgendaView, a DetailedDayView, and a YearMonthView. This page is designed to give the user a quick overview of what is going on today and in the near future (agenda).

Day Page

Composed of a DetailedWeekView.

Week Page

Shows a single MonthView control.

Month Page

Shows a YearView with twelve YearMonthView sub-controls. Alternatively can switch to a MonthSheetView.

Year Page using YearView

Year Page using MonthSheetView

Developer Console

CalendarFX supports a special system property called «calendarfx.developer». If this property is set to «true» then a developer console is being added to the skin of CalendarView. The console can be made visible by pressing META-D. The console is a standard CalendarFX control and you can also add it directly to your application for development purposes.

Developer Console

Logging

CalendarFX uses the standard java logging api for its logging. The logging settings and the available loggers can be found inside the distribution (misc/logging.properties). CalendarFX uses domains for logging and not packages or classes. Several domains are available: view, model, editing, recurrence, etc…​

Internationalization (i18n)

The default resource bundle of CalendarFX is English. A German bundle is also included. Both can be found in the distribution (misc/messages.properties, misc/messages_de.properties). To add another language to CalendarFX simply create a package called com.calendarfx.view and place your own bundle inside of it.

Known Issues

There is currently no support for defining exceptions for recurrence rules. In most calendar applications, when the user edits a recurrent entry, the user will be asked whether he wants to change just this one recurrence or the whole series. This feature is currently not supported but will be in one of the next releases.

In SwimLane layout it would be nice if the user could drag an entry horizontally from one column / calendar to another. This is currently not supported. We will investigate if this can be added in one of the next releases.

Da9el00 / Calendar.fxml

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

<? xml version = " 1.0 " encoding = " UTF-8 " ?>
<? import javafx .geometry.Insets?>
<? import javafx .scene.control.Button?>
<? import javafx .scene.layout.AnchorPane?>
<? import javafx .scene.layout.FlowPane?>
<? import javafx .scene.layout.HBox?>
<? import javafx .scene.text.Font?>
<? import javafx .scene.text.Text?>
< AnchorPane prefHeight = " 642.0 " prefWidth = " 744.0 " style = " -fx-background-color: #f2fafc; " xmlns = " http://javafx.com/javafx/15.0.1 " xmlns : fx = " http://javafx.com/fxml/1 " fx : controller = " com.example.calendarview.CalendarController " >
< FlowPane fx : id = " calendar " hgap = " 10.0 " layoutX = " 14.0 " layoutY = " 116.0 " prefHeight = " 498.0 " prefWidth = " 716.0 " vgap = " 5.0 " />
< HBox alignment = " CENTER " layoutX = " 163.0 " layoutY = " 14.0 " prefHeight = " 44.0 " prefWidth = " 419.0 " spacing = " 5.0 " >
< children >
< Button mnemonicParsing = " false " onAction = " #backOneMonth " text = " &lt; " />
< Text fx : id = " year " strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " #### " >
< font >
< Font size = " 22.0 " />
</ font >
</ Text >
< Text fx : id = " month " strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " #### " >
< font >
< Font size = " 22.0 " />
</ font >
</ Text >
< Button mnemonicParsing = " false " onAction = " #forwardOneMonth " text = " &gt; " />
</ children >
</ HBox >
< HBox alignment = " CENTER " layoutX = " 14.0 " layoutY = " 78.0 " prefHeight = " 44.0 " prefWidth = " 716.0 " spacing = " 88.75 " >
< children >
< Text strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " Su " textAlignment = " CENTER " />
< Text layoutX = " 213.0 " layoutY = " 37.0 " strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " Mo " textAlignment = " CENTER " />
< Text layoutX = " 222.0 " layoutY = " 37.0 " strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " Tu " textAlignment = " CENTER " />
< Text layoutX = " 232.0 " layoutY = " 37.0 " strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " We " textAlignment = " CENTER " />
< Text layoutX = " 241.0 " layoutY = " 37.0 " strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " Th " textAlignment = " CENTER " />
< Text layoutX = " 251.0 " layoutY = " 37.0 " strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " Fr " textAlignment = " CENTER " />
< Text layoutX = " 266.0 " layoutY = " 37.0 " strokeType = " OUTSIDE " strokeWidth = " 0.0 " text = " Sa " textAlignment = " CENTER " />
</ children >
< padding >
< Insets right = " 9.0 " />
</ padding >
</ HBox >
</ AnchorPane >

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

import java . time . ZonedDateTime ;
public class CalendarActivity <
private ZonedDateTime date ;
private String clientName ;
private Integer serviceNo ;
public CalendarActivity ( ZonedDateTime date , String clientName , Integer serviceNo ) <
this . date = date ;
this . clientName = clientName ;
this . serviceNo = serviceNo ;
>
public ZonedDateTime getDate () <
return date ;
>
public void setDate ( ZonedDateTime date ) <
this . date = date ;
>
public String getClientName () <
return clientName ;
>
public void setClientName ( String clientName ) <
this . clientName = clientName ;
>
public Integer getServiceNo () <
return serviceNo ;
>
public void setServiceNo ( Integer serviceNo ) <
this . serviceNo = serviceNo ;
>
@ Override
public String toString () <
return "CalenderActivity <" +
"date=" + date +
", clientName='" + clientName + '\'' +
", serviceNo=" + serviceNo +
'>' ;
>
>

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Как сделать календарь в javafx

This is the CalendarFX developer manual. It aims to contain all the information required to quickly get a calendar UI into your application. If you notice any mistakes or if you are missing vital information then please let us know.

Calendar View

Distribution

CalendarFX is distributed as an archive (ZIP file). Once downloaded double click on the file to extract it. When you open the extracted folder you will see the following content.

Distribution

Contains the calendar.css file used for styling all controls in CalendarFX.

Several executable JAR files — double click to start the demo. If the applications do not start or you encounter problems try starting the demos from the command line like this «java -jar calendar-demo.jar».

The generated JavaDocs / API documentation. The docs are covering everything in great detail. Many screenshots can be found inside of them.

A folder with third-party libraries. ControlsFX is used for providing additional controls (e.g. MasterDetailPane, CustomTextField), some of which are the result of our work on CalendarFX and have been handed over as open source to the community (e.g. PopOver). The second JAR file includes the FontAwesome graphics and API. The third JAR file in the «ext» folder «license4j.jar» is used for supporting the licensing concept behind CalendarFX.

Contains the resource bundles (english, german).

A folder containing the licensing agreements (development, runtime, source code, research).

The CalendarFX JAR files.

Contains this document.

Logging and i18N information and resources.

Two JavaFX apps showing you how to get started with CalendarFX.

Installation

To use CalendarFX for your project, simply add the calendarfx JAR files found in the «lib» folder and all JAR files found in the «ext» folder to the classpath of your application. This is all that is needed, no further configuration required, at least not for the trial period of several months. After this period it will be necessary to set a license key as shown below. For buying options please refer to the website at http://www.calendarfx.com.

Quick Start

The following section shows you how to quickly setup a JavaFX application that will show a complete calendar user interface. It includes a day view, a week view, a month view, a year view, an agenda view, a calendar selection view, and a search UI.

Create the calendar view

Create one or more calendars

Set a style on each calendar (entries will use different colors)

Create a calendar source (e.g. «Google») and add calendars to it

Add calendars to the view

Model

The primary model classes in CalendarFX are «CalendarSource», «Calendar» and «Entry». A calendar source often represents a calendar account, for example an account with «Google Calendar» (http://calendar.google.com). A group consists of a list of calendars and each calendar manages any number of entries. An entry represents an event with a start date / time and an end date / time.

Entry

The «Entry» class encapsulates all information that is required to display an event or an appointment in any of the calendar views included in CalendarFX.

Calendar Entry

The properties of an entry are:

a unique identifier

The title / name of the event or appointment (e.g. «Dentist Appointment»)

The calendar to which the entry belongs.

A complex data type grouping together start date / time, end date / time, and a time zone.

A free text description of a location, for example «Manhatten, New York». This information can be used by Geo services to return coordinates so that the UI can display a map if needed.

A flag used to signal that the event is relevant for the entire day and that the start and end times are not relevant, for example a birthday or a holiday. Full day entries are displayed as shown below.

All Day View

Ensures that the user can not create entries with a duration of less than, for example, 15 minutes.

An arbitrary object which might be responsible for the creation of the entry in the first place.

A text representation of a recurrence pattern according to RFC 2445 («RRULE:FREQ=DAILY»)

This last property is very interesting. It allows the entry to express that it defines a recurence. The entry can specify that it will be repeated over and over again following a given pattern. For example: «every Monday, Tuesday and Wednesday of every week until December 31st». If an entry is indeed a recurring entry then it produces one or more «recurrences». These recurrences are created by the framework by invoking the Entry.createRecurrence() method. The result of this method is another Entry that will be configured with the same values as the source entry.

A flag that expresses whether the entry represents a recurrence or not.

A reference to the original source entry.

If an entry represents a recurrence of a source entry then this property will store an additional ID, normally the date where the recurrence occurs.

In addition to these properties several read-only properties are available for convenience.

Needed y to easily determine if an entry spans multiple days. This information is constantly needed in various places of the framework for display / layout purposes.

The date when the event begins (e.g. 5/12/2015).

The time of day when the event begins (e.g. 2:15pm).

The date when the event ends (e.g. 8/12/2015).

The time of day when the event ends (e.g. 6:45pm).

Calendar

The «Calendar» class is used to store entries in a binary interval tree. This data structure is not exposed to the outside. Instead methods exist on Calendar to add, remove, and find entries.

The following is a description of the main properties of the Calendar class:

The display name of the calendar, shown in several places within the UI.

A short version of the calendar name. By default it is set to be equal to the regular name, but if the application is using the swimlane layout then it might make sense to also define a short name due to limited space.

A flag for controlling whether entries can be added interactively in the UI or not. Setting this flag to false does not prevent the application itself to add entries.

Basically a name prefix for looking up different styles from the CSS file (calendar.css): «style1-«, «style2-«. The «Calendar» class defines a «Style» enumerator that can be used to easily set the value of this property with one of the predefined styles.

Look Ahead / Back Duration

Two properties of type «java.time.Duration» that are used in combination with the current system time in order to create a time interval. The calendar class uses this time interval inside of its findEntries(String searchTerm) method.

Adding and Removing Entries

To add an entry simply call the addEntry() method on calendar. Example:

To remove an entry call the removeEntry() method on calendar.

Alternatively you can simply set the calendar directly on the entry.

To remove the entry from its calendar simply set the calendar to null.

Finding Entries for a Time Interval

The calendar class provides a findEntries() method which receives a start date, an end date, and a time zone. The result of invoking this method is a map where the keys are the dates for which entries were found and the values are lists of entries on that day.

The result does not only contain entries that were previously added by calling the addEntry() method but also recurrence entries that were generated on-the-fly for those entries that define a recurrence rule.

Finding Entries for a Search String

The second findEntries() method accepts a search term as a parameter and is used to find entries that were previously added to the calendar and that match the term.

To find actual matches the method invokes the Entry.matches(String) method on all entries that are found within the time interval defined by the current date, the look back duration, and the look ahead duration.

Calendar Source

A calendar source is used for creating a group of calendars. A very typical scenario would be that a calendar source represents an online calendar account (e.g. Google calendar). Calendars can be added to a source by simply calling mySource.getCalendars().add(myCalendar).

Events

CalendarFX utilizes the JavaFX event model to inform the application about changes made in a calendar, about user interaction that might require loading of new data, and about user interaction that might require showing different views.

Calendar Events

An event type that indicates that a change was made to the data is probably the most obvious type that anyone would expect from a UI framework. In CalendarFX this event type is called CalendarEvent.

ANY : the super event type

CALENDAR_CHANGED : «something» inside the calendar changed, usually causing rebuild of views (example: calendar batch updates finished)

ENTRY_CHANGED : the super type for changes made to an entry

ENTRY_CALENDAR_CHANGED : the entry was assigned to a different calendar

ENTRY_FULL_DAY_CHANGED : the full day flag was changed (from true to false or vice versa)

ENTRY_INTERVAL_CHANGED : the time interval of the entry was changed (start date / time, end date / time)

ENTRY_LOCATION_CHANGED : the location of the entry has changed

ENTRY_RECURRENCE_RULE_CHANGED : the recurrence rule was modified

ENTRY_TITLE_CHANGED : the entry title has changed

ENTRY_USER_OBJECT_CHANGED : a new user object was set on the entry

Listeners for this event type can be added to calendars by calling:

Load Events

Load events are used by the framework to signal to the application that the UI requires data for a specific time interval. This can be very useful for implementing a lazy loading strategy. If the user switches from one month to another then an event of this type will be fired and the time bounds on this event will be the first and the last day of that month. The LoadEvent type only supports a single event type called LOAD.

Listeners for this event type can be registerd on any date control:

Request Events

A somewhat unique event class is RequestEvent. It is used by the controls of the framework to signal to other framework controls that the user wants to «jump» to another view. For example: the user clicks on the date shown for a day in the MonthView then the month view will fire a request event that informs the framework that the user wants to switch to the DayView to see more detail for that day.

DateControl

A calendar user interface hardly ever consists of just a single control. They are composed of several views, some showing a single day or a week or a month. In CalendarFX the CalendarView control consists of dedicated «pages» for a day, a week, a month, or a full year. Each one of these pages consists of one or more subtypes of DateControl. The following image shows a simplified view of the scene graph / the containment hierarchy.

Hierarchy View

To make all of these controls work together in harmony it is important that they share many properties. This is accomplished by JavaFX property binding. The class DateControl features a method called «bind» that ensures the dates and times shown by the controls are synchronized. But also that many of the customization featuers (e.g. node factories) are shared.

The following listing shows the implementation of the DateControl.bind() method to give you an idea how much is bound within CalendarFX.

Class Hierarchy

CalendarFX ships with many built-in views for displaying calendar information. All of these views inherit from DateControl. The class hierarchy can be seen in the following image:

Class Hierarchy

Current Date, Time, and Today

Each DateControl keeps track of the «current date» and «today». The current date is the date that the control is supposed to display to the user. «Today» is the date that the control assumes to be the actual date. «Today» defaults to the current system date (provided by the operating system) but it can be any date.

The «today» and «time» properties do not get updated by themselves. See the daemon thread created in the listing shown in the «Quick Start» section.

DateControl defines utility methods that allow for easy modification of the «current» date.

Adding Calendars / Sources

Even though the DateControl class provides a getCalendars() method this is not the place where calendars are being added. Instead always create calendar sources, add calendars to them, and then add the sources to the control. The «calendars» list is a read-only flat list representation of all calendars in all calendar sources. The «calendars» list gets updated by the framework.

Customizing or Replacing the PopOver

The DateControl class has built-in support for displaying a PopOver control when the user double clicks on a calendar entry. The content node of this PopOver can be replaced. It is normally used to show some basic entry details (e.g. start / end date, title, event location) but applications might have defined specialized entries with custom properties that require additional UI elements. This can be accomplished by the help of the PopOver content node factory.

If an application does not want to use the PopOver at all but instead display a standard dialog then there is a way of doing that, too. Simply register an entry details callback.

These two callbacks normally work hand in hand. The default implementation of the entry details callback is producing a PopOver and sets the content node on the PopOver via the help of the content node callback.

Context Menu Support

A common place for customization are context menus. The DateControl class produces a context menu via specialized callbacks. One callback is used to produce a menu for a given calendar entry, the second callback is used when the user triggers the context menu by clicking in the background of a DateControl.

The context menu callbacks are automatically shared among all date controls that are bound to each other. The same context menu code will execute for different views, the DayView, the MonthView, and so on. This means that the code that builds the context menu will need to check the parameter object that was passed to the callback to configure itself appropriately.

The same is true for basically all callbacks used by the DateControl.

Creating Entries

The user can create new entries by double clicking anywhere inside a DateControl. The actual work of creating a new entry instance is then delegated to a specialized entry factory that can be set on DateControl.

Once the entry factory has returned the new entry it will be added to the calendar that is being returned by the «default calendar» provider. This provider is also customizable via a callback.

Besides the double click creation the application can also programmatically request the DateControl to create a new entry at a given point in time. Two methods are available for this: createEntryAt(ZonedDateTime) and createEntryAt(ZonedDateTime, Calendar). The second method will ensure that the entry will be added to the given calendar while the first method will invoke the default calendar provider.

Creating Calendar Sources

The user might also wish to add another calendar source to the application. In this case the DateControl will invoke the calendar source factory. The default implementation of this factory does nothing more than to create a new instance of the standard CalendarSource class. Applications are free to return a specialization of CalendarSource instead (e.g. GoogleCalendarAccount). A custom factory might even prompt the user first with a dialog, e.g. to request user credentials.

The calendar source factory gets invoked when the method DateControl.createCalendarSource() gets invoked. The CalendarView class already provides a button in its toolbar that will call this method.

Entry Views

Entry views are JavaFX nodes that are representing calendar entries. There are several different types, all extending EntryViewBase:

Shown inside a DayView or WeekDayView control. These views can be customized by subclassing DayEntryViewSkin and overriding the createContent() method.

All Day Entry View

Shown inside the AllDayView control.

Month Entry View

Shown inside the MonthView control.

Calendar Views

The most fundamental views inside CalendarFX are of course the views used to display a day (24 hours), an entire week, a month, and a year.

Shows a 24 hour time period vertically. The control has several options that can be used to influence the layout of the hours. E.g.: it is possible to define hour ranges where the time will be compressed in order to save space on the screen (early and late hours are often not relevant). The view can also specify whether it wants to always show a fixed number of hours or a fixed height for each hour.

Day View

wraps the DayView control with several additional controls: an AllDayView, a TimeScaleView, a CalendarHeaderView, a ScrollBar and and (optional) AgendaView.

Detailed Day View

The name of this control is somewhat misleading, because it can show any number of WeekDayView instances, not just 5 or 7 but also 14 (two weeks) or 21 (three weeks). In this view entries can be easily edited to span multiple days.

Week View

same concept as the DetailedDayView. This view wraps the WeekView and adds several other controls.

Detailed Week View

Shows up to 31 days for the current month plus some days of the previous and the next month.

Month View

Shows several months in a column layout. Weekdays can be aligned so that the same weekdays are always next to each other. A customizable cell factory is used to create the date cells. Several default implementations are included in CalendarFX: simple date cell, usage date cell, badge date cell, detail date cell.

Month Sheet View

Month Sheet View Aligned

Shows twelve YearMonthView instances.

Year View

Sort of a date picker control. 12 instances of this control are used to build up the YearPage control. This control provides many properties for easy customization. The month label, the year label, and the arrow buttons can be hidden. A cell factory can be set to customize the appearance of each day, and so on.

Year Month View

Just like the WeekView this control can also span multiple days. It is being used as a header for the DayView inside the DayPage and also for the WeekView inside the WeekPage. The control displays calendar entries that have their «full day» property set to true.

All Day View

Displays the names of all currently visible calendars, but only when the DateControl has its layout set to SWIMLANE and not to STANDARD.

Calendar Header View

Calendar Pages

Calendar pages are complex controls that are composed of several controls, many of them DateControl instances. All pages provide controls to navigate to different dates or to quickly jump to «Today». Each page also shows a title with the current date shown. The CalendarView class manages one instance of each page type to let the user switch from a day, to a week, to a month, to a year.

Shows an AgendaView, a DetailedDayView, and a YearMonthView. This page is designed to give the user a quick overview of what is going on today and in the near future (agenda).

Day Page

Composed of a DetailedWeekView.

Week Page

Shows a single MonthView control.

Month Page

Shows a YearView with twelve YearMonthView sub-controls. Alternatively can switch to a MonthSheetView.

Year Page using YearView

Year Page using MonthSheetView

Developer Console

CalendarFX supports a special system property called «calendarfx.developer». If this property is set to «true» then a developer console is being added to the skin of CalendarView. The console can be made visible by pressing META-D. The console is a standard CalendarFX control and you can also add it directly to your application for development purposes.

Developer Console

Logging

CalendarFX uses the standard java logging api for its logging. The logging settings and the available loggers can be found inside the distribution (misc/logging.properties). CalendarFX uses domains for logging and not packages or classes. Several domains are available: view, model, editing, recurrence, etc…​

Internationalization (i18n)

The default resource bundle of CalendarFX is English. A German bundle is also included. Both can be found in the distribution (misc/messages.properties, misc/messages_de.properties). To add another language to CalendarFX simply create a package called com.calendarfx.view and place your own bundle inside of it.

Known Issues

There is currently no support for defining exceptions for recurrence rules. In most calendar applications, when the user edits a recurrent entry, the user will be asked whether he wants to change just this one recurrence or the whole series. This feature is currently not supported but will be in one of the next releases.

In SwimLane layout it would be nice if the user could drag an entry horizontally from one column / calendar to another. This is currently not supported. We will investigate if this can be added in one of the next releases.

JavaFX: use a TableView as a calendar and fill it with events

I’m trying to make a calendar like application with fills a week schedule with lectures.

This is the code for the Lecture class:

Depending on the day and firstblock values the lecture gets placed in my TableView. Right now I made a custom row class which handles all this and fills the rows in my TableView. The result looks like this:

enter image description here

Is it possible to use a CellFactory to place the lectures on the right place? (maybe create labels with the name of the lecture, and empty labels if there isn’t a lecture).

I also want to add a contextmenu that pops up when you right click a course or an empty cell to have to possibility to add or remove a course, which I need the cellfactory for I think. Note that it has to be possible to have more than one lecture in a cell.

Edit: Would it be possible to use different lists to fill different columns? for example a list that has all lectures for a monday?

26 Date Picker

This chapter provides an overview of the date data supported in JavaFX and describes the basic features of the DatePicker control.

JavaFX DatePicker is a control that enables selection of a day from the given calendar. It is used mainly on web sites or in applications that require users to enter a date. The DatePicker control consists of a combo box with a date field and a date chooser.

Working with Time Data and Date Formats

The new Date-Time API introduced in JDK 8 enables you to perform various operations with Date and Time data, including setting the calendar and local time across different time zones.

The basic package of the Date-Time API is java.time . It provides the following classes that define time in the calendar system based on the International Organization for Standardization (ISO) calendar.

Clock – a clock providing access to the current instant, date, and time using a time-zone

Duration – a time-based amount of time

Instant – an instantaneous point on the timeline

LocalDate – a date without a time-zone in the ISO-8601 calendar system

LocalDateTime – a date-time without a time zone in the ISO-8601 calendar system

LocalTime – a time without time zone in the ISO-8601 calendar system

MonthDay – a month day in the ISO-8601 calendar system

OffsetDateTime – a date-time with an offset from Greenwich/UTC time in the ISO-8601 calendar system

OffsetTime – a time with an offset from Greenwich/UTC time in the ISO-8601 calendar system

Period – a date-based amount of time

Year – a year in the ISO-8601 calendar system

YearMonth – a year-month in the ISO-8601 calendar system

ZonedDateTime – a date time with a time zone in the ISO-8601 calendar system

ZoneId – a time zone ID

ZoneOffset – a time zone offset from Greenwich/UTC time

See the Date-Time API trail of the Java Tutorials for more information about the available functionality and code samples.

Date Picker Design Overview

To enhance the user interfaces of JavaFX applications with the new capabilities of the JDK 8 Date-Time API, JavaFX SDK introduced the DatePicker control. The DatePicker control consists of an editable combo box (date field) and a calendar (date chooser) shown in Figure 26-1.

Figure 26-1 Example of a Date Picker Control

Description of Figure 26-1 follows

Description of «Figure 26-1 Example of a Date Picker Control»

Adding a Date Picker to an Application UI

Use the DatePicker class available in the javafx.scene.control package to add a date picker component to the user interface (UI) of your JavaFX application as shown in Example 26-1.

Example 26-1 Adding a Date Picker Component

Example 26-1 implements a typical UI for selecting a check-in date for hotel booking. When you compile and run the application, the component shown in Figure 26-2 appears.

Figure 26-2 Initial View of a Date Picker Component

Description of Figure 26-2 follows
Description of «Figure 26-2 Initial View of a Date Picker Component»

Note that in the initial state the date field is empty. However, you can change this behavior and specify the date value to be shown before any date is selected. Set the value property in the DatePicker constructor or call the setValue method inherited from the ComboBox class. Example 26-2 shows several options for setting the LocalDate values.

Example 26-2 Setting Date Values

Once the initial value is set, it appears in the date field after you compile and run the application. Figure 26-3 shows a specified initial date in a date field.

Figure 26-3 Date Field with the Specified Initial Date

Description of Figure 26-3 follows
Description of «Figure 26-3 Date Field with the Specified Initial Date»

The DatePicker API provides several properties and methods to alter the default appearance and behavior of a date picker. In particular, you can toggle showing of the week numbers, customize date formats, and define and apply date cell factories.

Customizing the Date Picker

You can enable and disable showing the ISO week numbers in the calendar by using the setShowWeekNumbers method of the DatePicker class. Example 26-3 is a code line that implements this task for the checkInDatePicker.

Example 26-3 Enabling Week Numbers in the Date Picker

This modification produces the date picker component with the week numbers added to the calendar element as shown in Figure 26-4.

Figure 26-4 Showing Week Numbers in the Calendar

Description of Figure 26-4 follows
Description of «Figure 26-4 Showing Week Numbers in the Calendar»

By default, the dates in the date field are shown in the format defined by the system locale and the ISO calendar system. Thus, the selected dates in Example 26-1 are shown in the following format: mm/dd/yyyy. Normally, you do not need to modify that default format. Still, the converter property and the setConverter method of the DatePicker class enable you to set an alternative date format when required. Setting the converter value to null restores the default date format.

In Example 26-4, you create a converter to alter the format of the date according to the following pattern: yyyy-MM-dd. It converts the input text to an object of the LocalDate type when users enter a date in the date field. It also converts the LocalDate object that corresponds to the date selected in the calendar to the text shown in the date field.

Example 26-4 Converting a Date Format

In addition to converting the date format, Example 26-4 sets the prompt text for the date field to inform users about the required date format. Figure 26-5 shows two states of the date picker with the date format converter applied. Both the prompt text and the selected date are shown in the new format.

Figure 26-5 Date Picker with the Format Converter and Prompt Text

Description of Figure 26-5 follows

Description of «Figure 26-5 Date Picker with the Format Converter and Prompt Text»

You can also modify the default appearance and set a specific behavior for any cell or several cells of a calendar element. To implement this task, consider a real-life use case: selecting check-in and check-out dates during hotel booking. Example 26-5 creates a typical user interface with two date pickers.

Example 26-5 Adding Two Date Picker Components

The predefined value of the checkInDatePicker in Example 26-5 is LocalDate.now() , which corresponds to the current date from the system clock. The predefined date of the checkOutDatePicker is the next date after the current date.

When you compile and run this example on September 19, 2013, it produces the output shown in Figure 26-6.

Figure 26-6 Two Date Picker Components

Description of Figure 26-6 follows
Description of «Figure 26-6 Two Date Picker Components»

By default, all the cells in the calendar elements are available for selection. This could lead to a situation in which the check-out date precedes the check-in date, which is incorrect.

Example 26-6 creates a day cell factory for the checkOutDatePicker to disable the cell that corresponds to the date selected in the checkInDatePicker and all the cells corresponding to the preceding dates.

Example 26-6 Implementing a Day Cell Factory to Disable Some Days

The dayCellFactory applied to the checkOutDatePicker calls the setDisable and setStyle methods on a DateCell item to protect the cells from selection and paint them with the pink color.

When you compile and run the code in Example 26-6, the DatePickerSample produces a UI with the expected behavior shown in Figure 26-7.

Figure 26-7 Disabling Cells in the Calendar Element

Description of Figure 26-7 follows
Description of «Figure 26-7 Disabling Cells in the Calendar Element»

Now that you have learned how to create day cell factories, you can extend the default behavior of the checkOutDatePicker and provide additional functionality for the date cells that are enabled for selection.

Example 26-7 calculates the day interval between the date selected in the checkInDatePicker and the current date cell. The result is rendered in the cell tooltip.

Example 26-7 Calculating a Time Interval

When you compile and run the modified DatePickerSample application, you can see the tooltip if you hover the mouse cursor over a date cell. Figure 26-8 captures the moment when you put a mouse cursor over the cell for September 30. The tooltip states that the time interval between September 19 and September 30 is 11 days.

Figure 26-8 Setting a Tooltip for a Date Cell

Description of Figure 26-8 follows
Description of «Figure 26-8 Setting a Tooltip for a Date Cell»

Altering the Calendar System

The Date-Time Java API introduced in JDK 8 enables developers to operate not only with ISO-based calendar systems but also with alternative chronologies, such as Japanese, Hijrah, Minguo, and Thai Buddhist.

The DatePicker control also supports non-ISO calendar systems by rendering the appropriate year. For the Hijrah chronology, in which month dates do not coincide with the ISO dates, it provides an additional visual theme to distinguish between ISO and Hijrah days of the month.

Example 26-8 applies the Thai Buddhist chronology to the checkInDatePicker and the Hijrah chronology to the checkOutDatePicker.

Example 26-8 Applying Thai Buddhist and Hijrah Chronologies

When these lines are added to the DatePickerSample application, the date picker controls change their appearance as shown in Figure 26-9.

Figure 26-9 Using Alternative Chronology

Description of Figure 26-9 follows

Description of «Figure 26-9 Using Alternative Chronology»

You can find out more details about Non-ISO Date support in the corresponding lesson of the Java Tutorials.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *