Search code examples
javajava.util.scannernosuchelementexception

Java NoSuchElementException using Scanner on empty Lines


I got a program with a lot of JTextAreas, that get filled by the user. I'm saving those comments with a BufferedWriter in a .txt File separated by a semicolon.

I'm trying to read the contents of that .txt-File back into the program, which is where the problems start. I'm using a Scanner to read the File, which works perfectly for the first few TextAreas. However on another set of JTextAreas it fails if there are just spaces or nothing in the savefile. I don't understand why it works fine just a few lines before.

openItem.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
        JFileChooser oi = new JFileChooser();
        oi.showOpenDialog(null);
        Scanner scan = null;
        try{
        scan = new Scanner(oi.getSelectedFile());
        scan.useDelimiter(Pattern.compile(";"));
        String[] input = new String[144];
        for (int i = 1; i<9;i++){   //This works fine, even with empty JTextAreas
                input[i] = scan.next();
            }
            f1.setText(input[1]);
            f2.setText(input[2]);
            f3.setText(input[3]);
            f4.setText(input[4]);
            f5.setText(input[5]);
            f6.setText(input[6]);
            f7.setText(input[7]);
            f8.setText(input[8]);
        for(int i=1;i<13;i++){ //This throws a NoSuchElementException if it's reading a savefile with empty TextAreas
                input[i] = scan.next();
            }
            c1.setText(input[1]);
            c2.setText(input[2]);
            c3.setText(input[3]);
            c4.setText(input[4]);
            ....
            }catch(IOException | NoSuchElementException i){
                JOptionPane.showMessageDialog(null, "Error while reading", "Error",1);
            }}});

Now the second for-Loop does work perfectly if the savefile contains a value for every JTextArea, but fails if there is just whitespace for one of the elements. What am I doing wrong here?


Solution

  • It seems if the input string does not have the exact amount of inputs you will be calling scan.next() but there won't be any element to return so as you can see from the documentation it throws a NoSuchElementException.

    public String next()

    Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.

    Throws: NoSuchElementException - if no more tokens are available IllegalStateException - if this scanner is closed

    To fix this add a check to see if there is a token otherwise add empty string if there is no token. You can do this with a ternary operator like this

      for(int i=1;i<13;i++){ //This throws a NoSuchElementException if it's reading a savefile with empty TextAreas
             input[i] = (scan.hasNext())? scan.next(): "";
                }
                c1.setText(input[1]);
                c2.setText(input[2]);
                c3.setText(input[3]);
                c4.setText(input[4]);