0

Why can't I iterate through files in this example:

private List<String> bilder;
    private int bildNummer;


    public void initialize(URL location, ResourceBundle bundle) {
        // before maven: ladeBilder(new File("/img/settings"));
        ladeBilder(new File(String.valueOf((SettingsController.class.getResource("/img/settings")))));
        //imgView.setImage(uebergebeBilder());
    }

    private Image uebergebeBilder() {
        if(bildNummer <= 13){
            String bild = bilder.get(bildNummer);
            bildNummer++;
            return new Image("sample/img/settings/"+bild);
        } else{
            bildNummer = 0;
            String bild = bilder.get(bildNummer);
            bildNummer++;
            return new Image("sample/img/settings/"+bild);
        }
    }

    private void ladeBilder(final File pfad) {
        if(bilder == null) {
            bilder = new ArrayList<String>();
        } else {
            bilder.clear();
        }

        File[] files = pfad.listFiles((dir, name) -> {
            if(name.equals(".DS_Store")){
                return false;}
            else if(name.equals("thumbs.db")){
                return false;
            }else{
                return true;
            }
        });
        for(File f : files) {
            if(f.isDirectory()) {
                ladeBilder(f);
            } else {
                bilder.add(f.getName());
            }
        }
    }

It worked before I add the maven framework. System.out.println(String.valueOf((SettingsController.class.getResource("/img/settings")))); gave me the following path: file:/Users/****/****/Proggen/Passwort-Manager19/target/classes/img/settings The images got loaded into that path. I inserted several System.out.println(int) to determine to which position everything works fine and the System.out.println after for(File f : files) { wasn't executed. (Sorry I'm still working on reading these Error-Codes if it's a JavaFX-Project)

And btw...can I still use SettingsController.class.getResource("/img/settings") if I want to make a jar?

And yes I know that return new Image("sample/img/settings/"+bild); is not the right path, but that's not the problem right know.

Here's the log:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
    at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
    at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$6(ContextMenuContent.java:1358)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
    ... 40 more
Caused by: javafx.fxml.LoadException: 
/Users/****/****/Proggen/Passwort-Manager19/target/classes/sample/SettingsView.fxml

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at sample.MainController.settings(MainController.java:222)
    ... 50 more
Caused by: java.lang.NullPointerException
    at sample.SettingsController.ladeBilder(SettingsController.java:65)
    at sample.SettingsController.initialize(SettingsController.java:30)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
    ... 53 more
ata1704
  • 13
  • 3

2 Answers2

2

Apparently, you changed:

ladeBilder(new File("/img/settings"));

to

ladeBilder(new File(String.valueOf(
                    (SettingsController.class.getResource("/img/settings")))));

and it stopped working. The problem is that getResource doesn't return a filename. It returns a URL You then use String.valueOf(Object) to turn the URL into a string, and then treat the string as a filename.

But it isn't a filename. It is a url string. It will look something like this:

    jar:file:/path/to/jar!/img/settings

So when you new File(urlString) on that url string, you will get a File object that refers to a non-existent file. And ultimately you get an NPE (apparently).

How to fix this?

What you are trying to do is to iterate the resources in a given tree in the resource path. Put simply, you can't do that using the file I/O libraries (File, Path, Files, etcetera) because the resource namespace is not a file system namespace.

You need to use an alternative method. There are a variety of ways to do it; see the following:


It worked before I add the Maven framework.

It isn't Maven's fault.

A better characterization would be to say that it worked when you were accessing the resources from the file system in your development environment. It broke because you included the resources in a JAR file and changed your code to access them from there.

This would have happened no matter what approach you used to create the JAR file.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

@StephenC: Thank you. That would be a good solution for the next time I really need this. But after some reflection-time I came to the conclusion that I just go for an easier way. Because I know all the files, I simply use the following method (with bildNummer set to 1 at start):

private void Bilder(){
        System.out.println("/img/settings/"+bildNummer+".jpg");
        InputStream inputStream = SettingsController.class.getResourceAsStream("img/settings/"+bildNummer+".jpg");
        imgView.setImage(new Image(inputStream));
        if(bildNummer==14){
            bildNummer=1;
        }else{
            bildNummer++;
        }
    }
ata1704
  • 13
  • 3