Как сохранить соотношение в значениях JavaFX Spinner - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть два счетчика и кнопка переключения в моем приложении JavaFX, и я также установил их редактируемые

Spinner<Integer> hSelector = new Spinner<>(1,15000,1000,1);
Spinner<Integer> wSelector = new Spinner<>(1,15000,1000,1);
hSelector.setEditable(true);
wSelector.setEditable(true);
ToggleButton lock = new ToggleButton("lock");

Когда выбрана эта кнопка переключения lock, я хочу сохранить соотношение в значенияхhSelector и wSelector.Поэтому я попробовал следующее,

lock.selectedProperty().addListener((observable, oldValue, newValue) -> {
    if(newValue){
        hSelector.getValueFactory().valueProperty().addListener((ob, ov, nv) -> {
            wSelector.getEditor().setText(String.valueOf((nv * wSelector.getValue()) / ov));
        });
        wSelector.getValueFactory().valueProperty().addListener((ob, ov, nv) -> {
            hSelector.getEditor().setText(String.valueOf((nv * hSelector.getValue()) / ov));
        });
    }
});

Но это не сработало.Проблема в том, что когда выбран lock и я изменяю значение одного счетчика, а затем просто фокусирую (щелкая в текстовом поле счетчика) их обоих по одному, их значение изменяется автоматически, даже если я не редактируюзначения.

Теперь мои вопросы. Как правильно сохранить соотношение значений этих счетчиков? В чем проблема в моем методе?и как убрать поведение поддержания соотношения после того, как lock не выбран.

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Не добавляйте нового слушателя каждый раз, когда изменяется кнопка переключения.«Добавить слушателя» означает, что метод буквально добавляет слушателя к существующему набору слушателей, поэтому при написании вашего кода, если пользователь выберет кнопку переключения десять раз, у вас будет десять слушателей на каждом счетчике.

Правильный подход - добавить одного слушателя к каждому Spinner.Каждый слушатель не должен делать ничего, если кнопка переключения не выбрана.Вы захотите сохранить соотношение значений счетчика в закрытом поле для использования слушателями.

private double ratio = 1;

// ...

lock.selectedProperty().addListener((observable, oldValue, newValue) -> {
    if (newValue) {
        hSelector.commitValue();
        wSelector.commitValue();
        ratio = (double) hSelector.getValue() / wSelector.getValue();
    }
});

hSelector.getValueFactory().valueProperty().addListener((ob, ov, nv) -> {
    if (lock.isSelected()) {
        wSelector.getValueFactory().setValue((int) (nv / ratio));
    }
});
wSelector.getValueFactory().valueProperty().addListener((ob, ov, nv) -> {
    if (lock.isSelected()) {
        hSelector.getValueFactory().setValue((int) (nv * ratio));
    }
});
0 голосов
/ 28 декабря 2018

Вы не хотите добавлять слушателя в selectedProperty.Вместо этого прислушайтесь к изменениям Spinner значений .Когда значение изменится, проверьте, была ли выбрана кнопка lock, и выполните ваши вычисления:

    hSelector.valueProperty().addListener((observable, oldValue, newValue) -> {
        if (lock.isSelected()) {
            wSelector.getValueFactory().setValue(newValue * wSelector.getValue() / oldValue);
        }
    });
    wSelector.valueProperty().addListener((observable, oldValue, newValue) -> {
        if (lock.isSelected()) {
            hSelector.getValueFactory().setValue(newValue * hSelector.getValue() / oldValue);
        }
    });

Возможно, вам придется проверить формулу, которую вы используете, чтобы определить новое соотношение, однако, какэто, кажется, не работает должным образом;математика не моя сильная сторонаНо это должно заставить ваши счетчики корректно обновляться при изменении значений.

...