Java FX是否要更改ImageView图像或图像URL?

时间:2018-07-21 04:21:31

标签: java javafx scenebuilder

我对Java FX非常陌生。我正在尝试使用场景生成器创建一个纸牌游戏应用程序,但很有趣,但是更改ImageView组件的图像时遇到了问题。

src文件夹包含两个软件包,一个包含所有图像,另一个包含所有代码。

在控制器类中,我尝试使用以下多种组合来更改图像,其中卡是ImageView组件,与{{1}的fx:id匹配}在ImageView中:

SceneBuilder

card.setImage(new Image("../images/cards/As.png");

card.setImage(new Image("@../images/cards/As.png");

card.setImage(new Image(getClass().getResource("As.png").toExternalForm()));

在每种情况下,我最终都会遇到“无效的URL或找不到资源”或“空指针”异常。

例如,如果我转到.fxml并将URL编辑为“ @ .. / images / cards / As.png”,则它可以工作,但是当使用setImage方法时,我做不到。

我从其他线程那里得到的想法似乎是在为其他人工作的。我的图像放置在错误的位置吗?无法更改.fxml文件中某些内容的图像URL?如果有人可以帮助我解决这个问题,我将非常感激。

项目结构:

Project Structure:


我开始了一个名为JavaFXApplication1的新项目,以测试图像更改功能。我试图通过单击按钮来做到这一点。 从上面的项目结构中可以看到,有两个源程序包。有一个“图像”包,其中仅包含我要在我的应用程序中使用的所有.png,然后另一个包称为“ javafxapplication1”,其中包含3个文件。下面是每个代码:

FXMLDocument.fxml

card.setImage(new Image("File:..images/cards/As.png"));

FXMLDocumentController.java

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

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

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication1.FXMLDocumentController">
    <children>
        <Button fx:id="button" layoutX="126" layoutY="90" onAction="#handleButtonAction" text="Click Me!" />
        <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
      <ImageView id="rat" fx:id="card" cache="true" fitHeight="105.0" fitWidth="118.0" layoutX="39.0" layoutY="24.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="39.0" AnchorPane.rightAnchor="208.68595123291016">
         <image>
            <Image url="@../images/cards/back.png" />
         </image></ImageView>
    </children>
</AnchorPane>

JavaFXApplication1.java

package javafxapplication1;

import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

/**
 *
 * @author wesley
 */
public class FXMLDocumentController implements Initializable {
    
    @FXML
    private Label label;
    @FXML
    private ImageView card;
 
    @FXML
    private Button button;
    
    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        label.setText("Hello World!");
        
        System.out.println(getClass().getResourceAsStream("/images/cards/As.png"));
        Image image = new Image(getClass().getResourceAsStream("/images/cards/As.png"));
        card.setFitHeight(726); //726
        card.setFitWidth(500); //500
        card.setImage(image);
        System.out.println("You changed the pic ");
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) 
    {
        //File file = new File("/images/cards/Ad.png");
        //Image image = new Image(file.toURI().toString());
        card = new ImageView("images/cards/Ad.png");
        //card.setFitHeight(726); //726
       // card.setFitWidth(500); //500
    }    
 
}

当我运行该应用程序时,它会很好地加载,并且具有场景构建器中定义的图像(注意:我使用文档相对路径,不确定这是理想的还是可能存在问题)。单击按钮后,将执行setImage调用,但是我看不到图像中的任何更改。我知道它会执行,因为这是我的输出:

  

您点击了我!   sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@1db87651   您更改了图片

此外,我不确定是否应该通过initialize方法设置fitHeight和width。

3 个答案:

答案 0 :(得分:0)

您的问题:

card = new ImageView("images/cards/Ad.png");

这是无效的代码。您在FXML中创建了卡。说= new ImageView(...);时,实际上不再引用在Card/ImageView中创建的FXML

如果您需要在initialize方法中初始化Card/ImageView,请执行以下操作:

@Override
public void initialize(URL url, ResourceBundle rb)
{
    Image image = new Image(getClass().getResourceAsStream("/images/cards/Ad.png"));
    card.setFitHeight(100); //726
    card.setFitWidth(200); //500
    card.setImage(image);
}

答案 1 :(得分:0)

有两种加载图像的方法(我很高兴)
当您想将图像文件夹嵌入jar(包)文件时,使用Sedrick提到的方法, 但是,如果您想使罐子轻巧,将images文件夹放在罐子外面,我宁愿使用这种方式

card.setImage(new Image("file:images/cards/As.png"));

其中file关键字使文件浏览器从我们的案例JavaFXApplication1中的项目文件夹开始查找

答案 2 :(得分:0)

我能做到的最一致的方法-使用Netbeans作为我的IDE-是

new Image(JavaFXApplication1.class.getClass().getResource("/img/card.jpg").toString());

我的项目目录源结构的img目录与软件包位于同一级别。在文件系统中,从.java文件开始,它是../img/card.jpg,但是使用GetResource会将其指向与.../JavaFXApplication1/src/目录等效的文件