所以我在JavaFX中创建一个地图,我希望有时可以看到整个地图。但问题是,在我将imageView设置为适合屏幕大小然后将其添加到scrollPane后,我的缩放功能正常,但是一旦我放大,我就不能在图像周围平移。下面是我写的代码。
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;
}
}
答案 0 :(得分:4)
您正在缩放ScrollPane
而不是内容。此外,即使您缩放ImageView
,在计算内容的大小时也不会考虑scaleX
和scaleY
。因此,ImageView
也应包含在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;
}
要“保持居中居中”,您需要相应地调整其滚动位置:
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()));
}
答案 1 :(得分:1)
我使用mouseDragHandler改进了你的版本。
这应该是解决问题的正确方法!
package test;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javafx.application.Application;
import javafx.event.EventHandler;
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.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class test extends Application {
final double SCALE_DELTA = 1.1;
public double SCALE_TOTAL = 1;
public double dragDeltay;
public double dragDeltax;
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);
mapViewO.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
dragDeltax = mapViewO.getX() - mouseEvent.getScreenX();
dragDeltay = mapViewO.getY() - mouseEvent.getScreenY();
}
});
mapViewO.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
mapScroll.setTranslateX(mouseEvent.getScreenX() + dragDeltax);
mapScroll.setTranslateY(mouseEvent.getScreenY() + dragDeltay);
}
});
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;
}
}