我试图在JavaFX中显示一个非常大的图像。为此,我将图像分成几个较小的图像,只加载/显示我的ScrollPane
中可见的部分。JavaFX ScrollPane更新视窗滚动上的边框
要检测ScrollPane
中可见的区域,我要添加侦听器到。但是,viewportBounds
只在我调整窗口大小时更新,但在滚动滚动条时不会更新。
如果我要滚动我的大图像,我还需要滚动滚动条以更新viewportBounds
。我该怎么做呢?
我有一些测试代码如下。点击Button
的作品,但不通过ChangeListener
- left
和right
仍然保持不变,使用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);
}
}
编辑更新测试代码。
我可以响应滚动条的变化是这样的,但它并不完全符合我要找的。我需要能够在'ChangeListener'(和'top'和'botttom')中计算'left'和'right'。当我滚动滚动条时,“hval”打印正确,但“left”和“right”保持其初始值。 – sorbet 2014-10-07 21:48:15
当然,你只是从视口范围计算它们,这是视口在其父代中的范围。当你滚动时,这些不会改变。我更新了答案以显示如何计算内容的可见部分。 – 2014-10-07 23:27:35
但是为什么'viewportBounds'只有在调整大小时才会改变?在我的[测试代码](http://pastie.org/private/zsjaojwtytphephoxp3rg)中,我的'viewport'的'getMinX()'和'getMinY()'会返回更新后的坐标,但只能在调整大小之后。 – sorbet 2014-10-08 21:43:40