我想在用户拖动主窗口时自动调整图像大小。这可能吗?
我有以下代码设置一定大小的窗口。它还会从外部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();
}
答案 0 :(得分:8)
将解决方案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);
}
}
基于评论的替代方法和额外信息
如果你必须做所有这些,那么它就是JavaFX平台的一个弱点。理想情况下,我希望在图像上有一个可以设置的缩放属性,以便它使用SceneGraph来确定它的大小。
上面提出的解决方案只是一个答案,还有其他可能。可以通过将各种属性绑定到父节点的宽度和高度,或者通过覆盖父节点中的layoutChildren来使用场景图。
相关属性:
我更喜欢区域子类方法来进行缩放属性或基于变换的方法,因为然后根据布局管理器自动调整图像大小。上面定义的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());
}
答案 1 :(得分:1)
只需使用带有背景图片的普通窗格,这里需要css。
#titleImage{
-fx-background-image: url("../img/logo.png");
-fx-background-repeat: stretch;
-fx-background-position: center center;
}
答案 2 :(得分:0)
您是期待resize an actual image,还是只是为了居中?
您可以尝试:VBox.setVgrow(root, Priority.ALWAYS);
并查看这是否是您想要的。
另外,请注意图像,因为它是png
图像。我对那里的重新调整大小(实际图像或透明背景)有点怀疑。
答案 3 :(得分:0)
我知道这已经过时了,但像我这样的人可能偶然发现这一点,所以这是我的解决方案。我假设 root 是场景的根节点。但是,如果 ImageView 的父节点是 Pane 的任何子节点,这应该有用。
imv = new ImageView();
root.getChildren().add(imv);
Image image = new Image(Main.class.getResourceAsStream("image.png"))
imv.setImage(image);
imv.fitWidthProperty().bind(center.widthProperty());
imv.fitHeightProperty().bind(center.heightProperty());