我的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切换按钮时,我要保持hSelectorwSelector值的比率。所以我尝试跟随

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后如何消除维持比率的行为。

最佳答案

每次切换按钮时都不要添加新的侦听器。 “添加侦听器”是指该方法从字面上将侦听器添加到现有侦听器集,因此,在编写代码时,如果用户十次选择切换按钮,则每个微调器上将有十个侦听器。

正确的方法是为每个微调器添加一个侦听器。如果未选择切换按钮,则每个侦听器都不应执行任何操作。您需要将微调框值的比率保留在私有字段中,以供听众使用。

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));
    }
});

07-25 20:41