0

I'm new to JavaFX and am trying to monitor the resize events on a window so that I can trigger a recalculation of the layout.

If I create a stage and set the scene like in the example below I only get each resize event to be fired once. No matter how many times I resize the window.

Stage stage = new Stage();
stage.setScene(someScene);
stage.setTitle("Some Title");
stage.initModality(Modality.APPLICATION_MODAL);
stage.show();
stage.widthProperty().addListener(observable -> {
    System.out.println("Width changed");
});
stage.heightProperty().addListener(observable -> {
    System.out.println("Height changed");
});
James Robinson
  • 1,222
  • 1
  • 15
  • 43
  • Does this answer your question? [JavaFX InvalidationListener or ChangeListener](https://stackoverflow.com/questions/45117076/javafx-invalidationlistener-or-changelistener) – kleopatra Jun 29 '21 at 14:04
  • The answer accepted is helpful since it identifies that there is a difference between an invalidation listener and a change listener. Unless one knows that such a difference exists a detailed explanation is of little help. – James Robinson Jun 29 '21 at 14:32
  • repeating: a thorough look into appropriate tutorials (or at the very least the java doc of the observable/Value) is what would have helped right from the start .. you seem to be experienced enough to start at the .. beginning :) – kleopatra Jun 29 '21 at 14:54

1 Answers1

3

First note:

I'm trying to monitor the resize events on a window so that I can trigger a recalculation of the layout.

This is almost certainly the wrong approach. Layout recalculations will be triggered automatically when the stage and scene change size. If you use standard layout panes, there is no need to register listeners. If you really need a custom layout (which is highly unlikely), you should subclass Pane and override layoutChildren() (and other appropriate methods) to hook into the same layout system.

However, in the interests of explaining what you're observing:

You're registering an InvalidationListener with each property, which gets notified when the property goes from a valid state to an invalid state.

The invalid state only becomes valid again if you actually request the value of the property (e.g. stage.getWidth()). Since you never do that, the property never becomes valid, and hence never goes from valid to invalid again.

Instead, register a ChangeListener with each property:

stage.widthProperty().addListener((observable, oldWidth, newWidth) -> {
    System.out.println("Width changed");
});
stage.heightProperty().addListener((observable, oldHeight, newHeight) -> {
    System.out.println("Height changed");
});

Alternatively, you can force validation by requesting the value (though I think the change listener above actually gets to the point of what you are trying to do):

stage.widthProperty().addListener(observable -> {
    System.out.println("Width changed: "+stage.getWidth());
});

etc.

James_D
  • 201,275
  • 16
  • 291
  • 322
  • Wasn't intending to use this approach to do the resize, was just trying to debug what was going on and became completely flummoxed by the single print line, thank you for the detailed explanation. – James Robinson Jun 29 '21 at 14:02