user7128116
user7128116

Reputation:

JavaFX ImageView fits container

I'm trying to fit an ImageView in an AnchorPane, the ImageView is obtained from a database, so no CSS, I tried binding the width and height of the ImageView withe the width and height of the AnchorPane, but I get this result:

anchorPane problem

Here's my fxml:

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

<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
       <AnchorPane style="-fx-background-color: grey;" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
           <children>
               <Label fx:id="nombrePlato" alignment="CENTER" contentDisplay="CENTER" maxHeight="50.0" prefHeight="50.0" text="Nombre del Plato" textAlignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                   <font>
                       <Font size="30.0" />
                   </font>
               </Label>
           </children>
       </AnchorPane>
       <AnchorPane fx:id="anchorPane" layoutY="300.0" styleClass="anchorPane" stylesheets="@../../../../core/resources/css/MainCSS.css" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="50.0">
         <children>
            <ImageView fx:id="imagenPlato" fitHeight="100.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" />
         </children>
      </AnchorPane>
   </children>
</AnchorPane>

And here's my method:

public void rellenar(Label nombrePlato, ImageView imagenPlato, Plato plato, AnchorPane anchorPane) throws SQLException {

        nombrePlato.setText(plato.getNombre());
        Blob blob = plato.getRutaImagen();
        int blobLength = (int) blob.length();
        byte[] blobAsBytes = blob.getBytes(1, blobLength);
        Image convertToJavaFXImage = convertToJavaFXImage(blobAsBytes, 1024, 768);
        imagenPlato.setImage(convertToJavaFXImage);

        imagenPlato.fitWidthProperty().bind(anchorPane.widthProperty());
        imagenPlato.fitHeightProperty().bind(anchorPane.heightProperty());
    }

Any idea how to make it fit he anchorPane and make it responsive?

Upvotes: 4

Views: 4638

Answers (3)

geometrikal
geometrikal

Reputation: 3294

Grab ImageViewPane class from here as referenced from this bug ticket and place inside project.

Then wrap your image view in your FXML as so:

<?import PATH.TO.CLASS.ImageViewPane?>

<ImageViewPane fx:id="imageViewPane">
  <imageView>
    <ImageView fx:id="imageView"
               pickOnBounds="true"
               preserveRatio="true">
    </ImageView>
  </imageView>
</ImageViewPane>

The problem is ImageView only has fitWidth/fitHeight properties which do not conform to the parent's size or preferred size. ImageViewPane wraps ImageView in a pane and updates the ImageView's fitWidth/fitHeight properties to the pane's size.

Upvotes: 3

jewelsea
jewelsea

Reputation: 159291

As an alternative to an ImageView, you could use a CSS -fx-background-image attribute on a Region (such as your AnchorPane). The CSS -fx-background-size option will provide you with various sizing alternatives such as cover or contain:

contain

Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.

cover

Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.

Upvotes: 6

Michael Berry
Michael Berry

Reputation: 72284

Your problem most likely lies in the following line:

<ImageView fx:id="imagenPlato" fitHeight="100.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" />

Specifically, you've set:

preserveRatio="true"

...which will try to keep the aspect ratio the same, so the image won't fill the container. Set it to false instead, and you should be good to go.

Upvotes: 3

Related Questions