如何翻译 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 作为参数(不是移动的像素)。
您好,我目前正在根据特定的用户交互来移动滚动窗格内容的视图。在应用程序中,我有一个 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 作为参数(不是移动的像素)。