1

I have created two classes (and two interfaces) and then a main code. I just debugged the main code because I was getting an error that was preventing my code from working properly. I know that the problem in my Project03.java file is in line 29 and the line is input = userInput.nextLine(); . The error is: Exception in thread "main" java.util.NoSuchElementException: No line found at java.util.Scanner.nextLine(Scanner.java:1585) at Project03.main(Project03.java:29)

Why is the error coming up and how can I prevent it? Thank you! The codes are below: SimpleMusicTrack.java

import java.util.Scanner;
import java.lang.Object;
public class SimpleMusicTrack implements PlayListTrack {

private String name;
private String artist;
private String albumName;

// Convenience constructor for unit testing
public SimpleMusicTrack(String name, String artist, String album) {
    this.name = name;
    this.artist = artist;
    this.albumName = album;
}

public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

public String getArtist() {
    return this.artist;
}

public void setArtist(String artist) {
    this.artist = artist;
}

public String getAlbum() {
    return this.albumName;
}

public void setAlbum(String album) {
    this.albumName = album;
}

public boolean getNextTrack(Scanner infile) {
    if (infile == null)
        return false;
    while (infile.hasNext()) {
        this.setName(infile.nextLine());
        this.setArtist(infile.nextLine());
        this.setAlbum(infile.nextLine());
        return true;
    }
    return false;
}

public boolean equals(Object obj) {
    boolean songInfo;
    if (obj instanceof MusicTrack) {
        MusicTrack name1 = (MusicTrack) obj;
        if (this.name.equals(name1.getName())
                && this.artist.equals(name1.getArtist())
                && this.albumName.equals(name1.getArtist())) {
            songInfo = true;
        } else {
            songInfo = false;
        }
    } else {
        songInfo = false;
    }
    return songInfo;
}

public String toString() {
    String allSongInfo;
    allSongInfo = this.artist + " / " + this.name;
    return allSongInfo;
}
}

PlayListTrack.java

import java.util.Scanner;
public interface PlayListTrack {
public String getName();
public void setName(String name);
public String getArtist();
public void setArtist(String artist);
public String getAlbum();
public void setAlbum(String album);
public boolean getNextTrack(Scanner infile);

    // Attempts to read a play list track entry from a Scanner object
    // Sets the values in the object to the values given in
    // the file
    // If it successfully loads the track, return true
    // otherwise, return false
}

SimplePlayList.java

import java.util.*;
import java.util.Queue;

public class SimplePlayList implements PlayList {
Queue<PlayListTrack> queue;

public SimplePlayList(Scanner in) {
    queue = new LinkedList<PlayListTrack>();
    readFile(in);
}

public void readFile(Scanner in) {
    Scanner inScanner = new Scanner(System.in);
    Queue<PlayListTrack> queue = new LinkedList<PlayListTrack>();

    while (in.hasNext()) {

        queue.add(new SimpleMusicTrack(in.nextLine(), in.nextLine(), in
                .nextLine()));
    }
    inScanner.close();
}

public PlayListTrack getNextTrack() {
    while (!queue.isEmpty()) {
        queue.remove();
    }
    return queue.peek();
}

public PlayListTrack peekAtNextTrack() {
    while (!queue.isEmpty()) {
        queue.peek();
    }
    return queue.peek();
}

public void addTrack(PlayListTrack track) {
    while (!queue.isEmpty()) {
        queue.add(track);
    }
}

public boolean isEmpty() {
    while (!queue.isEmpty()) {
        return false;
    }
    return true;
}

}

PlayList.java

public interface PlayList {

public PlayListTrack getNextTrack();

// Removes track from PlayList and returns it to the caller
// Should return a null value if the PlayList is empty

public PlayListTrack peekAtNextTrack();

// Returns next entry to the caller, but leaves it in the list

public void addTrack(PlayListTrack track);

// Adds this track to the play list in the appropriate order

public boolean isEmpty();
// Returns true if the play list is empty

}

Project03.java

import java.io.File;
import java.io.*;
import java.util.Scanner;

public class Project03 {

public static void main(String[] args) {
    Scanner userInput = new Scanner(System.in);
    System.out.print("Enter database filename: ");
    String fileName = userInput.nextLine();
    try {
        File file = new File(fileName);
        Scanner musicList = new Scanner(file);
        String input = "P";
        PlayList playList = new SimplePlayList(musicList);
        while (!"Q".equalsIgnoreCase(input)) {
            if ("A".equalsIgnoreCase(input)) {
                displayAddTrackOption(userInput, playList);
                input = "";
            } else {
                displayNextSong(playList);
                System.out.print("> ");
                input = userInput.nextLine();
            }
        }

        displayRemainingTracks(playList);
    } catch (FileNotFoundException e) {
        System.out.println("Sorry, could not find your file");
    }
}

private static void displayRemainingTracks(PlayList playList) {
    System.out
            .println("Tracks remaining in play list------------------------------------------------------------");
    if (!playList.isEmpty()) {
        boolean hasAnotherTrack = true;
        int lineNumber = 1;
        while (hasAnotherTrack) {
            MusicTrack currentTrackToPlay = (MusicTrack) playList
                    .getNextTrack();
            if (currentTrackToPlay != null) {
                System.out.printf("%d - %s / %s / %s\n", lineNumber,
                        currentTrackToPlay.getName(),
                        currentTrackToPlay.getArtist(),
                        currentTrackToPlay.getAlbum());
                lineNumber++;
            } else
                hasAnotherTrack = false;
        }
    } else
        System.out.println("No tracks remaining");
}

private static void displayAddTrackOption(Scanner userInput,
        PlayList playList) {
    String title, artist, album, confirmation;
    System.out.print("Track name: ");
    title = userInput.nextLine();
    System.out.print("Artist name: ");
    artist = userInput.nextLine();
    System.out.print("Album name: ");
    album = userInput.nextLine();
    System.out.println("New Track: " + title);
    System.out.println("Artist: " + artist);
    System.out.println("Album: " + album);
    System.out.print("Are you sure you want to add this track [y/n]? ");
    confirmation = userInput.nextLine();
    if ("Y".equalsIgnoreCase(confirmation)) {
        playList.addTrack((PlayListTrack) new SimpleMusicTrack(title,
                artist, album));
    }
}

private static void displayNextSong(PlayList playList) {
    MusicTrack currentMusicTrackToPlay;
    MusicTrack nextMusicTrackToPlay;
    currentMusicTrackToPlay = (MusicTrack) playList.getNextTrack();
    nextMusicTrackToPlay = (MusicTrack) playList.peekAtNextTrack();
    if (currentMusicTrackToPlay != null) {
        System.out.println("Currently playing: "
                + currentMusicTrackToPlay.getName() + " / "
                + currentMusicTrackToPlay.getArtist());
    } else {
        System.out.println("Currently playing: No Song Playing");
    }
    if (nextMusicTrackToPlay != null) {
        System.out.println("Next track to play: "
                + nextMusicTrackToPlay.getName() + " / "
                + nextMusicTrackToPlay.getArtist());
    } else {
        System.out.println("Play list is empty, no more tracks");
    }
    System.out.println("[P]lay next track");
    System.out.println("[A]dd a new track");
    System.out.println("[Q]uit");
}
}
Jonny Henly
  • 4,023
  • 4
  • 26
  • 43
mryan
  • 33
  • 5

1 Answers1

0

You're using two Scanner's on the same stream (System.in). The first being userInput in the main method of your Project03 class. The second being inScanner in the readFile method of your SimplePlayList class:

public void readFile(Scanner in) {
    Scanner inScanner = new Scanner(System.in); // <-- remove this line
    Queue<PlayListTrack> queue = new LinkedList<PlayListTrack>();

    while (in.hasNext()) {

        queue.add(new SimpleMusicTrack(in.nextLine(), in.nextLine(), in
                .nextLine()));
    }
    inScanner.close(); // <--- remove this line
}

Using multiple scanners on the same stream is the underlying problem. Scanners can (and will) consume the stream - this may (will) lead to unexpected side-effects. Best not to do it.

If the input is closed, then the input [...] is closed for everyone - and that's not much fun for anyone.

"Details" on why multiple scanners are bad: Do not create multiple buffered wrappers on an InputStream

- from user166390's answer on How to use multiple Scanner objects on System.in?

Community
  • 1
  • 1
Jonny Henly
  • 4,023
  • 4
  • 26
  • 43