Agenda is an implementation of a calendar component similar to Google Calendar.
Some attention points are:
Appointments can be dragged, resized, created and its properties can be edited via a popup window.
Appointments are part of groups, which dictates the color that is used.
Whole-day appointments, unlike those in Google calendar, have a visual presence on the whole day: a small vertical bar runs from the label at the top along the whole day, indicating that a whole-day appointment is in effect. This is called a 'flag pole'.
A crucial aspect to grasp when using Agenda is that you (the user of the Agenda control) are in charge of populating the appointments list, Agenda just renders and manipulates them. ICalendarAgenda is an extension to Agenda, which picks up where Agenda stops in that it maintains this appointments list, by using the iCalendar standard to generate repeating appointments.
JavaFX now has a default date picker control, but it is only available as a popup to a textfield. JFXtras' CalendarPicker (and related LocalDatePicker and LocalDateTimePicker) are stand alone controls, which can be put into forms directly.
Of course they also are used by the TextField equivalents (like CalendarTextField). Furthermore, the Calendar and LocalDateTime pickers also allow selecting a time up to seconds, by combining the TimePicker control.
Years before JavaFX got a spinner control, JFXtras had ListSpinner which is used to select year and month in the CalendarPicker. It is a simple control that selects the value in a list. Using CSS it is possible to determining where the arrows are placed and pointing, both horizontally and vertically.
The standard layout classes in JavaFX are somewhat strange, they work on the assumption that if a node can be part of multiple layouts, that they have the same constraints in all. The chance of that being the case is very unlikely, but it is still a big influence on how the API of the layout classes is designed. JFXtras offers an alternative API on the more popular layout implementations (drop-in replacements) that take a more conventional approach, and arguably more readable.
Orginally one would add a control to a gridpane with the following code:
Text t = new Text("text"); gridPane.add(t, 1, 2, 2, 2)); GridPane.setHAlignment(t, HPos.CENTER);
The issue is that a separate variable is required for the control, and what exactly is the row, column order again?
Is the control in the code above placed in row and column 1 or 2?
JFXtras' alternative API looks like this:
gridPane.add(new Text("text"), new GridPane.C() .col(1).row(2) .colSpan(2).rowSpan(2) .halignment(HPos.CENTER));
Maybe not much more compact, but certainly more readable. Similar API’s exists for other layouts.
Button b = new Button("text"); b.setMaxHeight(50.0); hbox.getChildren().add(b); HBox.setHgrow(b1, Priority.ALWAYS);
In the code above a static method is used to set values in a node’s layout map, meaning that this will be applied in all layouts.
hbox.add(new Button("text"), new HBox.C() .maxHeight(50.0) .hgrow(Priority.ALWAYS));
Beside new API’s for existing layouts, JFXtras also has a couple of new layouts. The first is the CircularPane, which lays out its children in a circle.
The animation on how the icons flow into place (or back), plus the arc on which they are shown, is configurable. Based on this layout there are a number of animated menu’s available, which demonstrate the placement and animation of CircularPane.
CornerMenu pops out from any of the four corners of a window, animating icons out over a 90 degree arc.
CirclePopupMenu makes the icons of the menu appear where the right mouse button is clicked.
ResponsivePane as created as a result of an experiment to see how much effort it is to support multiple platforms using a single code base. This pane tries to find the best combination of layout and CSS file, given a certain resolution. The application can render itself in a grid form:
Or if the resolution becomes too small, it can switch to a layout based on tabs, increasing the size of the ListSpinner arrows because this probably is a touch environment.
When this switch is made, is configurable. The logic behind it, including DPI scaling, is what ResponsivePane handles.
Some of the standard controls lack a convenient binding feature.
A good example of this is the ToggleGroup, which allows to synchronize multiple toggling controls (like ToggleButton or RadioButton) to be synced, so that only one toggle can be selected at a time. But ToggleGroup lacks a way to associate the selected toggle with an actual value. For this JFXtras offers ToggleGroupValue, a drop-in extension to ToggleGroup.
ToggleGroupValue<String> toggleGroupValue = new ToggleGroupValue<>(); toggleGroupValue.add(new RadioButton("Animal that quacks"), "duck"); toggleGroupValue.add(new RadioButton("Animal that barks"), "dog"); toggleGroupValue.add(new RadioButton("Animal that roars"), "lion"); ... textField.textProperty().bindBidirectional(toggleGroupValue.valueProperty());
The main difference is that when adding a toggle to ToggleGroupValue, the associated value needs to be provided as well, and can be read, written or bound to.
The drop-in replacement for ListView allows easy binding to the selected value.
ListView<String> listView = new ListView<String>(); ... textField.textProperty().bindBidirectional(listView.selectedItemProperty());
Once upon a time Gerrit Grunwald had created a number of great looking gauges, which he used primarily in his presentations. That was the reason the gauges were not deemed production quality, so with his permission we implemented a few in JFXtras.
Shortly thereafter Gerrit found inspiration and decided to publish them in a more stable form himself, resulting in the Medusa library. The API of the gauges between the two libraries are totally different (and it is interesting to see how the same thing can be approached from different angles); JFXtras uses a functional API, with rendering details through CSS, Medusa has the rendering exposed in the API. The JFXtras gauges have some visual differences from their Medusa counterparts, for example in supporting more indicators. Medusa by now features many more gauges.