简体   繁体   English

Java FX更改ImageView图像或图像URL?

[英]Java FX Changing ImageView image or image URL?

I am very new to Java FX. 我是Java FX的新手。 I am trying to create a card game application with scene builder for fun but have been having issues changing the image of ImageView components. 我正在尝试使用场景生成器创建一个纸牌游戏应用程序,但很有趣,但是更改ImageView组件的图像时遇到了问题。

The src folder contains two packages, one for the all the images and the other containing all the code. src文件夹包含两个软件包,一个包含所有图像,另一个包含所有代码。

In the controller class, I've tried to change the image by using many combinations of the following, where the card is an ImageView component, which matches the fx:id of the ImageView in SceneBuilder : 在控制器类中,我尝试使用以下多种组合来更改图像,其中卡是ImageView组件,与SceneBuilder ImageViewfx:id相匹配:

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()));

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

In every scenario, I end up getting either an "Invalid URL or Resource not found" or "Null Pointer" exception. 在每种情况下,我最终都会收到“无效的URL或找不到资源”或“空指针”异常。

If I go to the .fxml and edit the URL to "@../images/cards/As.png", for example, then it works but when using the setImage method I can't do it. 例如,如果我转到.fxml并将URL编辑为“ @ .. / images / cards / As.png”,则它可以工作,但是当使用setImage方法时,我做不到。

I got those ideas from other threads on here where they worked for other people it seems. 我从其他线程那里得到的想法似乎是在为其他人工作的。 Are my images in the wrong place? 我的图像放置在错误的位置吗? Is it not possible to change the image URL of something in the .fxml file? 无法更改.fxml文件中某些内容的图像URL? If anyone can help me out with this i would appreciate it very much. 如果有人可以帮助我,我将非常感激。

Project Structure: 项目结构:

项目结构:


I started a new project, called JavaFXApplication1, to test image changing functionality. 我开始了一个名为JavaFXApplication1的新项目,以测试图像更改功能。 I am trying to do this with the click of a button. 我试图通过单击按钮来做到这一点。 There are two source packages, as you can see from the project structure above. 从上面的项目结构中可以看到,有两个源程序包。 There is the 'images' package that just contains all of the .pngs i want to use in my application, and then the other package is called 'javafxapplication1', containing 3 files. 有一个“图像”包,其中仅包含我要在我的应用程序中使用的所有.png,然后另一个包称为“ javafxapplication1”,其中包含3个文件。 Below is the code for each: 下面是每个代码:

FXMLDocument.fxml FXMLDocument.fxml

 <?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> 

FXMLDocumentController.java FXMLDocumentController.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 } } 

JavaFXApplication1.java JavaFXApplication1.java

 package javafxapplication1; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; /** * * @author */ public class JavaFXApplication1 extends Application { @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } 

When I run the application, It loads fine, with the image there that was defined in scene builder (Note: I use a document relative path, not sure if this is ideal or could be an issue). 当我运行该应用程序时,它会很好地加载,并具有在场景构建器中定义的图像(注意:我使用文档相对路径,不确定这是理想的还是可能存在问题)。 Upon clicking the button, the setImage call executes, but I see no change in the image. 单击按钮后,将执行setImage调用,但是我看不到图像中的任何更改。 I know it executes because this is my output: 我知道它会执行,因为这是我的输出:

You clicked me! 你点击了我! sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@1db87651 You changed the pic sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@1db87651您更改了图片

Also, I'm not sure if I should be setting the fitHeight and width from the initialize method or not. 另外,我不确定是否应该通过initialize方法设置fitHeight和width。

Your problem: 你的问题:

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

This is invalid code. 这是无效的代码。 You created the card in the FXML . 您在FXML创建了卡。 When you say = new ImageView(...); 当你说= new ImageView(...); , you are effectively no longer referencing the Card/ImageView create in the FXML . ,您实际上不再引用FXML创建的Card/ImageView

If you need to initialize the Card/ImageView in the initialize method do: 如果您需要在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);
}

There are two methodsTo load images (I prefare) 加载图像有两种方法 (预检)
The way mentioned by Sedrick is used when you wanna embed the images folder inside the jar (package) file, But if you wanna make the jar light weight and leave the images folder outside of the jar I'd rather use this way 当您要将images文件夹嵌入jar(打包)文件时,可以使用Sedrick提到的方法, 但是,如果您想使Jar轻巧,将images文件夹保留在jar之外,我宁愿使用这种方式

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

where file keyword make the file browser start looking from the project folder in our case JavaFXApplication1 其中,file关键字使文件浏览器从我们的案例JavaFXApplication1中的项目文件夹开始查找

The most consistent way I could do it - using Netbeans as my IDE - was 我能做到的最一致的方法-使用Netbeans作为我的IDE-是

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

And my project directory source structure has the img directory on the same level as the package. 我的项目目录源结构中的img目录与软件包相同。 From the file system, from the .java file it is ../img/card.jpg , but using GetResource points it to the equivalent of your .../JavaFXApplication1/src/ directory 在文件系统中,从.java文件为../img/card.jpg ,但使用GetResource会将其指向.../JavaFXApplication1/src/目录的等效目录。

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

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