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

标签 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();

}

最佳答案

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

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);
    }
}

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

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/

相关文章:

java - Java 中使用泛型进行继承

java - rJava 未在 R 中加载

java - 如何在 Eclipse 中的类型上启用 JSR308 空注释?

java - 如果从 Eclipse 运行 ant build,有没有办法将 ant 版本输出到控制台

iphone - (自动调整大小蒙版)具有固定高度的图像的灵活宽度

java - XPath NodeList 命令 (Java)

java - 从基于配置的服务 bean 切换到基于注释的服务 bean 时的 TransactionProxyFactoryBean

ruby - Eclipse(在 OS X 10.9 上)默认内置 Ruby 2.0 但需要 1.8.7

ios - 完整图像未加载到 UICollectionView Cell Swift 4 内的 ImageView 上

ios - 自动布局或自动调整大小