JavaFX:绑定无意外工作

时间:2018-01-03 10:20:48

标签: java javafx data-binding

我有一个不起作用的绑定,但我根本无法复制它。

在我解释究竟什么没有正常工作之前,这是我能提出的最接近的示例代码,实际产生问题:

public class Foo extends Application {

    private final Bar bar = new Bar();

    private final BooleanProperty test = new SimpleBooleanProperty();

    @Override
    public void start(Stage primaryStage) throws Exception {
        Pane root = new Pane();
        Scene sc = new Scene(root);
        primaryStage.setScene(sc);

        root.setPrefSize(800, 800);

        Pane hoverPane = new Pane();
        root.getChildren().add(hoverPane);
        hoverPane.setPrefSize(200, 200);
        hoverPane.setLayoutX(300);
        hoverPane.setLayoutY(300);

        bar.hoveredProperty().bind(hoverPane.hoveredProperty());
        bar.hoveredProperty().addListener((a,b,c) -> {
            // This one doesn't work correctly
            System.out.println("Bar received change");
        });

        // If this commented block is used instead of the normal binding, 
        // then "Bar received change" would be printed correctly.
        /*
         * hoverPane.addListener((a, b, c) -> {
         *     bar.hoveredProperty().set(c);
         * });
         */

        hoverPane.hoveredProperty().addListener((a,b,c) -> {
            // This line appears appear whenever I shift my mouse in and out
            System.out.println("HoverPane's hover property has changed");
        });

        test.bind(hoverPane.hoveredProperty());

        test.addListener((a,b,c) -> {
            // I get one line of this every time I hover in and out too
            System.out.println("Test property received change");
        });

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

public class Bar {

    private final BooleanProperty hovered = new SimpleBooleanProperty();

    public final BooleanProperty hoveredProperty() { return hovered; }
    public final boolean getHovered() { return this.hovered.get(); }
    public final void setHovered(boolean h) { this.hovered.set(h); }
}

实际代码比这复杂得多(几千行)。 Pane上放置了很多容器(Scene个对象),因此它不仅仅是hoverPane个。

问题是,其中一些Pane个对象执行会收到悬停值更改,而某些不会。我会说所有Pane对象都是相同的,因为它们是我写的同一个自定义Pane类的实例。

就像我的示例代码所说的那样,我非常确定这些窗格'每当我进出鼠标时,hoveredProperty()肯定会发生变化,这意味着那里没有任何东西搞砸了我的鼠标事件。

当我使用绑定时,一些窗格会在相应的Bar对象中收到更改,而有些窗格则不会。无论我重新运行应用程序多少次,那些确实收到的人都会收到更改。另一方面,那些没有收到的人永远不会收到改变。

当我从绑定切换到ChangeListener时,所有窗格都会收到更改。这是让我困惑的第一件事。

此外,我添加了一个额外的测试布尔属性,它也与Bar.hoveredProperty()类似地绑定,结果是所有这些测试绑定都能正常工作。这个让我很困惑的那个。

我理解这对任何人来说并不容易,因为我没有一个可以证明问题的工作MCV样本。我只是希望有人遇到这样奇怪的问题。

0 个答案:

没有答案