[英]JavaFX image fit to the width of ScrollPane
正如您所注意到的,您使用AnchorPane
的方法无法按预期工作。
我同意 James_D 的评论并创建了两个示例。 第一个例子是“quick-and-dirty way” ,在fitWidthProperty
的ImageView
和ScrollPane
的widthProperty
之间有一个简单的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.