你的方法存在问题
你没有一个格式良好的URL
new Image(String url)需要一个URL作为参数。
空格不是URL的有效字符:
这就是为什么你的x
字符串不是一个有效的URL,不能用来构建一个图像。
你需要提供Image构造函数识别的输入
请注意,稍微有点复杂,因为从Image javadoc中可以看到,url参数可能是一些其他的东西,但即使如此,它们也都与你尝试查找的内容不匹配。
如果将URL字符串传递给构造函数,则可以是以下任何一种情况:
- 可以由此线程的上下文类加载器解析的资源名称
- 可以由文件解析的文件路径
- 可以由URL解析并存在协议处理程序的URL
除了已注册应用程序的协议处理程序外,还支持RFC 2397“数据”方案的URL。 如果URL使用“数据”方案,则数据必须是base64编码的,并且MIME类型必须为空或图像类型的子类型。
你假设资源在文件系统中,但这不总是有效的。
如果将资源打包到jar中,则无法正常工作。
Arrays.asList(
new File(
Thread.currentThread()
.getContextClassLoader()
.getResource(packageName)
.toURI()
).listFiles()
);
这样做行不通,因为JAR包中的文件是使用
jar:
协议而不是
file:
协议定位的。因此,您将无法从getResource返回的
jar:
协议URI创建File对象。
推荐方法:使用Spring
从jar获取资源列表实际上是一件相当棘手的事情。从您链接的问题中,最简单的解决方案是使用
不幸的是,这意味着需要依赖于Spring框架才能使用它,这对于这个任务来说是完全过度的......但是我不知道还有什么其他简单而强大的解决方案。但至少您可以调用Spring实用程序类,您不需要启动整个Spring依赖注入容器来使用它,所以您实际上不需要了解任何Spring或遭受任何Spring开销就可以这样做。
因此,您可以编写像这样的内容(ResourceLister是我创建的一个类,以及toURL方法,请参见示例应用程序):
public List<String> getResourceUrls(String locationPattern) throws IOException {
ClassLoader classLoader = ResourceLister.class.getClassLoader();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(classLoader);
Resource[] resources = resolver.getResources(locationPattern);
return Arrays.stream(resources)
.map(this::toURL)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
可执行示例
ResourceLister.java
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class ResourceLister {
private static final String IMAGE_PATTERN =
"classpath:/img/*.png";
public List<String> getImageUrls() throws IOException {
return getResourceUrls(IMAGE_PATTERN);
}
public List<String> getResourceUrls(String locationPattern) throws IOException {
ClassLoader classLoader = ResourceLister.class.getClassLoader();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(classLoader);
Resource[] resources = resolver.getResources(locationPattern);
return Arrays.stream(resources)
.map(this::toURL)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
private String toURL(Resource r) {
try {
if (r == null) {
return null;
}
return r.getURL().toExternalForm();
} catch (IOException e) {
return null;
}
}
public static void main(String[] args) throws IOException {
ResourceLister lister = new ResourceLister();
System.out.println(lister.getImageUrls());
}
}
AnimalApp.java
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class AnimalApp extends Application {
private static final double ANIMAL_SIZE = 512;
private final Random random = new Random(42);
private final ResourceLister resourceLister = new ResourceLister();
private List<Image> images;
@Override
public void init() {
List<String> imageUrls = findImageUrls();
images = imageUrls.stream()
.map(Image::new)
.collect(Collectors.toList());
}
@Override
public void start(Stage stage) {
ImageView animalView = new ImageView();
animalView.setFitWidth(ANIMAL_SIZE);
animalView.setFitHeight(ANIMAL_SIZE);
animalView.setPreserveRatio(true);
Button findAnimalButton = new Button("Find animal");
findAnimalButton.setOnAction(e ->
animalView.setImage(randomImage())
);
VBox layout = new VBox(10,
findAnimalButton,
animalView
);
layout.setPadding(new Insets(10));
layout.setAlignment(Pos.CENTER);
stage.setScene(new Scene(layout));
stage.show();
}
private List<String> findImageUrls() {
try {
return resourceLister.getImageUrls();
} catch (IOException e) {
e.printStackTrace();
}
return new ArrayList<>();
}
private Image randomImage() {
if (images == null || images.isEmpty()) {
return null;
}
return images.get(random.nextInt(images.size()));
}
public static void main(String[] args) {
launch(args);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>resource-lister</artifactId>
<version>1.0-SNAPSHOT</version>
<name>resource-lister</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.7.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>LATEST</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
图片
放置在src/main/resources/img中。
- chicken.png
- cow.png
- pig.png
- sheep.png
![sheep](https://istack.dev59.com/SQDi4.webp)
执行命令
设置您的JavaFX SDK安装的VM参数:
-p C:\dev\javafx-sdk-17.0.2\lib --add-modules javafx.controls