0

I have this problem with the scrollPane where content is blurry I managed to fix it like this:

        Node scrollPaneSkin = menuScroll.getChildrenUnmodifiable().get(0);
        scrollPaneSkin.setCache(false);

I am taking the first child of the scrollPane which is a scrollPaneSkin and setting it's cache to false, but when I do It in initialize() the node is still not rendered or something, because I am getting NullPointerException. So I am doing it with a timeline:

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

And it is working, but I feel that there is a better way to do it. Same is happening if I try to get the scene of a node from the fxml in the initialize(). How can I get the children right away in the initialize() method?

  • 1
    The `Skin` is not part of a `Control`'s children list; you're getting some `Node` that's probably added by the `Skin`, but not the `Skin` itself. Have you tried setting the `cache` property on the `ScrollPane` itself? – Slaw Feb 26 '19 at 15:49
  • @Slaw I tried many things the the only thing that fixed it was an answer that extends the all ScrollPane and creates a new one with a new extended ScrollPaneSkin that the cache is set to false https://stackoverflow.com/a/26213480/10696487. But then I managed to do it like this. I am getting a Skin because when I try to take the children and cast it to let's say VBox I am getting "ClassCastException: class javafx.scene.control.skin.ScrollPaneSkin$5 cannot be cast to class javafx.scene.layout.VBox" so I just take it as Node and it is working. –  Feb 26 '19 at 15:54
  • @Slaw or maybe ScrollPaneSkin$5 is not a skin maybe it's the viewRect of the scrollPaneSkin? –  Feb 26 '19 at 16:00

1 Answers1

0

You should do this through listeners, rather than trying to wait a certain amount of time. What you listen to is up to you. One option is to listen to the skin property of the ScrollPane.

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

}

Another option is to listen to the children of the ScrollPane and react when the appropriate node is added. Looking at the source code the node is an anonymous subclass of StackPane whose style class is "viewport".

Note that this code is dependent on both ScrollPane using ScrollPaneSkin as it's skin and the internal implementation of ScrollPaneSkin. Be careful if you change the skin, which can be done via code, FXML, or CSS. And be careful when changing JavaFX versions; I tried the above example using Java 8u202 though it doesn't look like anything relevant changed by JavaFX 11.0.2.

Slaw
  • 37,820
  • 8
  • 53
  • 80