我找不到任何关于 PropertySheet 的自定义 Editor 的示例,但我想我现在想通了。就我而言,我只是想使用Slider 作为Number 的编辑器。这可能不切实际,因为您无法查看 Slider 的值,但我想 Slider 可以简单地替换为带有滑块和标签的窗格。
首先,我们需要实现Item,这里是controlsfx-samples 的略微修改版本。 Map 已移至此类,但可以在任何地方。不过,您可能根本不想使用地图,因为将类别和名称结合起来已经有些不切实际了;此外,没有空间为项目创建描述。
public class CustomPropertyItem implements PropertySheet.Item {
public static Map<String, Object> customDataMap = new LinkedHashMap<>();
static {
customDataMap.put("basic.My Text", "Same text"); // Creates a TextField in property sheet
customDataMap.put("basic.My Date", LocalDate.of(2016, Month.JANUARY, 1)); // Creates a DatePicker
customDataMap.put("misc.My Enum", SomeEnum.ALPHA); // Creates a ChoiceBox
customDataMap.put("misc.My Boolean", false); // Creates a CheckBox
customDataMap.put("misc.My Number", 500); // Creates a NumericField
customDataMap.put("misc.My Color", Color.ALICEBLUE); // Creates a ColorPicker
}
private String key;
private String category, name;
public CustomPropertyItem(String key)
{
this.key = key;
String[] skey = key.split("\\.", 2);
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() {
// doesn't really fit into the map
return null;
}
@Override
public Object getValue() {
return customDataMap.get(key);
}
@Override
public void setValue(Object value) {
customDataMap.put(key, value);
}
@Override
public Optional<ObservableValue<? extends Object>> getObservableValue() {
return Optional.empty();
}
@Override
public Optional<Class<? extends PropertyEditor<?>>> getPropertyEditorClass() {
// for an item of type number, specify the type of editor to use
if (Number.class.isAssignableFrom(getType())) return Optional.of(NumberSliderEditor.class);
// ... return other editors for other types
return Optional.empty();
}
}
接下来是PropertyEditor 实现,它是Node 和一组将属性项值与控件连接起来的方法。第一个构造函数对于实现和是必需的,因为方法Editors.createCustomEditor(Item) 使用反射来查找这个构造函数。您不必使用此方法,但默认的 PropertyEditorFactory 很可能依赖于此。
如果您出于某种原因想避免反射,则不需要在 your Item 中覆盖 getPropertyEditorClass() 并且可以使用 setPropertyEditorFactory(Callback) 并在其中创建 PropertyEditor 的新实例那里。
请注意,您根本不需要使用 setPropertyEditorFactory(Callback)(在此示例中)。
public class NumberSliderEditor extends AbstractPropertyEditor<Number, Slider> {
public NumberSliderEditor(Item property, Slider control)
{
super(property, control);
}
public NumberSliderEditor(Item item)
{
this(item, new Slider());
}
@Override
public void setValue(Number n) {
this.getEditor().setValue(n.doubleValue());
}
@Override
protected ObservableValue<Number> getObservableValue() {
return this.getEditor().valueProperty();
}
}
从这里开始,您只需创建您的 PropertySheet 并添加所有地图条目。
PropertySheet propertySheet = new PropertySheet();
for (String key : CustomPropertyItem.customDataMap.keySet()) propertySheet.getItems().add(new CustomPropertyItem(key));
我希望这对任何人都有帮助,因为似乎没有任何示例显示自定义 Editor 的使用。唯一的提示是Item.getPropertyEditorClass() 的javadoc,它有一个默认的接口实现,所以你通常不会看它。这里有一个答案说不要看这种方法的事实也没有帮助:/