I have a very large image I'm trying to display in JavaFX. To do this, I've split the image into several smaller ones, and only loading/displaying the parts that are visible in my ScrollPane
.
To detect the area visible in the ScrollPane
, I'm adding listener to ScrollPane.viewportBounds
. However, the viewportBounds
is only updated when I resize the window, but not when I scroll the scroll bars.
If I'm to be scrolling around my large image, I need viewportBounds
to be updated when I scroll the scroll bars as well. How do I do this?
I have some test code below. Clicking the Button
works, but not through the ChangeListener
- left
and right
still remain unchanged using the ChangeListener
.
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class TestClass extends Application {
@Override
public void start(Stage stage) {
VBox vbox = new VBox();
ScrollPane scrollPane = new ScrollPane(new Rectangle(1000, 700, Color.GREEN));
scrollPane.setPrefSize(500, 300);
// Using a ChangeListener on viewportBounds doesn't work.
scrollPane.viewportBoundsProperty().addListener(new ChangeListener<Bounds>() {
@Override
public void changed(ObservableValue<? extends Bounds> observable, Bounds oldBounds, Bounds bounds) {
int left = -1 * (int) bounds.getMinX();
int right = left + (int) bounds.getWidth();
System.out.println("hval:" + scrollPane.getHvalue() + " left:" + left + " right:" + right);
}
});
// Neither does this.
scrollPane.hvalueProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
Bounds bounds = scrollPane.getViewportBounds();
int left = -1 * (int) bounds.getMinX();
int right = left + (int) bounds.getWidth();
System.out.println("hval:" + scrollPane.getHvalue() + " left:" + left + " right:" + right);
}
});
// Clicking the button works.
Button printButton = new Button("Print");
printButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
Bounds bounds = scrollPane.getViewportBounds();
int left = -1 * (int) bounds.getMinX();
int right = left + (int) bounds.getWidth();
System.out.println("hval:" + scrollPane.getHvalue() + " left:" + left + " right:" + right);
event.consume();
}
});
vbox.getChildren().addAll(scrollPane, printButton);
Scene scene = new Scene(vbox, 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
EDIT Updated test code.