美文网首页
2021-06-19_PropertySheet

2021-06-19_PropertySheet

作者: 微笑碧落 | 来源:发表于2021-06-18 20:38 被阅读0次

    0.前言

    • PropertySheet 是一个垂直的属性列表,通常用来显示并编辑一个对象的各种属性。
    • 支持字符串、数字、布尔值、枚举、颜色和字体编辑器。除了支持内置编辑器,还可以自定义编辑器。


      [PropertySheet ]
    • PropertySheet 是一个控件,可以放置于各种pane内。

    1.PropertySheet的简单使用

    • 如下代码创建一个PropertySheet,显示一个Mission对象的各种属性,让终端用户修改。
    • 如果没有特殊要求,如下代码可以很简洁的完成对象的属性编辑gui创建。
    • 但是,通常都有特殊要求的。比如属性的显示名称,属性分类的定义。编辑器的自定义等。
    PropertySheet propertySheet = new PropertySheet(BeanPropertyUtils.getProperties(new Mission()));
    rootLayoutBorderPane.setCenter(propertySheet);
    

    2.PropertySheet使用代码的详细解释

    • 这段话,是看了PropertySheet的源代码,自己书写的。网上相关的资料实在太少了。
    • PropertySheet类的构造函数,接收一个PropertySheet.Item对象列表。
    • PropertySheet.Item是一个接口,定义如下:
    • 可以自己实现PropertySheet.Item。每个 Item 代表一个可由最终用户编辑的单个属性。
    • 就是说,不仅仅是一个对象的属性可以由PropertySheet来展示并编辑,任何属性列表都可以。如下展示了一个PropertySheet.Item的范例。用来修改一个map。
    • BeanProperty类。这个类实现PropertySheet.Item接口。接收一个bean对象,以及一个bean对象属性描述对象,通过反射,来实现对象属性的修改。通常使用的是这个对象。
    • BeanPropertyUtils类。这个类主要是一个工具类,对一个bean的各种属性,创建一个BeanProperty类的列表。
    public static interface Item {
    public Class<?> getType();
    public String getCategory();
    public String getName();
    public String getDescription();
    public Object getValue();
    public void setValue(Object value);
    public Optional<ObservableValue<? extends Object>> 
    default public Optional<Class<? extends PropertyEditor<?>>> getPropertyEditorClass() {
                return Optional.empty();
            }
    default public boolean isEditable() {
                return true;
            }
    }
    
     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];
            }
    
            @Override
            public Class<?> getType() {
                return customDataMap.get(key).getClass();
            }
    
            @Override
            public String getCategory() {
                return category;
            }
    
            @Override
            public String getName() {
                return name;
            }
    
            @Override
            public String getDescription() {
                return null;
            }
    
            @Override
            public Object getValue() {
                return customDataMap.get(key);
            }
    
            @Override
            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);
            getChildren().add(propertySheet);
        }
    }
    

    3. PropertySheet自定义编辑器

    3.1 编辑器接口

    public interface PropertyEditor<T> {
        public Node getEditor();
        public T getValue();
        public void setValue(T value);
    }
    

    3.2 AbstractPropertyEditor<T, C extends Node> implements PropertyEditor<T>编辑器

    • 这个主要是利用javafx的各种控件来实现控制器

    3.3 Editors类和DefaultPropertyEditorFactory类

    • 这个是策略模式,Editors类用来返回各种编辑器(都是 AbstractPropertyEditor类)。
    • DefaultPropertyEditorFactory类,通过各种策略(传入的item)来访问Editors类获得各种编辑器。
    • DefaultPropertyEditorFactory类先判断item的getPropertyEditorClass是否为null,如果不为null就通过这个class的构造函数来创建一个编辑器。如果为空,就通过item的属性类型(字符串,数字,或逻辑值)来创建编辑器。

    4. 自定义编辑器

    • 综上,自定义编辑器有2种方法。第一种,自定义 DefaultPropertyEditorFactory类。这个有点麻烦。。。第二种覆盖item的getPropertyEditorClass默认接口方法。如果是用BeanProperty,就需要覆盖BeanProperty的getPropertyEditorClass默认接口方法
    • 通过第二种方法创建的编辑器,必须有一个接收item的构造函数。

    5. 自定义编辑器的例子

    • 第1步,实现一个editor类
    public class NumberSliderEditor extends AbstractPropertyEditor<String, TextArea> {
        public NumberSliderEditor(PropertySheet.Item property, TextArea control) {
            super(property, control);
        }
    
        public NumberSliderEditor(PropertySheet.Item property) {
            super(property, new TextArea());
        }
    
        @Override
        protected ObservableValue<String> getObservableValue() {
            return getEditor().textProperty();
        }
    
        @Override
        public void setValue(String value) {
            getEditor().setText(value);
    
        }
    }
    
    • 第2步,继承BeanProperty并覆盖方法
    public Optional<Class<? extends PropertyEditor<?>>> getPropertyEditorClass() {
          return Optional.of(NumberSliderEditor.class);
    }
    

    参考文章

    1.javafx – 使用PropertyEditor(ControlsFX)的属性表示例
    2.Property sheet example with use of a PropertyEditor (ControlsFX)
    3.

    相关文章

      网友评论

          本文标题:2021-06-19_PropertySheet

          本文链接:https://www.haomeiwen.com/subject/rledyltx.html