Ivar Eriksson
Ivar Eriksson

Reputation: 973

JavafX - Dynamic ImageView Set Default Size

I have an ImageView which I have configured so that it is resized to fit its parent AnchorPane with the two following lines of code (both the AnchorPane and the image are square).

preview.fitWidthProperty().bind(previewPane.maxWidthProperty());
preview.fitHeightProperty().bind(previewPane.maxWidthProperty());

I have also set a fitWidth of 450 px in an fxml file that injects all nodes. When I create an instance of this object however it opens the preview with a width equal to that of the loaded image (2000 px) and not 450 px. The resizing functionality works as expected and it is possible to shrink it down to 450 px. I was wondering however if it is possible to make sure it opens up with a default size different from that of the width of the image but also making sure so that it grows and shrinks with its parent.

I have tried setting loads of different default widths in both java code and fxml but the only thing that seems to work is unbinding the fitWidth which I don't want.

Do you have any suggestions as to how I might solve this?

Main:

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class MainTest extends Application {

    @FXML private AnchorPane previewPane;
    @FXML private ImageView preview;

    @Override
    public void start(Stage primaryStage) {

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Test.fxml"));
        fxmlLoader.setController(this);
        fxmlLoader.setClassLoader(getClass().getClassLoader());

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }

        preview.fitWidthProperty().bind(previewPane.maxWidthProperty());
        preview.fitHeightProperty().bind(previewPane.maxWidthProperty());
        Scene scene = new Scene(previewPane);

        primaryStage.setTitle("Test");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

FXML:

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

<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane fx:id="previewPane" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <ImageView fx:id="preview" fitHeight="450.0" fitWidth="450.0" layoutX="55.0" layoutY="36.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <image>
            <Image url="@Blue%20Eyes%20White%20Dragon.png" />
         </image>
      </ImageView>
   </children>
</AnchorPane>

EDIT: Here is a MCVE of my problem.

Upvotes: 0

Views: 2353

Answers (1)

SedJ601
SedJ601

Reputation: 13859

The structure of your project is wrong. Also, to fix the problem you are having, you need to set the Scene size.

Code to get the ImageView from the Controller

//Code in the Main
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
Parent root = loader.load();
FXMLDocumentController fXMLDocumentController = loader.getController();
ImageView preView = fXMLDocumentController.getPreview();

//Code in the Controller
public ImageView getPreview()
{
    return preview;
}

Code to set the Scene's size

stage.setWidth(450);
stage.setHeight(450);

Main

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication213 extends Application
{

    @Override
    public void start(Stage stage) throws Exception
    {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
        Parent root = loader.load();
        FXMLDocumentController fXMLDocumentController = loader.getController();
        ImageView preView = fXMLDocumentController.getPreview();

        Scene scene = new Scene(root);

        stage.setWidth(450);
        stage.setHeight(450);
        stage.setScene(scene);
        stage.show();

        preView.fitHeightProperty().bind(stage.heightProperty());
        preView.fitWidthProperty().bind(stage.widthProperty());
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

}

Controller

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.ImageView;

/**
 *
 * @author blj0011
 */
public class FXMLDocumentController implements Initializable
{

    @FXML
    private ImageView preview;

    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        // TODO

    }

    public ImageView getPreview()
    {
        return preview;
    }
}

FXML

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

<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="previewPane" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication213.FXMLDocumentController">
    <children>
        <ImageView fx:id="preview" fitHeight="450.0" fitWidth="450.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
            <image>
                <Image url="@Blue%20Eyes%20White%20Dragon.png" />
            </image>
        </ImageView>
    </children>
</AnchorPane>

Finally, you need to uncheck Preserve Ratio. The FXML should already have this unchecked. I am pointing this out because it's important.

enter image description here

Upvotes: 1

Related Questions