如何翻译 Javafx 中滚动窗格的内容?

How to translate the contents of a scroll pane in Javafx?

您好,我目前正在根据特定的用户交互来移动滚动窗格内容的视图。在应用程序中,我有一个 gridPane,其中包含同一图像的 3 个图像视图,每个图像的大小都与屏幕相等。与缩放和平移有关的所有功能都可以正常工作,但是如果我尝试通过 setTranslateX() 翻译滚动窗格(或其我尝试过的内容)并将参数设置为屏幕宽度,我在以下情况下都没有变化滚动窗格的内容或空白屏幕。下面是我的代码,如果你用任何图像代替 "WorldProvincialMap-v1.01.png" 它应该仍然有效。该代码不会产生任何错误,它只是没有达到预期的结果。

package gameaspects;

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.io.IOException;

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.concurrent.Task;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
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.KeyCode;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Popup;
import javafx.stage.Stage;

public class SourceCodeVersion8 extends Application{

final double SCALE_DELTA = 1.1;
public double SCALE_TOTAL = 1;
public static int game_speed = 5, day = 1, month = 1, year = -813, pause =               0;
public IntegerProperty dayProperty, monthProperty, yearProperty, pauseProperty, game_speedProperty;
public static double xDragStart;
public static double xDragEnd;
public static double xScaleToScreen, yScaleToScreen;
public static int dragTotal = 0;
public static int timesExpanded = 1;

static GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
static SourceCodeVersion8 sourceObject = new SourceCodeVersion8();

public static void main(String[] args) {
    new Thread(task).start();
    launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
    Popup exitPopupO = addExitPopup();
    AnchorPane mapAnchorO = addMapAnchor();
    Scene mapScene = new Scene(mapAnchorO);
    primaryStage.setScene(mapScene);
    primaryStage.setFullScreen(true);
    primaryStage.setResizable(false);
    primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
    primaryStage.show();

    mapScene.setOnKeyPressed(e -> {
        if(e.getCode()==KeyCode.ESCAPE)
        {
            exitPopupO.show(primaryStage);
        }
    });
}

//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);
    //Sets the map to full screen.
    int width = gd.getDisplayMode().getWidth();
    int height = gd.getDisplayMode().getHeight();
    mapView.setFitHeight(height);
    mapView.setFitWidth(width);
    return mapView;
}

//Creates a gridPane to hold the ImageView
private GridPane addMapGrid()
{
    GridPane mapGrid = new GridPane();
    ImageView mapView1 = addMapView();
    ImageView mapView2 = addMapView();
    ImageView mapView3 = addMapView();
    mapGrid.add(mapView1,0,0);
    mapGrid.add(mapView2, 1, 0);
    mapGrid.add(mapView3, 2, 0);
    mapGrid.setManaged(false);
    return mapGrid;
}

//Creates a scrollPane for the map
private ScrollPane addMapScroll()
{           
    ScrollPane mapScroll = new ScrollPane();
    GridPane mapGridO = addMapGrid();
    mapScroll.setContent(new Group(mapGridO));
    mapScroll.setPannable(true);
    //Removes the ScrollBars
    mapScroll.setVbarPolicy(ScrollBarPolicy.NEVER);
    mapScroll.setHbarPolicy(ScrollBarPolicy.NEVER);
    //TROUBLED CODE HERE TRANSLATION ERRORS AND STUFF
    mapScroll.setTranslateX(gd.getDisplayMode().getWidth());
    //Adds functionality to scrolling
    mapScroll.addEventFilter(ScrollEvent.ANY, e ->{
        //Consumes the event
        e.consume();
        if(e.getDeltaY() == 0)
        {
            return;
        }
        double scaleFactor =
                  (e.getDeltaY() > 0)
                    ? SCALE_DELTA
                    : 1/SCALE_DELTA;
        //Ensures that you do not exceed the limits of the map
        if(scaleFactor * SCALE_TOTAL >= 1)
        {
            Bounds viewPort = mapScroll.getViewportBounds();
            Bounds contentSize = mapGridO.getBoundsInParent();

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

            mapGridO.setScaleX(mapGridO.getScaleX() * scaleFactor);
            mapGridO.setScaleY(mapGridO.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()));
        }
    });
    mapScroll.addEventFilter(MouseEvent.DRAG_DETECTED, e -> {
        xDragStart = e.getX();
    });
    mapScroll.addEventFilter(MouseEvent.MOUSE_RELEASED, e -> {
        xDragEnd = e.getX();
        if(dragTotal + (xDragEnd - xDragStart) >= gd.getDisplayMode().getWidth()/2)
        {

        }
        dragTotal += Math.abs(xDragEnd - xDragStart);
    });
    return mapScroll;
}

private Popup addExitPopup(){
    Popup exitPopup = new Popup();
    //Exit Panel
    VBox exitBox = new VBox();
    exitBox.setPadding(new Insets(10));
    Button exitPaneExit = new Button();
    exitPaneExit.setText("Return");
    exitPaneExit.setMinSize(75.0, 30.0);
    exitPaneExit.setOnAction(e -> {
        exitPopup.hide();
    });
    Button exitButton = new Button();
    exitButton.setText("Exit");
    exitButton.setMinSize(75.0, 30.0);
    exitButton.setOnAction(e -> {
        System.exit(0);
    });
    exitBox.getChildren().addAll(exitPaneExit,exitButton);
    exitBox.setVisible(true);

    exitPopup.setAutoHide(true);
    exitPopup.getContent().add(exitBox);
    return exitPopup;
}

static Task<Void> task = new Task<Void>() {
    @Override public Void call() throws IOException {
    long initialTime = System.currentTimeMillis(); //Finds the current time and links it with a variable
    while(true)
    {
        if(pause==0)//Makes sure the game is not running while paused
        {
            if(System.currentTimeMillis() - initialTime >= 500 &&game_speed == 5)//Lowest game speed 10 seconds per day
            {
                day++;//Hey its tomorrow!
                sourceObject.setDayProperty(day);
                initialTime = System.currentTimeMillis();//Resets time
                if(day == 32)
                {
                    switch(month)
                    {
                        case 1:
                            month++;
                            day = 1;
                            sourceObject.setDayProperty(day);
                            sourceObject.setMonthProperty(month);
                            break;

                        case 3:
                            month++;
                            day = 1;
                            break;

                        case 5:
                            month++;
                            day = 1;
                            break;

                        case 7:
                            month++;
                            day = 1;
                            break;

                        case 8:
                            month++;
                            day = 1;
                            break;

                        case 10:
                            month++;
                            day = 1;
                            break;

                        case 12:
                            month = 1;
                            day = 1;
                            year++;
                            break;

                        default:
                            break;
                    }
                }
                else if(day == 31)
                {
                    switch(month)
                    {
                        case 4:
                            month++;
                            day = 1;
                            break;

                        case 6:
                            month++;
                            day = 1;
                            break;

                        case 9:
                            month++;
                            day = 1;
                            break;

                        case 11:
                            month++;
                            day = 1;
                            break;

                        default:
                            break;
                    }
                }
                else if(day == 29)
                {
                    switch(month)
                    {
                        case 2:
                            month++;
                            day = 1;
                            break;

                        default:
                            break;
                    }
                }
                System.out.println(month + " " + day + " " + year);
            }
        }
    }
        };
};

public final int getDayProperty()
{
    return dayProperty.get();
}

public final void setDayProperty(int day)
{
    this.dayProperty.set(day);
}

public final IntegerProperty dayInitialProperty()
{
    if(dayProperty == null)
    {
        dayProperty = new SimpleIntegerProperty(1);
    }
    return dayProperty;
}

public final int getMonthProperty()
{
    return monthProperty.get();
}

public final void setMonthProperty(int month)
{
    this.monthProperty.set(month);
}

public final IntegerProperty monthInitialProperty()
{
    if(monthProperty == null)
    {
        monthProperty = new SimpleIntegerProperty(1);
    }
    return monthProperty;
}
}

为了翻译我不得不使用的内容 mapScroll.setHvalue();以 double 作为参数(不是移动的像素)。