Проблема с расширением SimpleStringProperty - PullRequest
0 голосов
/ 04 января 2019

Я просто пытаюсь расширить SimpleStringProperty в OpenJFX 11.0.1, чтобы добавить некоторые дополнительные функции.Но кажется, что это не так просто, я испытал странное поведение моего расширенного объекта недвижимости и не знаю почему.Я думаю, что это должно работать.

В этом примере кода упрощенное расширение 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);
    }

}

1 Ответ

0 голосов
/ 04 января 2019

Ваш объект phoneNumberA находится в процессе сборки мусора.Чтобы это исправить, вы должны держать сильную ссылку на объект.Один из вариантов - сделать его полем экземпляра.

JavaFX реализует привязки с использованием слабых слушателей / ссылок.Двунаправленные привязки не имеют сильных ссылок на другое свойство.Это отличается от однонаправленных привязок, где ссылка на наблюдаемое значение должна быть сохранена, чтобы открепить ее позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...