0

This is what my project structure looks like:

structure

I need to search through a specific subdirectory of the resource's folder for a file that starts with the substring orientation. If I have the filename I can easily load the image in my java fx GUI. I have tried multiple different ways, but nothing seems to work. All files of the img folder in are also inclueded in the build folder. I'm using JDK 17 and gradle 7.6.

Using Reflections:

private static String infoToPath(String info, String orientation) {
        
        // [...] convert info to roomDir
 
        String roomDir = "img/100/108/";

        Reflections reflections = new Reflections("com.client", new ResourcesScanner());
        Set<String> resourceList = reflections.getResources(Pattern.compile(".*"));

        String image = resourceList.iterator().next();
        return image;
    }

This results in a NoSuchElementException (i.e. no resources are added to resourceList) although it should match everything (see the regex) in src/main/resources/img/100/108/ (which is not empty).


Using an InputStream:

private static String infoToPath(String info, String orientation) {
        
        // [...] convert info to roomDir
 
        String roomDir = "img/100/108/";

        InputStream resourceStream = GameController.class.getResourceAsStream("roomDir");

        File tempFile = null;
        try {
            tempFile = File.createTempFile("temp", ".txt");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        try (OutputStream outputStream = new FileOutputStream(tempFile)) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = resourceStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


        File file = new File(tempFile.getAbsolutePath());


        File[] files = file.listFiles();

        String name = null;
        for (File image : files) {
            if (image.getName().substring(0,1).equals(orientation)) { 
            // match first character to orientation
                name = image.getName();
            }
        }


        tempFile.delete();

        return name;

Here, it fails because the InputStream is null. I have tried various other Strings than roomDir such as:

  • ./src/main/resources/img/100/108/
  • src/main/resources/img/100/108/
  • ./img/100/108
  • img/100/108

I am certain I'm making a wrong assumption somewhere. But I just can't find it.

  • Things within a JAR file don't have a filename. Certainly not a name / path that you could use with `File` or `FileInputStream`. – Stephen C Apr 03 '23 at 16:12
  • [Instead of opening the file as a FileInputStream, use getResourceAsStream](https://stackoverflow.com/a/1457264/2834978) – LMC Apr 03 '23 at 16:33
  • @StephenC So it's impossible since Gradle always makes a jar? And how does JavaFX know what files to load then? `.setImage(/img/some/folders/example.jpg)` works perfectly fine. – Tzatzikiiii Apr 03 '23 at 16:40
  • JavaFX knows how to look for resources. What you works only works because you are still on the development computer and the file happens to be in the path you mention. Move the jar to another computer and it won't work. – RealSkeptic Apr 03 '23 at 17:25
  • 1
    *"And how does JavaFX know what files to load then?"* - JavaFX is not loading files. It is loading resources. The point is that they are NOT files. They are not in the file system. They are in the JAR file and need to be treated as such. – Stephen C Apr 03 '23 at 22:33

0 Answers0