JavaFX --Match the size of ImageView with other nodes

A memo when I struggled to fulfill such a desire to make the display of ʻImageView` larger or smaller when the window size was changed. Since it is the result of various trials and errors, the correctness cannot be guaranteed.

When linked with Stage

Implementation

main.fxml


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

<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane fx:controller="sample.javafx.MainController" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1">
   <center>
      <ImageView fx:id="imageView" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
   </center>
</BorderPane>

javafx.jpg

MainController.java


package sample.javafx;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;

import java.net.URL;
import java.nio.file.Paths;
import java.util.ResourceBundle;

public class MainController implements Initializable {
    @FXML
    private ImageView imageView;

    public void initStage(Stage stage) {
        stage.setWidth(300);
        stage.setHeight(200);
        
        imageView.fitWidthProperty().bind(stage.widthProperty());
        imageView.fitHeightProperty().bind(stage.heightProperty());
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        Image image = new Image(Paths.get("./image/shirakawago.jpg ").toUri().toString());
        imageView.setImage(image);
    }
}

Main.java


package sample.javafx;

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

public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(this.getClass().getResource("/main.fxml"));

        Parent root = loader.load();

        MainController controller = loader.getController();
        controller.initStage(primaryStage);

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Execution result

javafx.gif

Description

--Bind the fitWidth and fitHeight properties of ʻImageView to the widthandheight properties of Stage --Note that it is necessary to set the values forwidth and heightofStagein advance. --If nothing is set,width and heightofStage will default to NaN. --If you bind the fitWidth, fitHeight properties of ʻImageView to the width, height properties, it seems that they are initialized to the original size of the set ʻImage`. ――However, if you look closely, the lower part of the image is hidden when you reduce the window size (it is easy to understand if you look at the woman in the lower right)

height | Window (JavaFX 8)

This value includes ** all decorations such as the title bar that can be added by the operating system **.

――So it seems that the image is probably hidden by the height of the title bar.

Match the route of the scene graph

Implementation

javafx.jpg

MainController.java


package sample.javafx;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.net.URL;
import java.nio.file.Paths;
import java.util.ResourceBundle;

public class MainController implements Initializable {
    @FXML
    private BorderPane borderPane;
    @FXML
    private ImageView imageView;
    
    public void initStage(Stage stage) {
        stage.setWidth(300);
        stage.setHeight(200);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        Image image = new Image(Paths.get("./image/shirakawago.jpg ").toUri().toString());
        imageView.setImage(image);
        
        imageView.fitWidthProperty().bind(borderPane.widthProperty());
        imageView.fitHeightProperty().bind(borderPane.heightProperty());
    }
}

Execution result

javafx.gif

Description

--Bind the width, height properties of BorderPane, which is the root of the scene graph, and the fitWidth, fitHeight properties of ʻImageView. --Also, if you do not set the initial values for width and heightofStage, it seems that it will be the original size of ʻImage. ――Even if you reduce the window size, the bottom of the image is not hidden and it seems to be working well

Link with nodes other than the root

When another node comes in

The above method can only be realized as a so-called image viewer because there are no other nodes in the scene graph. As a test, add another node in the scene graph.

Implementation

javafx.jpg

Execution result

javafx.gif

Description

--Since the area is used only for the size of the label, if the size of the root node and the size of ʻImageView` are linked, the range for displaying the image will be insufficient.

For the time being, try adding a node for the image display area

Implementation

javafx.jpg

--Added a new node (BorderPane) to surround ʻImageView --Thewidth and height relationships are all set to the default ʻUSE_COMPUTED_SIZE for the time being. --ʻImageViewshould be implemented so that it works with thewidth and heightproperties of this newly addedBorderPane`.

Execution result

javafx.gif

Description

――It's a little difficult to understand, but the image is displayed in the original size, and only the upper left part is visible. ――I don't understand the principle of why BorderPane is OK when it is the root node and it works like this when it is a child node.

Link with non-root node

Implementation

javafx.jpg

Execution result

javafx.gif

Description

--Set Min Width and Min Height to 0 respectively --Probably, if you set the default ʻUSE_COMPUTED_SIZE, the minimum size of the area will match the size of the child element (here, the size of ʻImageView), so the minimum size = the size of the image, 1 I imagine that the movement was like the one before (just imagine) --However, if so, the conditions should be the same when BorderPane is the root node, so I'm not sure why it didn't happen there. --For the time being, if you want to link the size with the non-root node, it seems to be good if you set Min Width, Min Height to some value other than ʻUSE_COMPUTED_SIZE, ʻUSE_PREF_SIZE.

Summary

--Common --Set width and height of Stage --Bind the fitWidth, fitHeight properties of ʻImageView to the width, heightproperties of the node you want to work with. --When the node to be linked is not the root node --Set the node'sMin Width, Min Height to some value other than ʻUSE_COMPUTED_SIZE, ʻUSE_PREF_SIZSE`

Recommended Posts

JavaFX --Match the size of ImageView with other nodes
Automatically adjust the height of the WebView dialog with the size of the content
Check the contents of params with pry
Introducing the features of JavaFX SceneBuilder container
Ruby from the perspective of other languages
Easily measure the size of Java Objects
About the treatment of BigDecimal (with reflection)
Format the contents of LocalDate with DateTimeFormatter
Verify the contents of the argument object with Mockito
Measure the size of a folder in Java
Manage the version of Ruby itself with rbenv
Overwrite the contents of config with Spring-boot + JUnit5
The story of tuning android apps with libGDX
Calculate the similarity score of strings with JAVA
Prepare the environment of CentOS 8 with Sakura VPS
Specify the default value with @Builder of Lombok
Measure the distance of the maze with breadth-first search
I checked the number of taxis with Ruby
[Personal memorandum] Button layout created with javafx in Eclipse (in the case of HBox / VBox)