Alex
Alex

Reputation: 55

java closing scanner causes exceptions?

i'm making a program that converts instructions from a text file into a drawing. the file contains commands and arguments, like "CIRCLE 100 200 15". once the scanner hits a line that says "END" i need to close the scanner, stop reading the file, and stop drawing. but when i use 'obj.close()' in the END switch case, i get InvocationTargetException, RuntimeException, and IllegalStateException. i've tried to look up solutions but i can't find any that work in my case. i've tried making the scanner static, which causes an error saying "modifier static not allowed here", making it into a try statement, moving it outside the try statement, and nothing works. here's the code:

public class Graphic extends Application {
    /**
     * The start method. Required by Application
     *
     * @param stage
     */
    public void start(Stage stage) {
        double fwidth = 0;
        double fheight = 0;
        ...

        Group root = new Group();  //creates group for all shapes to go in
        try {
            Scanner obj = new Scanner(new File("star.txt"));  //reads text file
            while(obj.hasNextLine()){
                String[] strArray = obj.nextLine().split(" ");  //splits all commands to new line
                switch(strArray[0]){
                    case "SIZE":                                      //sets size of window
                        ...
                    case "LINE":                                      //creates each line
                        ...
                    case "CIRCLE":                                    //creates each circle
                        ...
                    case "RECTANGLE":                                 //creates each rectangle
                        ...
                    case "TEXT":                                      //creates each string of text
                        ...
                    case "//":                                        //ignores comments
                        ...
                    case "END":                                       //stops reading file
                        obj.close();
                        break;
                }
            }

            Scene scene = new Scene(root, fwidth, fheight, Color.BLACK);
            stage.setTitle("poop");
            stage.setScene(scene);
            stage.show();
        }
        catch (FileNotFoundException fileNotFoundException) {
            fileNotFoundException.printStackTrace();
        }
        }

        /**
         * The main method
         * @param args
         */

        public static void main(String[] args) {
            launch(args);
        }
    }

here is the error:

Exception in Application start method
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 com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    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.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$1(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: Scanner closed
    at java.util.Scanner.ensureOpen(Scanner.java:1070)
    at java.util.Scanner.findWithinHorizon(Scanner.java:1670)
    at java.util.Scanner.hasNextLine(Scanner.java:1500)
    at sample.Graphic.start(Graphic.java:69)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
    ... 1 more
Exception running application sample.Graphic

Process finished with exit code 1

idk if it's a simple fix and i'm just missing it or what but if anyone can help it would be much appreciated.

Upvotes: 0

Views: 158

Answers (1)

Flashcap
Flashcap

Reputation: 141

Place your loop inside a try-with-resources block, then it will close the scanner by itself, since Scanner implements Closeable.

try (Scanner obj = new Scanner(new File("star.txt"))) {
    //Place your whole while loop here
}

You break out of the switch/case, so you should create a boolean inside the try, right above your loop, then set it to true on "END". Then check the variable's value in your loop and if it's true, then break out of the loop like so:

Above the while loop:

boolean shouldBreak = false;

End case:

case "END":
    shouldBreak = true;
    break;

Then at the end of your loop (inside)

if(shouldBreak) break;

Upvotes: 3

Related Questions