When I run the following code:
class Startup
(called by main()
):
import java.util.ArrayList;
public class Startup {
public void start() {
// Build rooms
final int WIDTH = 2;
final int HEIGHT = 2;
Room[][] room = new Room[WIDTH][HEIGHT];
Rooms.build(room, WIDTH, HEIGHT);
int x = 0;
int y = 0;
// Print starting room description
Rooms.print(room, x, y);
// Start game loop
boolean playing = true;
while (playing) {
// Get user input
String input = Input.getInput();
System.out.println(input);
// Movement commands
if (input.equals("n")) {
if (y > 0) {
y--;
Rooms.print(room, x, y);
} else {
System.out.println("You can't go that way.");
}
}
}
}
}
class Input
:
import java.util.Scanner;
public class Input {
public static String getInput() {
System.out.print("> ");
try(Scanner in = new Scanner(System.in)) {
String input = in.nextLine();
input.toLowerCase();
return input;
}
}
}
I will always get this NoSuchElementException
:
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at Input.getInput(Input.java:11)
at Startup.start(Startup.java:36)
at Driver.main(Driver.java:11)
If the movement commands part in start()
is removed, everything works fine. But when that part is included, that exception is always called, leading me to think that there's something wrong to it. But my question is: what's wrong?
You are creating a new Scanner every time you call
getInput
. Unfortunately, you are closing it every time:This construct is called "Try with resources". It creates the
Scanner
, which is aCloseable
object, and at the end of thetry
block, it closes it.This means that the input stream behind the scanner is also closed.
Once you closed a stream, it cannot be re-opened. Every request for input from that stream will return the "end of file" condition. Thus, each time you open a new scanner after the first one, on the same (closed)
System.in
, you'll get an empty scanner which is at the "end of file".What you need to do is open the Scanner only once. And then for the rest of the program, read from the same open scanner. To do this, you either have to have all the program inside the try-with-resources, or simply not use try-with-resources at all.