我只是想在 OpenJFX 11.0.1 中扩展 SimpleStringProperty 以添加一些额外的功能。但是 ist 似乎并不那么容易,我经历了我的扩展属性的奇怪行为,我不知道为什么。我认为它应该工作。
我在此示例代码中简化的 SimpleStringProperty 扩展包含另一个只读字符串属性,每次用户键入绑定的 TextField 时都应更新该属性。在这种情况下,删除所有不允许的字符并转换前缀。(我知道这并不完美,但足够短,可以展示)
启动示例代码后,您将获得一个带有一行控件的窗口。键入“001 (242) 555666”之类的字符串,标签应显示标准化的电话号码,例如“+1242555666”。
- 初始转换工作正常。
- 我从来没有得到任何例外。
- 当我输入新数字时调用转换。
但是,如果您在几秒钟后尝试键入和删除,则我的属性的 set() 方法不再由与 TextField 的双向绑定触发。
为了简化示例,我没有使用 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);
}
}