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

Ton*_*ony 4 java eclipse autoresize

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

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

}
Run Code Online (Sandbox Code Playgroud)

jew*_*sea 8

将解决方案应用于JavaFx图像调整大小到您的示例代码并调整窗口大小会为我产生不同的图像大小.

sizedefault sizeresize

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

基于评论的替代方法和额外信息

如果你必须做所有这些,那么它是JavaFX平台的一个弱点.理想情况下,我希望在图像上有一个可以设置的缩放属性,以便它使用SceneGraph来确定它的大小.

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

相关属性:

  • 有一个scale属性可以应用于任何节点.
  • 节点也有一个变换表,其一个尺度可以被应用.
  • ImageView具有fitWidth和fitHeight属性(在其他答案中演示了这一点).

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

另一种可能的方法是使用Region子类(例如Pane),它具有已定义的CSS样式类或id,然后将CSS中图像定义为背景.CSS定义图像的好处在于,您可以使用其他基于CSS的属性来定义图像的大小,缩放,定位和重复等内容.如果需要,也可以通过编程方式设置背景,而不是通过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());
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你必须做所有这些,那么它是JavaFX平台的一个弱点.理想情况下,我希望在图像上有一个可以设置的缩放属性,以便它使用SceneGraph来确定它的大小. (2认同)

And*_*w S 7

我知道这已经过时了,但像我这样的人可能会偶然发现这一点,所以这是我的解决方案。我假设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());
Run Code Online (Sandbox Code Playgroud)

  • 两条底线的“中心”到底是什么? (7认同)
  • 中心是图像或正在改变大小的容器的父级。这非常有效。 (2认同)