1

たぶん、JavaFXバインディングを誤解したか、SimpleStringPropertyにバグがあります。

このテストコードを実行すると、変更したモデル値が新しい値を取得しませんでした。テストtestBindingToModelは失敗します。次に、モデルをTextFieldtfの値で更新する必要があると思いました。ただし、prop1Bindingのバインディング値のみが値「test」を取得します。

public class BindingTest {  
    private TextField tf;
    private Model model;
    private ModelBinding mb;

    @Before
    public void prepare() {
        tf = new TextField();
        model = new Model();
        mb = new ModelBinding(model);
        Bindings.bindBidirectional(tf.textProperty(), mb.prop1Binding);
    }

    @Test
    public void testBindingToMB() {
        tf.setText("test");

        assertEquals(tf.getText(), mb.prop1Binding.get());
    }

    @Test
    public void testBindingToModel() {
        tf.setText("test");

        assertEquals(tf.getText(), mb.prop1Binding.get());
        assertEquals(tf.getText(), model.getProp1());
    }

    private static class ModelBinding {
        private final StringProperty prop1Binding;

        public ModelBinding(Model model) {
            prop1Binding = new SimpleStringProperty(model, "prop1");
        }

    }

    private static class Model {
        private String prop1;

        public String getProp1() {
            return prop1;
        }

        public void setProp1(String prop1) {
            this.prop1 = prop1;
        }       
    }
    }

ご協力いただきありがとうございます。

よろしくセバスチャン

編集:このクラスを使用すると、モデルの値を直接設定できます。数日中にこのクラスをテストし、この投稿に私の結果をコメントします。

public class MySimpleStringProperty extends SimpleStringProperty {
    public MySimpleStringProperty(Object obj, String name) {
        super(obj, name);
    }

    public MySimpleStringProperty(Object obj, String name, String initVal) {
        super(obj, name, initVal);
    }

    @Override
    public void set(String arg0) {
        super.set(arg0);
        if (this.getBean() != null) {
            try {
                Field f = this.getBean().getClass().getDeclaredField(this.getName());
                f.setAccessible(true);
                f.set(this.getBean(), arg0);
            } catch (NoSuchFieldException e) {
                // logging here
            } catch (SecurityException e) {
                // logging here
            } catch (IllegalArgumentException e) {
                // logging here
            } catch (IllegalAccessException e) {
                // logging here
            }
        }
    }
}
4

2 に答える 2

2

私の要求を満たすだけのJavaBeanStringPropertyクラスが提供されていることがわかりました。

このコードを使用して、Bean の値を StringProperty に直接バインドできます (Bean への/からの値の設定と取得が含まれます)。

binding = JavaBeanStringPropertyBuilder.create().beanClass(Model.class).bean(model).name("prop1").build();

私が見つけた唯一の問題は、バインディングを設定した後にモデルの値を変更すると、TextField などで更新がないことです。

于 2012-10-07T11:50:59.057 に答える
2

SimpleStringProperty残念ながら、このコンストラクターは Bean オブジェクトにアタッチしません。SimpleStringPropertyどの Bean プロパティに属しているかを示しているだけです。

たとえば、クラスにプロパティが必要な場合は、次の方法で行う必要があります。

public static class Model {

    private StringProperty prop1 = 
          new SimpleStringProperty(this, "prop1", "default_value");

    public String getProp1() {
        return prop1.get();
    }

    public void setProp1(String value) {
        prop1.set(value);
    }

    public StringProperty prop1Property() {
        return prop1;
    }
}

新しい値Modelの設定に関するイベントを提供しないため、元のクラスにバインドする方法がないことに注意してください。prop1観測可能なモデルが必要な場合は、最初から fx プロパティを使用する必要があります。

于 2012-10-04T15:24:32.373 に答える