Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么JavaFXImageView有时需要BuffereImage来显示任何内容?_Javafx_Imageview - Fatal编程技术网

为什么JavaFXImageView有时需要BuffereImage来显示任何内容?

为什么JavaFXImageView有时需要BuffereImage来显示任何内容?,javafx,imageview,Javafx,Imageview,当前正在尝试实现将警告图形放置在输入字段旁边 将ImageView拖放到场景生成器中,找到文件,生成: <ImageView fx:id="helpPic" fitHeight="22.0" fitWidth="33.0" layoutX="47.0" layoutY="336.0" onMouseClicked="#warnInfo" pickOnBounds="true" preserveRatio="true"> <image>

当前正在尝试实现将警告图形放置在输入字段旁边

将ImageView拖放到场景生成器中,找到文件,生成:

    <ImageView fx:id="helpPic" fitHeight="22.0" fitWidth="33.0" layoutX="47.0" layoutY="336.0" onMouseClicked="#warnInfo" pickOnBounds="true" preserveRatio="true">
       <image>
          <Image url="@../../Library/risk-468289_640.png" />
       </image>
    </ImageView>
没有错误,仍然没有图像

为了验证它不是图像,我在mspaint中潦草地写了一些东西作为jpg,并尝试加载它,但它仍然没有显示任何内容

为了寻找解决方案,我通过以下途径实现了:

BufferedImage bufferedImage = ImageIO.read(new File("Library/risk-468289_640.png"));
Image image = SwingFXUtils.toFXImage(bufferedImage, null);
helpPic.setImage(image);
但是FXML/ImageView需要额外的处理来完成它的一项工作,这似乎非常奇怪

编辑:

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("MainWindow.fxml"));

    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.resizableProperty().setValue(Boolean.FALSE);
    stage.show();
}

我不太明白为什么FXML版本对您不起作用,但我可以给您一个如何工作的描述,这应该足以让您了解到底发生了什么

当FXMLLoader遇到以@开头的属性值时,它将其视为资源位置,并将其解析为URL,如中所述。这基本上意味着它通过调用

new URL(location, spec);
其中location是FXMLLoader的location属性,spec是前导@stripped off的属性值。这将根据描述的规则进行解析

FXMLLoader的location属性则是传递给或静态的值。在本例中,您可以使用getClass.getResourceMainWindow.fxml创建此URL。我一直认为这意味着获取一个URL,它从加载这个类的相同位置加载资源:显然这是一个非正式的定义,精确的描述是。粗略地说,如果您提供的字符串不是以/开头,那么将在与类相同的包中搜索资源;否则,通常会在类路径中搜索它。URL的方案取决于与当前类关联的类加载器。因此,如果您是从文件系统运行应用程序,实际的URL如下所示file:///path/to/current/package/MainWindow.fxml. 如果您是从一个jar文件运行的,它看起来像jar:///path/to/jar/file!/package/mainfown.fxml或类似的东西,其中package是定义类的包,带有。替换为/

因此,如果FXMLLoader的location属性有一个file:scheme,那么在假定文件位于正确位置的情况下,基本上应该可以正常工作。你基本上是这样的

new URL("file:///path/to/current/package/MainWindow.fxml", "../../Library/risk-468289_640.png");
第一个参数实际上是一个现有的URL对象,而不是字符串。由于file:scheme可以很好地理解父目录符号..,因此应该可以正常工作

另一方面,如果您的类是由jar类装入器装入的,则可能会出现问题:

new URL("jar:///path/to/jar/file!/package/MainWindow.fxml", "../../Library/risk-468289_640.png");
如果这里的父目录级别比包级别多,jar类装入器将无法创建任何有意义的内容。scheme意味着从jar文件加载,但您正试图跳出jar文件条目层次结构的顶层

这听起来像是您试图访问类路径之外的文件资源:使用FXML资源位置执行此操作并不一定成功,因为它实际上是尝试使用类加载器加载资源,而类加载器通常只真正了解类路径中的内容。具体地说,使用jar类装入器,它将失败

您可以在start方法中添加一些调试,以尝试查看正在发生的情况:

URL fxmlURL = getClass().getResource("MainWindow.fxml") ;
System.out.println(fxmlURL.toExternalForm());
URL resourceURL = new URL(fxmlURL, "../../Library/risk-468289_640.png");
System.out.println(resourceURL.toExternalForm());

Parent root = FXMLLoader.load(fxmlURL);
这至少可以让您看到FXMLLoader正在尝试做什么,并且您应该能够看到结果URL是否有意义

如果您是从文件系统而不是从类路径加载映像,那么最好显式创建一个文件URL,您必须在Java代码中这样做,即在控制器中:

helpPic.setImage(new Image("Library/risk-468289_640.png"));
// path is relative to working dir: use an absolute path if needed
File imageFile = new File("Library/risk-468289_640.png"); 
String imageURL = imageFile.toURI().toURL().toExternalForm(); 
helpPic.setImage(new Image(imageURL));

您使用的是Windows、Linux或Mac?javafx.scene.image.image构造函数需要有效URI的字符串版本。是否帮助pic.setImagenew-Imagenew-FileLibrary/risk-468289_640.png.toUri.toString;工作对于FXML版本,我必须检查这一点,但我认为。。不能在这种上下文中解释如果所有内容都在一个文件系统上是有意义的,但是一旦所有内容都绑定到一个jar文件中,它就不能再形成一个有效的URI。如果我有时间,我将尝试如何在没有其他人先做的情况下发布真实答案。最初的案例由场景生成器通过文件选择器对话框提供。我稍后会尝试一下代码,看看它是否有效。不过,我觉得这有点傻。如果可以在文件中指定的位置将文件标识为存在,那么该文件不应该包含任何接受文件以对其进行解析的必要信息。如果不是,它不应该抛出一些东西吗?是的,它应该抛出一个异常。所以,也许我找错了方向,还有别的事情不对劲。让我用父目录测试一下@resource位置解析。不是说你现在可以编辑它,而是toURI而不是toURI,不过它似乎可以工作。