-1

i want to scale the ImageView by resizing the scene (window), but i have to keep the aspect ratio. Is it possible to do that directly by resizing the window? Thank you for your help. The pproblem is, that the ImageView isnt scaling by resizing the window. My other question is: How can i bind an Image to the background so its always fitting into the window and resizes, too when i resize the window?

Thank you for your help

Here is my fxml code:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="900.0" style="-fx-background-color: beige; -fx-border-color: black;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.GUI.Controller">
   <children>
      <VBox fx:id="vbRed" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="101.0" style="-fx-border-color: black;" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="110.0">
         <children>
                  <ImageView fx:id="ivRed" disable="true" fitHeight="88.0" pickOnBounds="true" preserveRatio="true" VBox.vgrow="ALWAYS">
               <image>
                  <Image url="@Images/figurrot.png" />
               </image>
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="5.0" />
               </VBox.margin>
            </ImageView>
            <CheckBox fx:id="cbRed" mnemonicParsing="false" onAction="#handleCBRedAction" selected="true" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="40.0" right="10.0" top="10.0" />
               </VBox.margin></CheckBox>
            <TextField fx:id="tfNameRed" prefHeight="25.0" prefWidth="88.0" promptText="Name" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="2.0" right="2.0" top="10.0" />
               </VBox.margin></TextField>
            <ChoiceBox fx:id="dbRed" prefHeight="25.0" prefWidth="88.0" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="10.0" />
               </VBox.margin></ChoiceBox>
         </children>
         <opaqueInsets>
            <Insets />
         </opaqueInsets>
      </VBox>
      <VBox fx:id="vbYellow" layoutX="117.0" layoutY="110.0" prefHeight="200.0" prefWidth="101.0" style="-fx-border-color: lightgrey;" AnchorPane.leftAnchor="115.0">
         <children>
            <ImageView fx:id="ivYellow" disable="true" fitHeight="88.0" opacity="0.5" pickOnBounds="true" preserveRatio="true" VBox.vgrow="ALWAYS">
               <image>
                  <Image url="@Images/figurgelb.png" />
               </image>
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="5.0" />
               </VBox.margin>
            </ImageView>
            <CheckBox fx:id="cbYellow" mnemonicParsing="false" onAction="#handleCBYellowAction" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="40.0" right="10.0" top="10.0" />
               </VBox.margin>
            </CheckBox>
            <TextField fx:id="tfNameYellow" disable="true" prefHeight="25.0" prefWidth="88.0" promptText="Name" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="2.0" right="2.0" top="10.0" />
               </VBox.margin>
            </TextField>
            <ChoiceBox fx:id="dbYellow" disable="true" prefHeight="25.0" prefWidth="88.0" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="10.0" />
               </VBox.margin>
            </ChoiceBox>
         </children>
      </VBox>
      <VBox fx:id="vbGreen" layoutX="227.0" layoutY="110.0" prefHeight="200.0" prefWidth="101.0" style="-fx-border-color: lightgrey;" AnchorPane.leftAnchor="220.0">
         <children>
            <ImageView fx:id="ivGreen" disable="true" fitHeight="88.0" opacity="0.5" pickOnBounds="true" preserveRatio="true" VBox.vgrow="ALWAYS">
               <image>
                  <Image url="@Images/figurgruen.png" />
               </image>
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="5.0" />
               </VBox.margin>
            </ImageView>
            <CheckBox fx:id="cbGreen" mnemonicParsing="false" onAction="#handleCBGreenAction" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="40.0" right="10.0" top="10.0" />
               </VBox.margin>
            </CheckBox>
            <TextField fx:id="tfNameGreen" disable="true" prefHeight="25.0" prefWidth="88.0" promptText="Name" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="2.0" right="2.0" top="10.0" />
               </VBox.margin>
            </TextField>
            <ChoiceBox fx:id="dbGreen" disable="true" prefHeight="25.0" prefWidth="88.0" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="10.0" />
               </VBox.margin>
            </ChoiceBox>
         </children>
      </VBox>
      <VBox fx:id="vbBlue" layoutX="335.0" layoutY="110.0" prefHeight="200.0" prefWidth="101.0" style="-fx-border-color: lightgrey;" AnchorPane.leftAnchor="325.0">
         <children>
            <ImageView fx:id="ivBlue" fitHeight="88.0" opacity="0.5" pickOnBounds="true" preserveRatio="true" VBox.vgrow="ALWAYS">
               <image>
                  <Image url="@Images/figurblau.png" />
               </image>
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="5.0" />
               </VBox.margin>
            </ImageView>
            <CheckBox fx:id="cbBlue" mnemonicParsing="false" onAction="#handleCBBlueAction" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="40.0" right="10.0" top="10.0" />
               </VBox.margin>
            </CheckBox>
            <TextField fx:id="tfNameBlue" disable="true" prefHeight="25.0" prefWidth="88.0" promptText="Name" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="2.0" right="2.0" top="10.0" />
               </VBox.margin>
            </TextField>
            <ChoiceBox fx:id="dbBlue" disable="true" prefHeight="25.0" prefWidth="88.0" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets left="5.0" right="5.0" top="10.0" />
               </VBox.margin>
            </ChoiceBox>
         </children>
      </VBox>
      <VBox layoutX="441.0" layoutY="105.0" prefHeight="200.0" prefWidth="100.0" AnchorPane.topAnchor="115.0">
         <children>
            <ImageView fx:id="ivNoOfTreasureCards" disable="true" fitHeight="38.0" fitWidth="176.0" opacity="0.0" pickOnBounds="true" preserveRatio="true" VBox.vgrow="ALWAYS">
               <image>
                  <Image url="@Images/AnzahlSchatzkarten2.png" />
               </image>
            </ImageView>
            <TextField fx:id="tfNumOfTreasurecards" disable="true" opacity="0.0" text="24" VBox.vgrow="ALWAYS">
               <font>
                  <Font size="22.0" />
               </font>
               <VBox.margin>
                  <Insets left="60.0" right="60.0" top="10.0" />
               </VBox.margin>
            </TextField>
            <Button fx:id="btnMinus" disable="true" mnemonicParsing="false" onAction="#handleBTNMinusAction" opacity="0.0" prefHeight="38.0" prefWidth="38.0" text="-" VBox.vgrow="ALWAYS">
               <font>
                  <Font name="System Bold" size="9.0" />
               </font>
               <VBox.margin>
                  <Insets left="30.0" right="40.0" top="10.0" />
               </VBox.margin>
            </Button>
            <Button fx:id="btnPlus" disable="true" mnemonicParsing="false" onAction="#handleBTNPlusAction" opacity="0.0" prefHeight="38.0" prefWidth="38.0" text="+" VBox.vgrow="ALWAYS">
               <font>
                  <Font name="System Bold" size="9.0" />
               </font>
               <VBox.margin>
                  <Insets left="100.0" />
               </VBox.margin>
            </Button>
         </children>
      </VBox>
      <Button fx:id="btnGo" disable="true" layoutX="519.0" layoutY="313.0" mnemonicParsing="false" onAction="#startGame" opacity="0.0" prefHeight="48.0" prefWidth="88.0" text="Go!">
         <font>
            <Font name="Kristen ITC" size="20.0" />
         </font>
      </Button>
      <ImageView fitHeight="88.0" fitWidth="880.0" layoutX="12.0" layoutY="12.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="11.0" AnchorPane.rightAnchor="11.0" AnchorPane.topAnchor="11.0">
         <image>
            <Image url="@Images/titel3.png" />

         </image>
      </ImageView>
      <ImageView fx:id="ivReadyToPlay" disable="true" fitHeight="57.0" fitWidth="245.0" layoutX="310.0" layoutY="315.0" opacity="0.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@Images/ReadyToPlay2.png" />
         </image>
      </ImageView>
      <Button fx:id="btnConfirm" layoutX="170.0" layoutY="327.0" mnemonicParsing="false" onAction="#handleBTNConfirmAction" prefHeight="48.0" prefWidth="88.0" text="Confirm">
         <font>
            <Font name="Kristen ITC" size="14.0" />
         </font></Button>
   </children>
</AnchorPane>
Dimax1
  • 7
  • 1

1 Answers1

0

I had a similar problem with an image and its resizing behavior and I was able to find a code snippet which helped me to fix the resizing issue. Please have a look here.

The attached ImageViewPane.java file you may want to use:

/*
 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 */



import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Region;


/**
 *
 * @author akouznet
 */
public 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);
    }
}

I wrote a simple example application so you can play around with the window size and test and see for yourself if the image is resizing how you would like it for your own project. It also shows a way how to add a background image to answer your other, second question:

package org.example;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.util.Collections;


public class App extends Application {

    @Override
    public void start(Stage stage) {

        // Create necessary nodes to show an image and to illustrate its resizing behavior when user resizes the window:
        Image image = new Image("https://images.unsplash.com/photo-1613665287214-25b49c103a4f?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=687&q=80");
        ImageView imageView = new ImageView(image);
        ImageViewPane imageViewPane = new ImageViewPane(imageView);

        // Create a check box and a binding to be able to toggle the preserve ratio property of the image view:
        CheckBox checkBox = new CheckBox("Preserve Ratio");
        checkBox.selectedProperty().bindBidirectional(imageView.preserveRatioProperty());

        // Create a root container for the nodes and add them to it:
        GridPane rootPane = new GridPane();
        rootPane.add(imageViewPane, 0, 0);
        rootPane.add(checkBox, 1, 0);

        // Create and add a column constraint so that the image view pane takes always 30 % of the width:
        ColumnConstraints columnConstraint = new ColumnConstraints();
        columnConstraint.setPercentWidth(30);
        rootPane.getColumnConstraints().add(columnConstraint);

        // Create and add a row constraint so that the nodes are in the center:
        RowConstraints rowConstraint = new RowConstraints();
        rowConstraint.setVgrow(Priority.ALWAYS);
        rowConstraint.setValignment(VPos.CENTER);
        rootPane.getRowConstraints().add(rowConstraint);

        // Set the background image of the root pane (alternatively you can create and use a css stylesheet for this,
        // see https://stackoverflow.com/a/9739698/13561971 for an example):
        String backgroundUrl = "https://images.unsplash.com/photo-1497211419994-14ae40a3c7a3?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80";
        rootPane.setBackground(new Background(Collections.singletonList(new BackgroundFill(
                Color.WHITE,
                new CornerRadii(0),
                new Insets(0))),
                Collections.singletonList(new BackgroundImage(
                        new Image(backgroundUrl, 100, 100, false, true),
                        BackgroundRepeat.NO_REPEAT,
                        BackgroundRepeat.NO_REPEAT,
                        BackgroundPosition.DEFAULT,
                        new BackgroundSize(1.0, 1.0, true, true, false, false)))));

        // Create scene and show:
        stage.setScene(new Scene(rootPane, 800, 600));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
anko
  • 1,628
  • 1
  • 6
  • 14