扩展SimpleStringProperty的问题

时间:2019-01-04 06:39:34

标签: java properties extend openjfx

我只是想在OpenJFX 11.0.1中扩展SimpleStringProperty以添加一些额外的功能。但是ist似乎并不容易,我在扩展属性中遇到了奇怪的行为,我也不知道为什么。我认为应该可以。

我在此示例代码的简化SimpleStringProperty扩展中包含另一个只读字符串属性,该属性应在用户每次键入绑定的TextField时更新。在这种情况下,请删除所有不允许的字符并转换前缀。 (我知道这并不完美,但足以说明问题)

启动示例代码后,您将获得一个带有一行控件的窗口。在字符串中输入“ 001(242)555666”之类的标签时,应显示标准化的电话号码,例如““ +1242555666””。

  • 初始转换正确无误。
  • 我从不例外。
  • 当我输入新数字时,将调用转换。

但是,如果您在几秒钟后尝试输入和删除,则不会再通过双向绑定到TextField来触发我属性的set()方法了。

为简化示例,我没有使用TextFormatter。如果我使用一个,问题不会改变。

有人可以帮助我解决问题吗?

Windows和OS X在OpenJFX 11和OpenJFX 11.0.1中显示相同的行为

我在JDK 1.8上尝试了相同的代码,在这里工作正常。

package testproperty;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;


public class TestProperty extends Application {

    // attempt to create an own property
    public class myPhoneNumberProperty extends SimpleStringProperty {

        private final ReadOnlyStringWrapper normalizedNumber = new ReadOnlyStringWrapper("");
        public ReadOnlyStringProperty normalizedNumberProperty() { return normalizedNumber.getReadOnlyProperty(); }
        public String getNormalizedNumber() { return normalizedNumber.get(); }

        public myPhoneNumberProperty() {
            super();
        }

        public myPhoneNumberProperty(String s) {
            super(s);
            calculate();
        }

        @Override
        public void set(String s) {
            super.set(s);
            calculate();
        }

        private void calculate() {
            // some calculations (only for test purposes)
            String original = this.get();
            String result = original.replaceAll("[^0123456789]","");
            if (result.startsWith("00")) result = result.replaceFirst("00", "+");
            if (original.startsWith("+")) result = "+".concat(result);
            normalizedNumber.set(result);
        }
    }


    @Override
    public void start(Stage primaryStage) {

        // create my property
        myPhoneNumberProperty phoneNumberA = new myPhoneNumberProperty("+34 952 111 222");

        // set up grid pane
        GridPane grid = new GridPane();
        grid.setPadding(new Insets(5,5,5,5));
        grid.setVgap(20);
        grid.setHgap(20);

        // set up the row
        Label labelA = new Label("Enter phone number");
        TextField textFieldA = new TextField();
        textFieldA.textProperty().bindBidirectional(phoneNumberA);
        Label labelB = new Label("Normalized number");
        Label labelN = new Label();
        labelN.textProperty().bind(phoneNumberA.normalizedNumberProperty());
        grid.addRow(0, labelA, textFieldA, labelB, labelN);

        // complete scene
        Scene scene = new Scene(grid, 1000, 100);
        primaryStage.setTitle("PhoneNumberProperty TestProg");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

1 个答案:

答案 0 :(得分:1)

您的user_** deleteMen(user_** mens,int* numMens, int index) { int f; if (index >=(*numMens)) { printf("Error\n"); return mens; } //free the index string free(mens[index]->userName); free(mens[index]->description); free(mens[index]->password); free(mens[index]->name); free(mens[index]->lastName); free(mens[index]->userId); for (f = index; f < *numMens - 1; f++) { mens[f]->age = mens[f + 1]->age; mens[f]->description = mens[f + 1]->description; mens[f]->gender = mens[f + 1]->gender; mens[f]->hobbies = mens[f+ 1]->hobbies; mens[f]->lastName = mens[f + 1]->lastName; mens[f]->name = mens[f + 1]->name; mens[f]->password = mens[f + 1]->password; mens[f]->userId = mens[f + 1]->userId; mens[f]->userName = mens[f + 1]->userName; } free(mens[*numMens - 1]->description); free(mens[*numMens - 1]->lastName); free(mens[*numMens - 1]->name); free(mens[*numMens - 1]->password); free(mens[*numMens - 1]->userId); free(mens[*numMens - 1]->userName); free(mens[*numMens - 1]); mens= (user_**)realloc(mens, (*numMens-1) * sizeof(user_*)); if (mens == NULL) if (*numMens != 1) exit(1); *numMens-=1; return mens; } 属性对象正在被垃圾回收。要解决此问题,您必须保持对该对象的强烈引用。一种选择是使其成为实例字段。

JavaFX使用弱侦听器/引用实现绑定。双向绑定没有对其他属性的强引用。这与单向绑定不同,在单向绑定中,必须保留对可观察值的引用,以便以后与之解除绑定。