Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFx ImageView won't resize on fitWidthProperty bind to VBox

I am trying to re-size an image so it fits (scaled) in the space allotted by a SplitPane (for workaround suggestions: this image will change when running the program, it should be generated from the text). The ImageView I'm using currently changes the location of the SplitPane Divider. The divider can never cause the ImageView to decrease past the size of the image.

Two images showing this behavior.

Linking the ImageView fitWidthProperty to a VBox has not given me the resize behavior I expected. Increasing the ImageView's size does work (where it is fixed without the binding), but the image never grows, it just gets borders around it.

My MWE:

sample.fxml:

<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<SplitPane orientation="HORIZONTAL" xmlns:fx="http://javafx.com/fxml">
    <TextArea fx:id="textArea"/>
    <VBox fx:id="vBox" alignment="CENTER">
        <HBox fx:id="hBox" alignment="CENTER">
            <ImageView fx:id="imageView"/>
        </HBox>
    </VBox>
</SplitPane>

Controller.java:

import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;

public class Controller {
    @FXML
    private TextArea textArea = new TextArea();
    @FXML
    private VBox vBox = new VBox();
    @FXML
    private HBox hBox = new HBox();
    @FXML
    private ImageView imageView = new ImageView();

    public Controller() {
        imageView.fitWidthProperty().bind(vBox.widthProperty());
        imageView.fitHeightProperty().bind(hBox.heightProperty());
    }

    public void start() {
        textArea.setText("text");

        Image image = new Image("https://www.google.nl/images/srpr/logo11w.png");
        imageView.setImage(image);
    }
}

and Main.java:

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 {

    @Override
    public void start(final Stage primaryStage) throws Exception {
        final Controller controller = new Controller();

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("sample.fxml"));
        fxmlLoader.setController(controller);

        final Parent root = fxmlLoader.load();
        primaryStage.setTitle("MWE");
        final Scene scene = new Scene(root, 640, 480);
        primaryStage.setScene(scene);
        primaryStage.show();

        controller.start();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
like image 856
user1658374 Avatar asked Oct 19 '22 06:10

user1658374


2 Answers

You can try binding the ImageView's fitWidthProperty() to the SplitPane's divider position property.

A binding similar to this should work :

imageView.fitWidthProperty().bind(Bindings.subtract(1, 
               splitPane.getDividers().get(0).positionProperty())
                                      .multiply(splitPane.widthProperty());
like image 172
ItachiUchiha Avatar answered Oct 27 '22 18:10

ItachiUchiha


this is my sample for you!

<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<StackPane fx:controller="sample.Controller"
       xmlns:fx="http://javafx.com/fxml" alignment="center">

<SplitPane fx:id="splitpane">
    <VBox fx:id="left" prefWidth="300" prefHeight="200" style="-fx-background-color: antiquewhite">
        <ImageView fx:id="image1" preserveRatio="true" pickOnBounds="true">
            <image>
                <Image url="@/sample/test.jpg"/>
            </image>
        </ImageView>
    </VBox>
    <VBox fx:id="right" prefWidth="300" prefHeight="300" style="-fx-background-color: aquamarine">
        <ImageView fx:id="image2" preserveRatio="true" pickOnBounds="true">
            <image>
                <Image url="@/sample/test.jpg"/>
            </image>
        </ImageView>
    </VBox>
</SplitPane>

package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.SplitPane;
import javafx.scene.image.ImageView;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

    @FXML
    ImageView image1;
    @FXML
    ImageView image2;
    @FXML
    SplitPane splitpane;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
   splitpane.getDividers().get(0).positionProperty().addListener((observable, oldValue, newValue) -> {
        System.out.println(newValue);
        int w = 600;
        double w1 = w * newValue.doubleValue();
        double w2 = w - w1;
        image1.setFitWidth(w1);
        image2.setFitWidth(w2);
    });
   }
}

run result

like image 25
cmlanche Avatar answered Oct 27 '22 16:10

cmlanche