在对象数组

时间:2017-03-31 15:53:03

标签: java javafx

我有一个包装javafx控件的包装器对象数组:

  • CheckBox
  • 微调

我希望能够在CheckBox或Spinner上收听更改。我已经尝试提取我需要的信息,但问题是它只有在数组只有Spinner时才有效。

我的一些代码:

ObservableList<WrapperClass>  WrapperObjectList = FXCollections.observableArrayList(
     new Callback<WrapperClass, Observable[]>() {
          @Override
          public Observable[] call(WrapperClass param) {
               return new Observable[] {
                    ((Spinner) param.getControl()).valueProperty()
                };
          }
     }
);

WrapperClass.java

private Item item;
private Control control;

public WrapperClass(Item item, Control control) {
    this.item = item;
    this.control = control;
}

1 个答案:

答案 0 :(得分:2)

一个相当天真但直截了当的解决方案就是测试包装节点的类型:

ObservableList<WrapperClass>  WrapperObjectList = FXCollections.observableArrayList(
     new Callback<WrapperClass, Observable[]>() {
          @Override
          public Observable[] call(WrapperClass param) {
               if (param.getControl() instanceof Spinner) {
                   return new Observable[] {
                       ((Spinner) param.getControl()).valueProperty()
                   };
               } else if (param.getControl() instanceof CheckBox) {
                   return new Observable[] {
                       ((CheckBox) param.getControl()).selectedProperty()
                   };
               } else return new Observable[0] ;
          }
     }
);

更优雅的方法是从WrapperClass公开适当的属性。你可以使WrapperClass抽象:

public abstract class WrapperClass {

    private Item item;
    private Control control;

    public WrapperClass(Item item, Control control) {
        this.item = item;
        this.control = control;
    }

    public abstract Observable observableValue() ;

}

然后创建具体的子类:

public class SpinnerWrapper extends WrapperClass {

    private final Spinner spinner ;

    public SpinnerWrapper(Item item, Spinner spinner) {
        super(item, spinner);
        this.spinner = spinner ;
    }

    @Override
    public Observable observableValue() {
        return spinner.valueProperty();
    }
}

,同样适用于CheckBoxSpinner。那你就需要

ObservableList<WrapperClass>  WrapperObjectList = FXCollections.observableArrayList(
     new Callback<WrapperClass, Observable[]>() {
          @Override
          public Observable[] call(WrapperClass param) {
               return new Observable[] {
                    param.observableValue()
                };
          }
     }
);

或者,您可以使WrapperClass通用,并为其提供一个返回所需属性的函数:

public class WrapperClass<C extends Control> {

    private Item item ;
    private C control ;

    private Function<C, Observable> valueFunction ;

    public WrapperClass(Item item, C control, Function<C, Observable> valueFunction) { 
        this.item = item ;
        this.control = control ;
        this.valueFunction = valueFunction ;
    }

    public Observable observableValue() {
        return valueFunction.apply(control);
    }
}

您将实例化为

WrapperClass<Spinner> spinnerWrapper = new WrapperClass(someItem, someSpinner, 
    Spinner::valueProperty);
WrapperClass<CheckBox> checkBoxWrapper = new WrapperClass(someOtherItem, someCheckBox, 
    CheckBox::selectedProperty);

将使用提取器创建可观察列表,如上所述返回param.observableValue()