在屏幕上显示图像 "wrap around"。 JavaFX
Having an image "wrap around" the screen. JavaFX
许多在线地图都具有此功能,当用户到达图像的 left/right 端时,他们会发现自己在看另一端。这在 JavaFX 中如何实现,它是否与 scrollPane 兼容?另外,当环绕时,我会查看原始图像还是图像的副本(最好是前者)?如果对我具体要完成的工作有任何疑问,请在下方提问。
您可以在多个 ImageView
中显示相同的 Image
。这样图像在内存中只存储一次。
ScrollPane
在这里不是一个好的选择,因为您正在尝试创建 ScrollPane
不支持的 "infinite" 窗格。
以下示例允许用户移动蒙娜丽莎的 2 x 2 网格并调整 window 的整个内容区域被图像覆盖。根据图像大小和可见区域,您可能需要更大的网格。 (检查从左上角开始在 x/y 方向上有多少图像适合可见区域,然后将这些数字加一以确定所需的网格大小。)
@Override
public void start(Stage primaryStage) {
Image image = new Image("https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/687px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg");
GridPane images = new GridPane();
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 2; y++) {
images.add(new ImageView(image), x, y);
}
}
Pane root = new Pane(images);
images.setManaged(false);
class DragHandler implements EventHandler<MouseEvent> {
double startX;
double startY;
boolean dragging = false;
@Override
public void handle(MouseEvent event) {
if (dragging) {
double newX = (event.getX() + startX) % image.getWidth();
double newY = (event.getY() + startY) % image.getHeight();
if (newX > 0) {
newX -= image.getWidth();
}
if (newY > 0) {
newY -= image.getHeight();
}
images.setLayoutX(newX);
images.setLayoutY(newY);
}
}
}
DragHandler handler = new DragHandler();
root.setOnMouseDragged(handler);
root.setOnDragDetected(evt -> {
images.setCursor(Cursor.MOVE);
handler.startX = images.getLayoutX() - evt.getX();
handler.startY = images.getLayoutY() - evt.getY();
handler.dragging = true;
});
root.setOnMouseReleased(evt -> {
handler.dragging = false;
images.setCursor(Cursor.DEFAULT);
});
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}
许多在线地图都具有此功能,当用户到达图像的 left/right 端时,他们会发现自己在看另一端。这在 JavaFX 中如何实现,它是否与 scrollPane 兼容?另外,当环绕时,我会查看原始图像还是图像的副本(最好是前者)?如果对我具体要完成的工作有任何疑问,请在下方提问。
您可以在多个 ImageView
中显示相同的 Image
。这样图像在内存中只存储一次。
ScrollPane
在这里不是一个好的选择,因为您正在尝试创建 ScrollPane
不支持的 "infinite" 窗格。
以下示例允许用户移动蒙娜丽莎的 2 x 2 网格并调整 window 的整个内容区域被图像覆盖。根据图像大小和可见区域,您可能需要更大的网格。 (检查从左上角开始在 x/y 方向上有多少图像适合可见区域,然后将这些数字加一以确定所需的网格大小。)
@Override
public void start(Stage primaryStage) {
Image image = new Image("https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/687px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg");
GridPane images = new GridPane();
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 2; y++) {
images.add(new ImageView(image), x, y);
}
}
Pane root = new Pane(images);
images.setManaged(false);
class DragHandler implements EventHandler<MouseEvent> {
double startX;
double startY;
boolean dragging = false;
@Override
public void handle(MouseEvent event) {
if (dragging) {
double newX = (event.getX() + startX) % image.getWidth();
double newY = (event.getY() + startY) % image.getHeight();
if (newX > 0) {
newX -= image.getWidth();
}
if (newY > 0) {
newY -= image.getHeight();
}
images.setLayoutX(newX);
images.setLayoutY(newY);
}
}
}
DragHandler handler = new DragHandler();
root.setOnMouseDragged(handler);
root.setOnDragDetected(evt -> {
images.setCursor(Cursor.MOVE);
handler.startX = images.getLayoutX() - evt.getX();
handler.startY = images.getLayoutY() - evt.getY();
handler.dragging = true;
});
root.setOnMouseReleased(evt -> {
handler.dragging = false;
images.setCursor(Cursor.DEFAULT);
});
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}