在scrollPane JavaFX中仅绘制Canvas的可见部分

时间:2016-02-10 23:29:05

标签: user-interface canvas javafx scrollpane

如果重要的话,我正在使用SceneBuilder。

老实说,似乎无法弄明白。我不明白如何访问scrollPane的可见部分,或者其他一些确定我需要的界限的方法。 scrollPane是300x300,画布更大。我只想在画布上画一个300x300像素的部分。

1 个答案:

答案 0 :(得分:1)

ScrollPane有一个ViewPort。使用ViewPort的边界。

代码

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.ScrollPane;
import javafx.stage.Stage;

public class Main extends Application {

    Canvas canvas = new Canvas( 2000, 2000);

    @Override
    public void start(Stage primaryStage) {

        ScrollPane scrollPane = new ScrollPane( canvas);

        scrollPane.viewportBoundsProperty().addListener((ChangeListener<Bounds>) (observable, oldValue, newValue) -> showBounds( scrollPane));
        scrollPane.hvalueProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> showBounds( scrollPane));
        scrollPane.vvalueProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> showBounds( scrollPane));

        Scene scene = new Scene( scrollPane, 400, 400);

        primaryStage.setScene( scene);
        primaryStage.show();

    }

    private void showBounds( ScrollPane scrollPane) {

        double hValue = scrollPane.getHvalue();
        double vValue = scrollPane.getVvalue();
        double width = scrollPane.viewportBoundsProperty().get().getWidth();
        double height = scrollPane.viewportBoundsProperty().get().getHeight();

        double x = (scrollPane.getContent().getBoundsInParent().getWidth() - width) * hValue;
        double y = (scrollPane.getContent().getBoundsInParent().getHeight() - height) * vValue;

        System.out.println( "x=" + x + ", y=" + y + ", width=" + width + ", height=" + height);

        // demo: draw a line of the canvas size and a rectangle of the viewport size => the rectangle must always be in the center
        double size = 80;
        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.clearRect(x, y, width, height);

        gc.beginPath();
        gc.moveTo(0, 0);
        gc.lineTo(canvas.getWidth(), canvas.getHeight());
        gc.closePath();
        gc.stroke();

        gc.fillRect(x + (width-size) / 2, y + (height-size) / 2, size, size);

    }

    public static void main(String[] args) {
        launch(args);
    }

}