Java 在fxml加载后获取节点的子节点

Java 在fxml加载后获取节点的子节点,java,javafx,Java,Javafx,我有一个滚动窗格的问题,其中的内容模糊,我设法解决它,如下所示: Node scrollPaneSkin = menuScroll.getChildrenUnmodifiable().get(0); scrollPaneSkin.setCache(false); 我正在获取scrollPane的第一个子元素,它是一个scrollPaneSkin,并将其缓存设置为false,但是当我在初始化中这样做时,节点仍然没有被渲染或其他什么,因为我得到的是NullPoint

我有一个滚动窗格的问题,其中的内容模糊,我设法解决它,如下所示:

        Node scrollPaneSkin = menuScroll.getChildrenUnmodifiable().get(0);
        scrollPaneSkin.setCache(false);
我正在获取scrollPane的第一个子元素,它是一个scrollPaneSkin,并将其缓存设置为false,但是当我在初始化中这样做时,节点仍然没有被渲染或其他什么,因为我得到的是NullPointerException。所以我用一个时间表来做:

    Timeline timeline = new Timeline(new KeyFrame(Duration.millis(15),event -> {
        Node scrollPaneSkin = menuScroll.getChildrenUnmodifiable().get(0);
        scrollPaneSkin.setCache(false);
    }));
    timeline.play();

这是可行的,但我觉得有更好的方法。如果我尝试从初始化中的fxml获取节点的场景,也会发生同样的情况。如何在initialize方法中立即获取子项?

您应该通过侦听器执行此操作,而不是尝试等待一定的时间。你听什么取决于你自己。一个选项是侦听ScrollPane的skin属性

另一个选项是监听ScrollPane的子节点,并在添加适当的节点时做出反应。查看源代码,该节点是StackPane的一个匿名子类,其样式类为viewport


请注意,此代码既依赖于使用ScrollPaneSkin作为皮肤的ScrollPane,也依赖于ScrollPaneSkin的内部实现。如果更改皮肤,请小心,这可以通过代码、FXML或CSS来完成。更改JavaFX版本时要小心;我使用Java 8u202尝试了上面的示例,尽管它看起来与JavaFX 11.0.2所做的任何更改都不相关。

外观不是控件子列表的一部分;您得到的节点可能是由蒙皮添加的,但不是蒙皮本身。你试过在ScrollPane本身上设置cache属性吗?@Slaw我试过很多方法,唯一能修复的方法是一个扩展all ScrollPane并创建一个新的扩展ScrollPane的答案缓存设置为false。但后来我就这样做了。我得到了一个皮肤,因为当我试图将孩子们的皮肤投射到VBox时,我得到了ClassCastException:class javafx.scene.control.Skin.ScrollPaneSkin$5不能投射到class javafx.scene.layout.VBox,所以我只把它当作节点,它正在工作。@Slaw或者ScrollPaneSkin$5不是皮肤,可能它是羊皮?
public class Controller {

    @FXML private ScrollPane sp;

    @FXML
    private void initialize() {
        // may want to remove the listener once it does its job
        sp.skinProperty().addListener((obs, ov, nv) -> {
            if (nv != null) {
                sp.getChildrenUnmodifiable().get(0).setCache(false);
            }
        });
    }

}