Property sheet example with use of a PropertyEditor (ControlsFX)


I have been searching a lot for any good examples of the use of a ControlsFX PropertySheet but couldn’t find anything but this.

In this example, the ObservableList items which includes NameItem objects, is added to the PropertySheet object in its constructor just like the documentation tells.

However, as this documentation says, a column of a PropertySheet “provides a PropertyEditor that allows the end user the means to manipulate the property”. It even says that there is a “CheckEditor, ChoiceEditor, TextEditor and FontEditor, among the many editors that are available in the Editors package.”.

I don’t want to be limited to my NameItem example. I also want to add check boxes, choice boxes and other dynamic editor elements. Can anyone please give an example on how to use one or more of the editors to build a simple PropertySheet?

6/16/2014 7:49:14 AM

PropertySheet does support few property editors out of the box, depending on a property type.

Following example is an extension from ControlsFX sample application. It shows how String, LocalDate, Enum, Boolean and Integer types are mapped to the TextField, DatePicker, ChoiceBox, CheckBox and NumericField respectively.

public class PropertySheetExample extends VBox {
    private static Map<String, Object> customDataMap = new LinkedHashMap<>();
    static {
        customDataMap.put("Group 1#My Text", "Same text"); // Creates a TextField in property sheet
        customDataMap.put("Group 1#My Date", LocalDate.of(2000, Month.JANUARY, 1)); // Creates a DatePicker
        customDataMap.put("Group 2#My Enum Choice", SomeEnumType.EnumValue); // Creates a ChoiceBox
        customDataMap.put("Group 2#My Boolean", false); // Creates a CheckBox
        customDataMap.put("Group 2#My Number", 500); // Creates a NumericField

    class CustomPropertyItem implements PropertySheet.Item {
        private String key;
        private String category, name;

        public CustomPropertyItem(String key) {
            this.key = key;
            String[] skey = key.split("#");
            category = skey[0];
            name = skey[1];

        public Class<?> getType() {
            return customDataMap.get(key).getClass();

        public String getCategory() {
            return category;

        public String getName() {
            return name;

        public String getDescription() {
            return null;

        public Object getValue() {
            return customDataMap.get(key);

        public void setValue(Object value) {
            customDataMap.put(key, value);

    public PropertySheetExample {
        ObservableList<PropertySheet.Item> list = FXCollections.observableArrayList();
        for (String key : customDataMap.keySet())
            list.add(new CustomPropertyItem(key));

        PropertySheet propertySheet = new PropertySheet(list);
        VBox.setVgrow(propertySheet, Priority.ALWAYS);

This behavior can be further extended in two ways. First, an existing editor can be used for types which are not supported by default property editor factory. Following example sets new property editor factory which will create ChoiceBox for List<String> type. For other types it delegates editor creation to the default factory.

SimpleObjectProperty<Callback<PropertySheet.Item, PropertyEditor<?>>> propertyEditorFactory = new SimpleObjectProperty<>(this, "propertyEditor", new DefaultPropertyEditorFactory());

propertySheet.setPropertyEditorFactory(new Callback<PropertySheet.Item, PropertyEditor<?>>() {
    public PropertyEditor<?> call(PropertySheet.Item param) {
        if(param.getValue() instanceof List) {
            return Editors.createChoiceEditor(param, (List) param.getValue());

        return propertyEditorFactory.get().call(param);

And finally, we can create custom editor and override getPropertyEditorClass() method from the PropertySheet.Item to return the custom editor type. In that case, default property editor factory will create the editor, and there is no need to override the factory method.

5/28/2019 3:18:32 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow