Issue
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.
Solution
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;
Answered By - Ádám Maul