繁体   English   中英

JavaFX 图像适合 ScrollPane 的宽度

[英]JavaFX image fit to the width of ScrollPane

我正在尝试在ScrollPane中加载图像并使图像始终适合ScrollPane的宽度,即使在 window 调整大小时也是如此,因此您只需垂直滚动即可。 我正在使用 Scene Builder 8.5.0 并且ScrollPane的 Fit To Width 属性设置为 true,但它不起作用并且图像仍然扩展超出ScrollPane的可见宽度。 保留比率也设置为真。 这是我用于此的组件层次结构:

在此处输入图像描述

我还尝试使用代码设置适合宽度属性,但这也不起作用

imgScrollPane.setFitToWidth(true);

我错过了什么吗?

正如您所注意到的,您使用AnchorPane的方法无法按预期工作。

我同意 James_D 的评论并创建了两个示例。 第一个例子是“quick-and-dirty way” ,在fitWidthPropertyImageViewScrollPanewidthProperty之间有一个简单的Binding 第二个示例包含一个小示例 class 为您的需求定制,它覆盖了layoutChildren()方法。

示例 1 (快速而肮脏的Binding ):

package org.example;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;

import java.util.Optional;

public class App extends Application {

    @Override
    public void start(Stage stage) {
        
        String imageUrl = "https://images.freeimages.com/images/large-previews/2e9/fisherman-in-the-lighthouse-1496152.jpg";
        Image image = new Image(imageUrl);
        ImageView imageView = new ImageView(image);

        imageView.setPreserveRatio(true);

        ScrollPane scrollPane = new ScrollPane(imageView);
        
        scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);

        // Example of how the Binding could be (here: take into account if the vertical scroll bar is showing or not):
        imageView.fitWidthProperty().bind(Bindings.createDoubleBinding(() -> {

            // Find the vertical scroll bar of the scroll pane:
            Optional<ScrollBar> verticalScrollBarOpt = scrollPane.lookupAll(".scroll-bar").stream()
                    .filter(node -> node instanceof ScrollBar)
                    .map(node -> (ScrollBar) node)
                    .filter(scrollBar -> scrollBar.getOrientation() == Orientation.VERTICAL).findAny();

            if (verticalScrollBarOpt.isPresent() && verticalScrollBarOpt.get().isVisible())
                return scrollPane.getWidth() - verticalScrollBarOpt.get().getWidth();
            else
                return scrollPane.getWidth();

        }, scrollPane.widthProperty()));

        stage.setScene(new Scene(scrollPane, 1300, 600));
        stage.show();
    }

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

示例 2 (自定义 class 与layoutChildren() ):

package org.example;

import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Region;
import javafx.stage.Stage;

public class App extends Application {

    @Override
    public void start(Stage stage) {

        String imageUrl = "https://images.freeimages.com/images/large-previews/2e9/fisherman-in-the-lighthouse-1496152.jpg";
        Image image = new Image(imageUrl);
        ImageView imageView = new ImageView(image);
        imageView.setPreserveRatio(true);
        CustomImagePane customImagePane = new CustomImagePane(imageView);

        ScrollPane scrollPane = new ScrollPane(customImagePane);

        scrollPane.setFitToWidth(true);

        stage.setScene(new Scene(scrollPane, 1300, 600));
        stage.show();
    }

    /**
     * A simplified example how your custom control could look like.
     */
     public class CustomImagePane extends Region {

        private final ObjectProperty<ImageView> imageView = new SimpleObjectProperty<>();

        public CustomImagePane(ImageView imageView) {
            this.imageView.addListener((observable, oldValue, newValue) -> {
                if (oldValue != null)
                    getChildren().remove(oldValue);

                if (newValue != null)
                    getChildren().add(newValue);
            });
            this.imageView.set(imageView);
        }

        @Override
        protected void layoutChildren() {
            ImageView imageView = getImageView();
            if (imageView != null) {

                imageView.setFitWidth(getWidth());
                imageView.setFitHeight(0);

                layoutInArea(imageView, 0, 0, getWidth(), getHeight(), 0, HPos.CENTER, VPos.CENTER);
            }
            super.layoutChildren();
        }

        public ImageView getImageView() {
            return imageView.get();
        }

        public ObjectProperty<ImageView> imageViewProperty() {
            return imageView;
        }

        public void setImageView(ImageView imageView) {
            this.imageView.set(imageView);
        }
    }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM