gpt4 book ai didi

javafx - 包含 ImageView 的 ScrollPane 在调用 setImage() 后不会更新其滚动条

转载 作者:行者123 更新时间:2023-12-01 11:41:10 24 4
gpt4 key购买 nike

我正在使用简单的图像查看器试验 JavaFX。我希望它显示图像,如果它不适合窗口,则显示滚动条。要显示的图像使用 FileChooser 加载并使用 imageView.setImage(image) 设置为 ImageView

问题是包含 ScrollPane 的滚动条在调用 imageView.setImage(image)更新。相反,我需要执行更改场景的操作(例如调整窗口大小)。当显示一个图像并加载另一个图像时,它的行为相同,即滚动条的大小反射(reflect)了前一个图像的大小。


使用以下代码的简化版本可以重现该错误:

(Java)

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

public class ImageViewerBug extends Application
{
@FXML private ImageView imageView;

@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ImageViewerBug.fxml"));
fxmlLoader.setController(this);
try {
BorderPane borderPane = (BorderPane) fxmlLoader.load();
Scene scene = new Scene(borderPane);
primaryStage.setScene(scene);
primaryStage.show();
}
catch( IOException e ) {
throw new RuntimeException(e);
}
}

public void loadClicked() {
FileChooser fileChooser = new FileChooser();
File f = fileChooser.showOpenDialog(null);
if( f != null ) {
try( InputStream is = new FileInputStream(f) ) {
Image image = new Image(is);
imageView.setImage(image);
}
catch( IOException e ) {
e.printStackTrace();
}
}
}

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

(FXML)

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

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.Group?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<BorderPane id="BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml">
<center>
<ScrollPane prefHeight="200.0" prefWidth="200.0">
<content>
<Group>
<ImageView fx:id="imageView" pickOnBounds="true" preserveRatio="true" />
</Group>
</content>
</ScrollPane>
</center>
<top>
<ToolBar>
<items>
<Button mnemonicParsing="false" onAction="#loadClicked" text="Load" />
</items>
</ToolBar>
</top>
</BorderPane>

最佳答案

我可以确认这个错误。一个快速而肮脏的解决方法为我修复了它:

    public void loadClicked() {
FileChooser fileChooser = new FileChooser();
File f = fileChooser.showOpenDialog(null);
if( f != null ) {
try( InputStream is = new FileInputStream(f) ) {
Image image = new Image(is);
imageView.setImage(image);
imageView.snapshot(new SnapshotParameters(), new WritableImage(1, 1));
double rnd = new Random().nextInt(10);
imageView.setX(rnd/1000);
imageView.setY(rnd/1000);
}
catch( IOException e ) {
e.printStackTrace();
}
}
}

snapshot() 方法有时会在某些 UI 元素未更新或未正确显示时发挥作用。但不要问我为什么会这样,也许它与渲染过程有关,因为 snapshots 强制 JavaFX 渲染场景图或目标元素。在 ImageView 的一部分之后添加新图像时,需要随机的东西来创建正确的滚动条大小。也许这与 strange behaviour i found some weeks earlier 有关.解决方法也解决了我当时的问题。

(真的很晚)编辑

问题是由包装 ImageViewGroup 引起的。如果您使用从 Pane 继承的节点,即使没有解决方法,ScrollPane 的行为也应该符合预期。只要 Pane 包裹 ImageViewGroup 仍然可以用作 ScrollPane 的直接子级。

例子:

<ScrollPane prefHeight="200.0" prefWidth="200.0">
<content>
<Group id="Group">
<children>
<HBox id="HBox" alignment="CENTER" layoutX="0.0" layoutY="0.0" spacing="5.0">
<children>
<ImageView fx:id="imageView" pickOnBounds="true" preserveRatio="true" />
</children>
</HBox>
</children>
</Group>
</content>
</ScrollPane>

关于javafx - 包含 ImageView 的 ScrollPane 在调用 setImage() 后不会更新其滚动条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20610950/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com