JavaFX:使用文件选择器移动文件后,图像未显示在图像视图中



在我的JavaFX GUI中,允许用户编辑他们的帖子,这涉及将现有图像更改为用户上传的图像。这就是下面显示的功能的用武之地。

postImage 是我从 FXML 文件中引用的图像视图 -@FXML private ImageView postImage;

private void uploadImage(ActionEvent actionEvent) {
// Create fileChooser
FileChooser fileChooser = new FileChooser();
FileChooser.ExtensionFilter extFilterImages = new FileChooser.ExtensionFilter("Image files (*.jpg)", "*.JPG", "*.PNG");
fileChooser.getExtensionFilters().addAll(extFilterImages);
// open dialog to have user select an image from the file system
File selectedFile = fileChooser.showOpenDialog(title.getScene().getWindow());
if (selectedFile != null) {
System.out.println("File selected:" + selectedFile);
System.out.println("Selected Image: " + selectedFile.getName());
Path source = FileSystems.getDefault().getPath(selectedFile.getPath());
String fileExtension = selectedFile.getName().substring(selectedFile.getName().lastIndexOf("."));
String imagePath = "newImageUploaded" + fileExtension;
Path destination = FileSystems.getDefault().getPath("resources/images/" + imagePath);
System.out.println("Source: " + source);
System.out.println("Destination: " + destination);
// moving the uploaded image to the resources folder
try {
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ioException) {
ioException.printStackTrace();
System.out.println("Exception Caught");
}
System.out.println("Changing image: " + imagePath);
// Set the uploaded image in the ImageView in GUI.
postImage.setImage(new Image("/images/" + imagePath)); // error on this line: PostDetailsController.java:326
}
}

运行此功能时,图像将成功移动并显示在我的资源文件夹中。但是,应该更新我的图像的最后一行postImage.setImage(new Image("/images/" + imagePath));给了我以下错误:

File selected:/Users/vaishnavinaik/Downloads/shoes.jpg
Selected Image: shoes.jpg
Source: /Users/vaishnavinaik/Downloads/shoes.jpg
Destination: resources/images/newImageUploaded.jpg
Changing image: newImageUploaded.jpg
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Invalid URL: Invalid URL or resource not found
at javafx.graphics/javafx.scene.image.Image.validateUrl(Image.java:1107)
at javafx.graphics/javafx.scene.image.Image.<init>(Image.java:617)
at controller.PostDetailsController.uploadImage(PostDetailsController.java:326)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8879)
at javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3851)
at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1200(Scene.java:3579)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2588)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:390)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
at javafx.graphics/com.sun.glass.ui.mac.MacView.notifyMouse(MacView.java:127)
Caused by: java.lang.IllegalArgumentException: Invalid URL or resource not found
at javafx.graphics/javafx.scene.image.Image.validateUrl(Image.java:1099)
... 46 more

是否有可能在执行语句postImage.setImage(new Image("/images/" + imagePath));时,移动尚未完成?将图像设置为图像视图时我做错了什么吗?

Image构造函数期望将表示URLString传递给它。如文档中所述

如果传递的字符串不是有效的 URL,而是路径,则 在这种情况下,将在类路径上搜索图像。

因此,您在这里有效地尝试在运行时修改类路径的内容;这是不可行的(例如,如果应用程序从jar文件运行,这在生产中几乎肯定是正确的,则必须在运行时修改该jar文件的内容,这可能是不可能的(。

假设此处的目标是保留映像,以便在用户下次运行应用程序时可用,通常的方法是将映像复制到用户系统上的文件夹,该文件夹旨在存储应用程序的用户特定数据。(替代方法可能是将图像数据存储在本地或远程数据库中,具体取决于应用程序。常见的方案是仅使用名称以.开头并包含应用程序名称且位于用户主目录中的文件夹:

Path applicationDataPath = Paths.get(System.getProperty("user.home"), ".my-application");
Files.createDirectories(applicationDataPath);

现在你可以做

Path destination = applicationDataPath.resolve("newImageUploaded"+fileExtension);
try {
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Changing image: " + imagePath);
// Set the uploaded image in the ImageView in GUI.
postImage.setImage(new Image(destination.toUri().toURL().toExternalForm())); 
} catch (IOException ioException) {
ioException.printStackTrace();
System.out.println("Exception Caught");
}

您还可以相当容易地,例如,在应用程序启动时检查该文件是否存在,并根据需要显示图像等。

最新更新