Javafx:将ImageView绑定到Anchorpane或VBox,并通过调整场景大小来缩放ImageView.&l



我想通过调整场景(窗口)的大小来缩放ImageView,但我必须保持长宽比。有可能通过调整窗口大小直接做到这一点吗?谢谢你的帮助。问题是,ImageView不能通过调整窗口大小来缩放。我的另一个问题是:我如何将图像绑定到背景,使其始终适合窗口和调整大小,当我调整窗口的大小?

谢谢你的帮助

下面是我的fxml代码:

<?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>

我有一个图像和它的大小调整行为类似的问题,我能够找到一个代码片段,这有助于我解决大小调整问题。请看这里。

附件ImageViewPane.java您可能想要使用的文件:

/*
* 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);
}
}

我写了一个简单的示例应用程序,所以你可以玩周围的窗口大小和测试,看看自己的图像是如何调整大小,你希望它为自己的项目。它还展示了如何添加背景图像来回答您的第二个问题:

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();
}
}

最新更新