如何在JavaFX中调整窗口大小时调整图像大小

我想在用户拖动主窗口时自动调整图像大小.那可能吗?

我有以下代码设置一定大小的窗口.它还从外部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.

上面提出的解决方案只是一个答案,还有其他可能.可以通过将各种属性绑定到父节点的宽度和高度,或者通过覆盖父节点中的layoutChildren来使用场景图.

相关属性:

>有一个scale property可以应用于任何节点.
>节点还具有transform list,可以应用Scale.
> ImageView具有fitWidth和fitHeight属性(在其他答案中使用此功能).

我更喜欢区域子类方法到scale属性或基于变换的方法,因为然后根据布局管理器自动调整图像大小.上面定义的ImageViewPane只是一个一次性定义类,可以根据需要重复使用,使用ImageView或ImageViewPane的实际应用程序代码几乎相同.

另一种可能的方法是使用Region子类(例如Pane),它具有已定义的CSS样式类或id,然后定义image in CSS as a background. CSS定义图像的好处是可以使用其他基于CSS的属性定义事物,如图像的大小,缩放,定位和重复.如果需要,background也可以是set programmatically,而不是通过CSS.

相关问题:

> Resizing images to fit the parent node

保持图像的比例高度和宽度

以下代码可以在上面提供的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());
}

转载注明原文:如何在JavaFX中调整窗口大小时调整图像大小 - 代码日志