【问题标题】:Add CheckComboBox to PropertySheet JavaFX将 CheckComboBox 添加到 PropertySheet JavaFX
【发布时间】:2016-07-14 14:55:09
【问题描述】:

我想将 CheckComboBox 添加到 controlsfx 库中的 PropertySheet。默认编辑器仅包含 ComboBox 实现。是否可以添加 CheckComboBox?我尝试使用 AbstractPropertyEditor 实现 PropertyEditor 但出现异常。

    public static final <T> PropertyEditor<?> createCheckComboBoxEditor(PropertySheet.Item property,
        final Collection<T> choices) {
    final ObservableList<T> result = FXCollections.observableArrayList();
    result.addAll(choices);
    CheckComboBox<T> comboBox = new CheckComboBox<T>(result);
    return new AbstractPropertyEditor<ObservableList<T>, CheckComboBox<T>>(property, comboBox) {

        {
            getEditor().getCheckModel().getCheckedItems().setAll(FXCollections.observableArrayList(choices));                
        }
        @Override
        public void setValue(ObservableList<T> value) {
            getEditor().getCheckModel().getCheckedItems().setAll(value);
        }

        @Override
        protected ObservableValue<ObservableList<T>> getObservableValue() {
            return (ObservableValue<ObservableList<T>>) getEditor().getItems();
        }
    };
}

例外:

Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: com.sun.javafx.collections.ObservableListWrapper cannot be cast to javafx.beans.value.ObservableValue
at configurator.ComboBoxEditor$3.getObservableValue(ComboBoxEditor.java:109)
at org.controlsfx.property.editor.AbstractPropertyEditor.<init>(AbstractPropertyEditor.java:83)
at org.controlsfx.property.editor.AbstractPropertyEditor.<init>(AbstractPropertyEditor.java:67)
at configurator.ComboBoxEditor$3.<init>(ComboBoxEditor.java:85)
at configurator.ComboBoxEditor.createCheckComboBoxEditor(ComboBoxEditor.java:85)
at configurator.ConfiguratorController.lambda$setPropertySheetEditors$7(ConfiguratorController.java:273)
at impl.org.controlsfx.skin.PropertySheetSkin$PropertyPane.getEditor(PropertySheetSkin.java:321)
at impl.org.controlsfx.skin.PropertySheetSkin$PropertyPane.setItems(PropertySheetSkin.java:301)
at impl.org.controlsfx.skin.PropertySheetSkin$PropertyPane.<init>(PropertySheetSkin.java:269)
at impl.org.controlsfx.skin.PropertySheetSkin$PropertyPane.<init>(PropertySheetSkin.java:261)
at impl.org.controlsfx.skin.PropertySheetSkin.buildPropertySheetContainer(PropertySheetSkin.java:223)
at impl.org.controlsfx.skin.PropertySheetSkin.refreshProperties(PropertySheetSkin.java:188)
at impl.org.controlsfx.skin.PropertySheetSkin.lambda$new$65(PropertySheetSkin.java:140)

【问题讨论】:

    标签: java javafx controlsfx propertysheet


    【解决方案1】:

    这是一种可能的方法,按照您使用CheckComboBox 控件实现AbstractPropertyEditor 的方法。

    基于HelloCheckComboBox,我使用Person 类、Musicians bean 和自定义编辑器创建了这个示例。

    人物

    public static class Person {
    
        private final StringProperty firstname = new SimpleStringProperty();
        private final StringProperty lastname = new SimpleStringProperty();
        private final ReadOnlyStringWrapper fullName = new ReadOnlyStringWrapper();
    
        public Person(String firstname, String lastname) {
            this.firstname.set(firstname);
            this.lastname.set(lastname);
            fullName.bind(Bindings.concat(firstname, " ", lastname));
        }
    
        public static final ObservableList<Person> createDemoList() {
            final ObservableList<Person> result = FXCollections.observableArrayList();
            result.add(new Person("Paul", "McCartney"));
            result.add(new Person("Andrew Lloyd", "Webber"));
            result.add(new Person("Herb", "Alpert"));
            result.add(new Person("Emilio", "Estefan"));
            result.add(new Person("Bernie", "Taupin"));
            result.add(new Person("Elton", "John"));
            result.add(new Person("Mick", "Jagger"));
            result.add(new Person("Keith", "Richerds"));
            return result;
        }
    
        public final StringProperty firstnameProperty() {
            return this.firstname;
        }
    
        public final java.lang.String getFirstname() {
            return this.firstnameProperty().get();
        }
    
        public final void setFirstname(final String firstname) {
            this.firstnameProperty().set(firstname);
        }
    
        public final StringProperty lastnameProperty() {
            return this.lastname;
        }
    
        public final String getLastname() {
            return this.lastnameProperty().get();
        }
    
        public final void setLastname(final String lastname) {
            this.lastnameProperty().set(lastname);
        }
    
        public final ReadOnlyStringProperty fullNameProperty() {
            return this.fullName.getReadOnlyProperty();
        }
    
        public final String getFullName() {
            return this.fullNameProperty().get();
        }
    
        @Override
        public String toString() {
            return getFullName(); 
        }
    
        @Override
        public int hashCode() {
            int hash = 3;
            hash = 79 * hash + Objects.hashCode(this.firstname);
            hash = 79 * hash + Objects.hashCode(this.lastname);
            hash = 79 * hash + Objects.hashCode(this.fullName);
            return hash;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Person other = (Person) obj;
            if (!Objects.equals(getFirstname(), other.getFirstname())) {
                return false;
            }
            if (!Objects.equals(getLastname(), other.getLastname())) {
                return false;
            }
            return Objects.equals(this.getFullName(), other.getFullName());
        }
    
    }
    

    音乐家

    该类包含一个StringProperty 字段,将使用TextField 进行编辑,以及一个ListProperty&lt;Person&gt; 字段,将使用CheckComboBox&lt;Person&gt; 控件进行编辑:

    public static class Musicians {
    
        private final StringProperty category = new SimpleStringProperty();
        private final ListProperty<Person> persons = new SimpleListProperty<>(FXCollections.observableArrayList());
    
        public Musicians() { }
    
        public String getCategory() {
            return category.get();
        }
    
        public void setCategory(String category) {
            this.category.set(category);
        }
    
        public StringProperty categoryProperty() {
            return category;
        }
    
        public void setPersons(ObservableList<Person> value) {
            this.persons.set(value);
        }
    
        public ObservableList<Person> getPersons() {
            return persons.get();
        }
    
        public ListProperty<Person> personsProperty() {
            return persons;
        }
    }
    

    CustomPropertyEditorFactory

    现在我们提供自己的PropertyEditorFactory,使用与DefaultEditorFactory 相同的文本编辑器作为字符串字段,并添加CheckComboBox 实现。

    请注意,我们必须填充 CheckComboBox 的项目列表,在这种情况下,这将使用 Person.createDemoList() 完成。

    public class CustomPropertyEditorFactory implements Callback<Item, PropertyEditor<?>> {
    
        @Override public PropertyEditor<?> call(Item item) {
            Class<?> type = item.getType();
    
            if (type == String.class) {
                return createTextEditor(item);  
            }
    
            if (type != null && type == javafx.collections.ObservableList.class) {
                return createCheckComboBoxEditor(item, Person.createDemoList());
            }
    
            return null; 
        }
    
        public final PropertyEditor<?> createTextEditor(PropertySheet.Item property) {
    
            return new AbstractPropertyEditor<String, TextField>(property, new TextField()) {
    
                @Override protected StringProperty getObservableValue() {
                    return getEditor().textProperty();
                }
    
                @Override public void setValue(String value) {
                    getEditor().setText(value);
                }
            };
        }
    
        public final <T> PropertyEditor<?> createCheckComboBoxEditor(PropertySheet.Item property, final Collection<T> choices) {
    
            return new AbstractPropertyEditor<ObservableList<T>, CheckComboBox<T>>(property, new CheckComboBox<>()) {
    
                private ListProperty<T> list;
    
                { 
                    getEditor().getItems().setAll(choices);
                } 
    
                @Override
                protected ListProperty<T> getObservableValue() {
                    if (list == null) {
                        list = new SimpleListProperty<>(getEditor().getCheckModel().getCheckedItems());
                    }
                    return list;
                }
    
                @Override
                public void setValue(ObservableList<T> checked) {
                    checked.forEach(getEditor().getCheckModel()::check);
                }
            };
        }
    }
    

    最后,我们可以在我们的应用程序中使用这个自定义工厂:

    @Override
    public void start(Stage primaryStage) {
    
        PropertySheet propertySheet = new PropertySheet();
    
        propertySheet.setPropertyEditorFactory(new CustomPropertyEditorFactory());
    
        Musicians address = new Musicians();
    
        // 1: set initial selected values:
        address.getPersons().add(new Person("Paul", "McCartney"));
    
        // 2: listen to changes in selection:
        address.personsProperty().addListener((ors, ov, nv) -> {
            System.out.println("Selected persons:");
            nv.forEach(System.out::println);
        });
    
        propertySheet.getItems().setAll(BeanPropertyUtils.getProperties(address));
    
        Scene scene = new Scene(propertySheet, 500, 500);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-28
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 2014-04-02
      • 2021-02-10
      • 2017-04-07
      相关资源
      最近更新 更多