当前位置: 首页 > 知识库问答 >
问题:

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

郭辉
2023-03-14

我对javafx非常陌生。我正试图用scene builder创建一个有趣的纸牌游戏应用程序,但在更改ImageView组件的图像时遇到了问题。

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

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

card.setImage(新图像(“../images/cards/As.png”);

card.setImage(新图像(“@../images/cards/As.png”);

card.setImage(新图像(getClass().getResource(“As.png”).toExternalForm())

card.setImage(新图像(“文件:…images/cards/As.png”)

在每种情况下,我都会得到“无效URL或未找到资源”或“空指针”异常。

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

我从这里的其他线程中得到了这些想法,它们似乎是为其他人工作的。我的照片放错地方了吗?无法更改.fxml文件中某些内容的图像URL吗?如果有人能帮我解决这个问题,我将非常感激。

项目结构:

我启动了一个名为JavaFXApplication1的新项目,以测试图像更改功能。我试图通过点击一个按钮来实现这一点。从上面的项目结构中可以看到,有两个源程序包。有一个“images”包,它只包含我想在应用程序中使用的所有.png,另一个包叫做“javafxapplication1”,包含3个文件。以下是每个项目的代码:

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

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

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

当我运行的应用程序,它加载罚款,与图像在场景生成器中定义(注意:我使用文档相对路径,不确定这是否是理想的或可能是一个问题)。单击按钮后,setImage调用执行,但我没有看到图像中的任何变化。我知道它会执行,因为这是我的输出:

你点击了我!sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@1db87651你换了照片

另外,我不确定是否应该从initialize方法设置fitHeight和width。


共有3个答案

陶乐生
2023-03-14

我能做到的最一致的方法——使用Netbean作为我的集成开发环境——是

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

我的项目目录源结构的img目录与包处于同一级别。从文件系统来看,从.java文件来看,它是。/img/card.jpg,但是使用GetResource将它指向与您的../JavaFXApplication1/src/目录等效的目录

孟谭三
2023-03-14

有两种方法可以加载图像(I prefare)
当您想将图像文件夹嵌入jar(package)文件时,可以使用Sedrick提到的方法,但是如果您想使jar更轻,并将图像文件夹保留在jar之外,我宁愿使用这种方法

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

在本例中,where file关键字使文件浏览器从项目文件夹开始查看JavaFXApplication1

黄弘深
2023-03-14

你的问题:

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

这是无效代码。您在FXML中创建了卡。当你说=newimageview(…),则实际上不再引用FXML中创建的卡/图像视图如果需要在初始化方法中初始化卡/图像视图,请执行以下操作:

@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);
}

 类似资料:
  • 基本上,我有一个方法可以将Image从数据库加载到ImageView中,还有第二个方法可以更改图像,我成功地运行了这两个方法,没有出现异常,但是在change eImage()方法中的setImage之后,我需要更新什么以及如何(场景、阶段)是可能的。我知道在javafx中没有像swings中的repaint()这样的方法,那么我该如何处理呢?

  • 我想问一下,是否有人知道JavaFX ImageView如何处理图像清理。当图像对象/内存空闲时。 以下是给我带来问题的情况:我的场景中有两个“标签”。这是我的标签:在父窗格中的按钮和切换窗格。每个选项卡都有自己的ImageView。在切换窗格之前,我先在旧ImageView上设置空图像,然后加载新图像。我原以为在切换标签后,旧图像从旧图像视图将是免费的,但事实并非如此。 为了监控行为,我使用Ja

  • 我有一个图像视图和一堆图像,但问题是我想一个接一个地显示图像视图中的所有图像,图像应该像gif动画一样每秒钟或每0.2秒改变一次。

  • 我有一个装满图像的文件夹要在我正在创建的游戏中实现,我想在窗口中显示这些。这是我迄今为止的代码。 这将是一个程序在IntelliJ/中从jar运行。“资产”文件夹与此文件位于同一目录中。我没有发现文件路径错误,所以我假设它可以找到图像,但它不会出现在屏幕上,而矩形会出现。 公平警告,我正在从头开始学习JavaFX,我发现没有太多关于事物如何工作的解释,所以这可能是一个愚蠢的问题。

  • 停留在基础上。我在设置图像路径时遇到了一些语法问题。当我尝试创建一个图像并给它图像路径时,它总是抛出一些关于路径的一些异常。我已经评论了一些我已经尝试过的路径组合。你能告诉我我做错了什么吗?谢谢你。 封装JOPOFX; 这是打印出来的内容:错误while creating image java.lang.IllegalArgumentException:无效URL:在javafx.scene.im

  • 我想在对话框窗口中显示图像(保存在项目文件夹中),但当我运行我的方法showDialogWithImage时,我会得到文件NotFoundException:imgs\pic1。jpg(系统无法找到指定的文件),尽管图像位于那里。 我也尝试过以这种方式加载图像: Image=new Image(getClass(). getResourceAsStream(path));,但遇到了同样的问题。 是