用于scrollPane中使用的图像的JavaFX setFitHeight()/ setFitWidth()禁用平移 [英] JavaFX setFitHeight()/setFitWidth() for an image used within a scrollPane disables panning

查看:840
本文介绍了用于scrollPane中使用的图像的JavaFX setFitHeight()/ setFitWidth()禁用平移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在JavaFX中创建一个地图,我希望有时可以看到整个地图。但问题是,在我将imageView设置为适合屏幕大小然后将其添加到scrollPane后,我的缩放功能正常工作,但是一旦我放大,我就不能在图像周围平移。下面是我写的代码。

So I am creating a map in JavaFX and I would like to have the whole map visible at times. However, the issue is that after I set the imageView to fit the screen size then adding it to the scrollPane my zoom function works fine, but once I zoom in I am not allowed to pan around the image. Below is the code that I have written.

package gameaspects;

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class SourceCodeVersion8 extends Application{

final double SCALE_DELTA = 1.1;
public double SCALE_TOTAL = 1;

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

@Override
public void start(Stage primaryStage) throws Exception {
    AnchorPane mapAnchorO = addMapAnchor();
    Scene mapScene = new Scene(mapAnchorO);
    primaryStage.setScene(mapScene);
    primaryStage.setFullScreen(true);
    primaryStage.setResizable(false);
    primaryStage.show();
}

//Creates an AnchorPane for the map
private AnchorPane addMapAnchor()
{
    AnchorPane mapAnchor = new AnchorPane();
    ScrollPane mapScrollO = addMapScroll();
    mapAnchor.getChildren().add(mapScrollO);
    AnchorPane.setLeftAnchor(mapScrollO, 0.0);
    AnchorPane.setTopAnchor(mapScrollO, 0.0);
    AnchorPane.setBottomAnchor(mapScrollO, 0.0);
    AnchorPane.setRightAnchor(mapScrollO, 0.0);
    return mapAnchor;
}

//Creates an ImageView for the map
private ImageView addMapView()
{
    Image mapImage = new Image("WorldProvincialMap-v1.01.png");
    ImageView mapView = new ImageView(mapImage);
    GraphicsDevice gd =               GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    int width = gd.getDisplayMode().getWidth();
    int height = gd.getDisplayMode().getHeight();
    mapView.setFitHeight(height);
    mapView.setFitWidth(width);
    return mapView;
}

//Creates a scrollPane for the map
private ScrollPane addMapScroll()
{
    ScrollPane mapScroll = new ScrollPane();
    ImageView mapViewO = addMapView();
    mapScroll.setContent(mapViewO);
    mapScroll.setPannable(true);
    mapScroll.setVbarPolicy(ScrollBarPolicy.NEVER);
    mapScroll.setHbarPolicy(ScrollBarPolicy.NEVER);
    mapScroll.addEventFilter(ScrollEvent.ANY, e ->{
        e.consume();
        if(e.getDeltaY() == 0)
        {
            return;
        }
        double scaleFactor =
                  (e.getDeltaY() > 0)
                    ? SCALE_DELTA
                    : 1/SCALE_DELTA;

        if(scaleFactor * SCALE_TOTAL >= 1)
        {
            mapScroll.setScaleX(mapScroll.getScaleX() * scaleFactor);
            mapScroll.setScaleY(mapScroll.getScaleY() * scaleFactor);
            SCALE_TOTAL *= scaleFactor;
        }
    });
    return mapScroll;
    }
}


推荐答案

你'缩放 ScrollPane 而不是内容。此外,即使您缩放 ImageView scaleX scaleY 在计算内容的大小时不考虑。因此 ImageView 也应包含在中:

You're scaling the ScrollPane instead of the content. Furthermore even if you scale the ImageView, scaleX and scaleY are not taken into account when it comes to calculating the content's size. Therefore the ImageView should also be wrapped in a Group:

private ScrollPane addMapScroll() {
    ScrollPane mapScroll = new ScrollPane();
    ImageView mapViewO = addMapView();
    mapScroll.setContent(new Group(mapViewO));
    mapScroll.setPannable(true);
    mapScroll.setVbarPolicy(ScrollBarPolicy.NEVER);
    mapScroll.setHbarPolicy(ScrollBarPolicy.NEVER);
    mapScroll.addEventFilter(ScrollEvent.ANY, e -> {
        e.consume();
        if (e.getDeltaY() == 0) {
            return;
        }
        double scaleFactor
                = (e.getDeltaY() > 0)
                        ? SCALE_DELTA
                        : 1 / SCALE_DELTA;

        if (scaleFactor * SCALE_TOTAL >= 1) {
            mapViewO.setScaleX(mapViewO.getScaleX() * scaleFactor);
            mapViewO.setScaleY(mapViewO.getScaleY() * scaleFactor);
            SCALE_TOTAL *= scaleFactor;
        }
    });
    return mapScroll;
}

要保持中心居中,您需要相应地调整滚动位置:

To "keep the center centered" you need to adjust he scroll positions accordingly:

if (scaleFactor * SCALE_TOTAL >= 1) {
    Bounds viewPort = mapScroll.getViewportBounds();
    Bounds contentSize = mapViewO.getBoundsInParent();

    double centerPosX = (contentSize.getWidth() - viewPort.getWidth()) * mapScroll.getHvalue() + viewPort.getWidth() / 2;
    double centerPosY = (contentSize.getHeight() - viewPort.getHeight()) * mapScroll.getVvalue() + viewPort.getHeight() / 2;

    mapViewO.setScaleX(mapViewO.getScaleX() * scaleFactor);
    mapViewO.setScaleY(mapViewO.getScaleY() * scaleFactor);
    SCALE_TOTAL *= scaleFactor;

    double newCenterX = centerPosX * scaleFactor;
    double newCenterY = centerPosY * scaleFactor;

    mapScroll.setHvalue((newCenterX - viewPort.getWidth()/2) / (contentSize.getWidth() * scaleFactor - viewPort.getWidth()));
    mapScroll.setVvalue((newCenterY - viewPort.getHeight()/2) / (contentSize.getHeight() * scaleFactor  -viewPort.getHeight()));
}

这篇关于用于scrollPane中使用的图像的JavaFX setFitHeight()/ setFitWidth()禁用平移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆