我希望在用户拖动主窗口时自动调整图像大小。这可能吗?
我有以下设置特定大小窗口的代码。它还从外部 URL 加载图像。
@Override
public void start(Stage primaryStage) {
MenuBar menuBar=new MenuBar();
Menu menuGame = new Menu("Game");
MenuItem newGame = new MenuItem("New Game F1");
MenuItem exit = new MenuItem("Exit F2");
exit.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
primaryStage.close();
}
});
menuGame.getItems().addAll(newGame,new SeparatorMenuItem(),exit);
menuBar.getMenus().addAll(menuGame);
Image image = new Image("http://docs.oracle.com/javafx/"
+ "javafx/images/javafx-documentation.png");
ImageView imageView = new ImageView();
imageView.setImage(image);
VBox vbox=new VBox();
StackPane root=new StackPane();
root.getChildren().addAll(imageView);
vbox.getChildren().addAll(menuBar,root);
Scene scene= new Scene(vbox,400,400);
primaryStage.setScene(scene);
primaryStage.setMaxHeight(800);
primaryStage.setMinHeight(400);
primaryStage.setMaxWidth(1000);
primaryStage.setMinWidth(800);
primaryStage.setTitle("Minesweeper");
primaryStage.show();
}
最佳答案
将解决方案应用于 JavaFx image resizing到您的示例代码并调整窗口大小会为我生成不同的图像大小。
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.event.*;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ImageResizer extends Application {
@Override
public void start(Stage primaryStage) {
MenuBar menuBar=new MenuBar();
Menu menuGame = new Menu("Game");
MenuItem newGame = new MenuItem("New Game F1");
MenuItem exit = new MenuItem("Exit F2");
exit.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
primaryStage.close();
}
});
menuGame.getItems().addAll(newGame,new SeparatorMenuItem(),exit);
menuBar.getMenus().addAll(menuGame);
Image image = new Image("http://docs.oracle.com/javafx/"
+ "javafx/images/javafx-documentation.png");
ImageView imageView = new ImageView();
imageView.setImage(image);
ImageViewPane viewPane = new ImageViewPane(imageView);
VBox vbox=new VBox();
StackPane root=new StackPane();
root.getChildren().addAll(viewPane);
vbox.getChildren().addAll(menuBar,root);
VBox.setVgrow(root, Priority.ALWAYS);
Scene scene= new Scene(vbox,200,200);
primaryStage.setScene(scene);
primaryStage.setMaxHeight(400);
primaryStage.setMinHeight(200);
primaryStage.setMaxWidth(500);
primaryStage.setMinWidth(400);
primaryStage.setTitle("Minesweeper");
primaryStage.show();
}
public static void main(String[] args) { launch(); }
}
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*/
/**
*
* @author akouznet
*/
class ImageViewPane extends Region {
private ObjectProperty<ImageView> imageViewProperty = new SimpleObjectProperty<ImageView>();
public ObjectProperty<ImageView> imageViewProperty() {
return imageViewProperty;
}
public ImageView getImageView() {
return imageViewProperty.get();
}
public void setImageView(ImageView imageView) {
this.imageViewProperty.set(imageView);
}
public ImageViewPane() {
this(new ImageView());
}
@Override
protected void layoutChildren() {
ImageView imageView = imageViewProperty.get();
if (imageView != null) {
imageView.setFitWidth(getWidth());
imageView.setFitHeight(getHeight());
layoutInArea(imageView, 0, 0, getWidth(), getHeight(), 0, HPos.CENTER, VPos.CENTER);
}
super.layoutChildren();
}
public ImageViewPane(ImageView imageView) {
imageViewProperty.addListener(new ChangeListener<ImageView>() {
@Override
public void changed(ObservableValue<? extends ImageView> arg0, ImageView oldIV, ImageView newIV) {
if (oldIV != null) {
getChildren().remove(oldIV);
}
if (newIV != null) {
getChildren().add(newIV);
}
}
});
this.imageViewProperty.set(imageView);
}
}
基于评论的替代方法和额外信息
If you have to do all that, then it's a weakness in he JavaFX platform. Ideally I would expect there to have been a scale property on the image that one could set so that it uses the SceneGraph to determine it's size.
上面给出的解决方案只是一个答案,还有其他可能的。可以通过将各种属性绑定(bind)到父节点的宽度和高度或通过覆盖 layoutChildren 来使用场景图。在父节点中。
相关属性:
- 有一个scale property可以应用于任何节点。
- 一个节点也有一个transform list Scale可以应用。
- ImageView 有一个 fitWidth和 fitHeight 属性(在其他答案中演示了此属性的使用)。
我更喜欢区域子类方法而不是基于缩放属性或变换的方法,因为这样图像会根据布局管理器自动调整大小。上面定义的 ImageViewPane 只是一个一次性的定义类,可以根据需要重复使用,实际的应用程序代码使用 ImageView 或 ImageViewPane 几乎是等价的。
另一种可能的方法是使用 Region 子类(例如 Pane),它具有已定义的 CSS 样式类或 id,然后定义 image in CSS as a background . CSS 定义图像的好处在于,您可以使用额外的基于 CSS 的属性来定义图像的大小、缩放、定位和重复等内容。这background也可以是set programmatically如果需要而不是通过 CSS。
相关问题:
保持图像的高度和宽度比例
下面的代码可以用在上面提供的ImageViewPane类中:
if (imageView.isPreserveRatio()) {
if (getHeight() > getWidth()) {
imageView.setFitWidth(getWidth());
imageView.setFitHeight(0);
} else {
imageView.setFitWidth(0);
imageView.setFitHeight(getHeight());
}
} else {
imageView.setFitWidth(getWidth());
imageView.setFitHeight(getHeight());
}
关于java - 在 JavaFX 中调整窗口大小时如何调整图像大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22993550/