Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I have the code for two seperate programs (SongEntry.java and Playlist.java) tha

ID: 3572599 • Letter: I

Question

I have the code for two seperate programs (SongEntry.java and Playlist.java) that work together to recreate the expected output and would appreciate any help altering the code to meet the requirements.

1. Unit Test: Tests that setNext() correctly sets "Canned Heat" to be "All For You"'s next node

2. Compare Output

Input: Jamz

         q

Your Output: Exception in thread "main" java.lang.NoClassDef

Expected Output: Enter playlist's title:

3. Compare Output

Input: JAMZ

         a

         SD123

         Peg

         Steely Dan

         237

         a

         JJ234

         All For You

         Janet Jackson

         391

         a

         J345

         Canned Heat

         Jamiroquai

         330

         a

         JJ456

         Black Eagle

         Janet Jackson

         197

         a

        SD567

         I Got The News

        Steely Dan

         306

         c

         3

         2

         o

         q

Your Output: a.security.AccessController.doPrivileged(Native Method)

                                 at java.net.URLClassLoader.findClass(URLClassLoader.java:354)

                                 at java.lang.ClassLoader.loadClass(ClassLoader.java:425)

                                 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

                                 at java.lang.ClassLoader.loadClass(ClassLoader.java:358)

                                 at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)

Expected Output: JAMZ - OUTPUT FULL PLAYLIST

                           1.

                           Unique ID: SD123

                           Song Name: Peg

                           Artist Name: Steely Dan

                           Song Length (in seconds): 237

                           2.

                          Unique ID: J345

                          Song Name: Canned Heat

                          Artist Name: Jamiroquai

                          Song Length (in seconds): 330

                           3.

                          Unique ID: JJ234

                          Song Name: All For You

                          Artist Name: Janet Jackson

                          Song Length (in seconds): 391

                           4.

                          Unique ID: JJ456

                          Song Name: Black Eagle

                          Artist Name: Janet Jackson

                          Song Length (in seconds): 197

                           5.

                           Unique ID: SD567

                           Song Name: I Got The News

                           Artist Name: Steely Dan

                           Song Length (in seconds): 306

                           JAMZ PLAYLIST MENU

                           a - Add song

                           d - Remove song

                           c - Change position of song

                           s - Output songs by specific artist

                           t - Output total time of playlist (in seconds)

                           o - Output full playlist

   q - Quit Choose an option:

                           Choose an option:

SongEntry.java

package playlist;

public class SongEntry {

   private String uniqueID;
   private String songName;
   private String artistName;
   private int songLength;
   SongEntry nextNode;

   SongEntry()
   {
       uniqueID = "";
       songName = "";
       artistName = "";
       songLength = 0;
       nextNode = null;
   }

   SongEntry(String uniqueID, String songName, String artistName, int songLength)
   {
       this.uniqueID = uniqueID;
       this.songName = songName;
       this.songLength = songLength;
       this.artistName = artistName;
       this.nextNode = null;
   }

   public void insertAfter( SongEntry entry)
   {
       SongEntry entries = this;
       while(entries.nextNode != null)
       {
           entries = entries.nextNode;
       }
       entries.nextNode = entry;
   }

   public void setNext(SongEntry entry){
       this.nextNode = entry;
   }

   public String getID()
   {
       return this.uniqueID;
   }

   public String getSongName()
   {
       return this.songName;
   }

   public String getArtistName()
   {
       return this.artistName;
   }

   public int getSongLength()
   {
       return this.songLength;
   }

   public SongEntry getNext()
   {
       return this.nextNode;
   }

   public void printPlaylistSongs()
   {
       System.out.println("Unique ID: "+getID());
       System.out.println("Song Name: "+getSongName());
       System.out.println("Artist Name: "+getArtistName());
       System.out.println("Song Length(in seconds): "+getSongLength());
   }
}

Playlist.java

package playlist;

import java.util.Scanner;
public class Playlist {

public static Scanner sc = new Scanner(System.in);
public static Scanner scInt = new Scanner(System.in);
public static SongEntry headSong = new SongEntry();
public static SongEntry tailSong = new SongEntry();
public static SongEntry allEntries;
public static int numberOfNodes = 0;

public static void printMenu(String playlistTitle)
{
System.out.println(" "+playlistTitle.toUpperCase()+" PLAYLIST MENU");
System.out.println("a - Add song d - Remove song c - Change position of song s - Output songs by specific artist");
System.out.println("t - Output total time of playlist (in seconds) o - Output full playlist q - Quit");
System.out.println(" Choose an option: ");
String option = sc.next();
boolean isEnter = option.equals("a") || option.equals("d") || option.equals("c") || option.equals("s") || option.equals("t") || option.equals("o") || option.equals("q");
if(isEnter)
{
switch(option.charAt(0))
{
case 'a': addSong();
printMenu(playlistTitle);
break;

case 'd': allEntries = removeSong(allEntries);
printMenu(playlistTitle);
break;

case 'c': allEntries = changeSongPosition(allEntries);
printMenu(playlistTitle);
break;

case 's': songsBySpecificArtist(allEntries);
printMenu(playlistTitle);
break;

case 't': totalTimeofPlaylist(allEntries);
printMenu(playlistTitle);
break;

case 'o': outputFullPlaylist(allEntries);
printMenu(playlistTitle);
break;

case 'q': break;

}
}
else
{
System.out.println("Invalid Choice !");
printMenu(playlistTitle);
}
}

public static void outputFullPlaylist(SongEntry entries)
{
int counter = 1;
if(entries != null)
{
System.out.println(counter+".");
entries.printPlaylistSongs(); // head node
counter++;
while(entries.nextNode != null) // all the remaining nodes
{
entries = entries.nextNode;
System.out.println(counter+".");
entries.printPlaylistSongs();
counter++;
}
}
else
{
System.out.println("Playlist is empty");
}
}

public static void addSong()
{
sc = new Scanner(System.in);
System.out.println("ADD SONG");
System.out.println("Enter song's Unique ID: ");
String songID = sc.next();
sc = new Scanner(System.in);
System.out.println("Enter song's name: ");
String songname = sc.nextLine();
sc = new Scanner(System.in);
System.out.println("Enter artist's name: ");
String artistName = sc.nextLine();
System.out.println("Enter song's length(in seconds): ");
int songlength = scInt.nextInt();

SongEntry entry = new SongEntry(songID, songname, artistName, songlength);
if(allEntries == null)
{
headSong = entry; // this is the head
allEntries = entry;
tailSong = entry; // this is the tail
numberOfNodes++;
}
else
{
allEntries.insertAfter(entry);
tailSong = entry;
numberOfNodes++;
}
}

public static SongEntry removeSong(SongEntry entries)
{
System.out.println("Enter the song's unique ID: ");
String id = sc.next();
SongEntry newEntry = null, entry=null;
int counter = 0;
while(entries != null)
{
if(counter!=0)
{
newEntry.nextNode = null;
newEntry = newEntry.nextNode;
}

if(!entries.getID().equals(id))
{
newEntry = new SongEntry(entries.getID(),entries.getSongName(),entries.getArtistName(),entries.getSongLength());
if(entry == null)
entry = newEntry;
else
entry.insertAfter(newEntry);
counter++;
}
else
{
System.out.println(entries.getSongName()+" removed");
numberOfNodes--;
}
entries = entries.nextNode;
}
return entry;
}

public static SongEntry changeSongPosition(SongEntry entries)
{

System.out.println("CHANGE POSITION OF SONG");
System.out.println("ENTER song's current position: ");
int currentPos = scInt.nextInt();
System.out.println("Enter new position of song: ");
int newPos = scInt.nextInt();
SongEntry currentPosEntry = null, entry = null, newPosEntry = null, returnEntry = null;
entry = entries;
int counter = 1;
// System.out.println("Number of nodes: " + numberOfNodes);
if(newPos<1)
newPos = 1;
else if(newPos>numberOfNodes)
newPos = numberOfNodes;
System.out.println("cuurent pos: "+currentPos);
System.out.println("new pos: "+newPos);
for(int i=1; i<=numberOfNodes; i++)
{
if(i==currentPos)
currentPosEntry = entries;
else if(i==newPos)
newPosEntry = entries;
else
entries = entries.nextNode;
}
// System.out.println("After for loop");
//System.out.println("Current song details" ); currentPosEntry.printPlaylistSongs();
// System.out.println("New song details"); newPosEntry.printPlaylistSongs();
entries = entry;
while(counter <= numberOfNodes+1)
{
if(counter == currentPos) // we need to adjust the current position
{

entries = entries.nextNode;
if(entries !=null)
{
entry = new SongEntry(entries.getID(), entries.getSongName(), entries.getArtistName(), entries.getSongLength());
if(returnEntry == null)
returnEntry = entry;
else
returnEntry.insertAfter(entry);
entries = entries.nextNode;
}
counter++;
}
else if(counter == newPos)
{

entry = currentPosEntry;
entry.nextNode = null;
if(returnEntry == null)
returnEntry = entry;
else
returnEntry.insertAfter(entry);
counter++;
}
else
{

if(entries !=null)
{
entry = new SongEntry(entries.getID(), entries.getSongName(), entries.getArtistName(), entries.getSongLength());
if(returnEntry == null)
returnEntry = entry;
else
returnEntry.insertAfter(entry);
entries = entries.nextNode;
}
counter++;
}
}
return returnEntry;
}

public static void totalTimeofPlaylist(SongEntry entries)
{
System.out.println("OUTPUT TOTAL TIME OF PLAYLIST (IN SECONDS)");
int totalSeconds = entries.getSongLength();
entries = entries.nextNode;
while(entries != null)
{
totalSeconds += entries.getSongLength();
entries = entries.nextNode;

}
System.out.println("Total Time: "+totalSeconds+" seconds");
}

public static void songsBySpecificArtist(SongEntry entries)
{
sc = new Scanner(System.in);
System.out.println("OUTPUT SONGS BY SPECIFIC ARTIST");
System.out.println("Enter artist's name: ");
String artistname = sc.nextLine();
while(entries != null)
{
if(entries.getArtistName().equals(artistname))
{
entries.printPlaylistSongs();
}
entries = entries.nextNode;
}
}
/**
* @param args
*/
public static void main(String[] args) {

System.out.println("Enter playlist's title: ");
sc = new Scanner(System.in);
String title = sc.nextLine();
printMenu(title);
}
}

Explanation / Answer

import javafx.application.*;

import javafx.beans.value.*;

import javafx.collections.*;

import javafx.event.*;

import javafx.geometry.Pos;

import javafx.scene.Scene;

import javafx.scene.control.*;

import javafx.scene.control.cell.MapValueFactory;

import javafx.scene.image.*;

import javafx.scene.layout.*;

import javafx.scene.media.*;

import javafx.stage.Stage;

import javafx.util.Callback;

import javafx.util.Duration;

import java.io.File;

import java.io.FilenameFilter;

import java.util.*;

public class AudioPlaylist extends Application {

private static final String MUSIC_DIR = "/Users/lilyshard/Music";

public static final String TAG_COLUMN_NAME = "Tag";

public static final String VALUE_COLUMN_NAME = "Value";

public static final List<String> SUPPORTED_FILE_EXTENSIONS = Arrays.asList(".mp3", ".m4a");

public static final int FILE_EXTENSION_LEN = 3;

final Label currentlyPlaying = new Label();

final ProgressBar progress = new ProgressBar();

final TableView<Map> metadataTable = new TableView<>();

private ChangeListener<Duration> progressChangeListener;

private MapChangeListener<String, Object> metadataChangeListener;

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

public void start(final Stage stage) throws Exception {

    stage.setTitle("Simple Audio Player");

    final List<String> params = getParameters().getRaw();

    final File dir = (params.size() > 0)

      ? new File(params.get(0))

      : new File(MUSIC_DIR);

    if (!dir.exists() || !dir.isDirectory()) {

      System.out.println("Cannot find audio source directory: " + dir + " please supply a directory as a command line argument");

      Platform.exit();

      return;

    }

    final List<MediaPlayer> players = new ArrayList<>();

    for (String file : dir.list(new FilenameFilter() {

      @Override public boolean accept(File dir, String name) {

        for (String ext: SUPPORTED_FILE_EXTENSIONS) {

          if (name.endsWith(ext)) {

            return true;

          }

        }

        return false;

      }

    })) players.add(createPlayer("file:///" + (dir + "\" + file).replace("\", "/").replaceAll(" ", "%20")));

    if (players.isEmpty()) {

    System.out.println("No audio found in " + dir);

      Platform.exit();

      return;

    }   

   

    final MediaView mediaView = new MediaView(players.get(0));

    final Button skip = new Button("Skip");

    final Button play = new Button("Pause");

    for (int i = 0; i < players.size(); i++) {

      final MediaPlayer player     = players.get(i);

      final MediaPlayer nextPlayer = players.get((i + 1) % players.size());

      player.setOnEndOfMedia(new Runnable() {

        @Override public void run() {

          player.currentTimeProperty().removeListener(progressChangeListener);

          player.getMedia().getMetadata().removeListener(metadataChangeListener);

          player.stop();

          mediaView.setMediaPlayer(nextPlayer);

          nextPlayer.play();

        }

      });

    }

   

    skip.setOnAction(new EventHandler<ActionEvent>() {

      @Override public void handle(ActionEvent actionEvent) {

        final MediaPlayer curPlayer = mediaView.getMediaPlayer();

        curPlayer.currentTimeProperty().removeListener(progressChangeListener);

        curPlayer.getMedia().getMetadata().removeListener(metadataChangeListener);

        curPlayer.stop();

        MediaPlayer nextPlayer = players.get((players.indexOf(curPlayer) + 1) % players.size());

        mediaView.setMediaPlayer(nextPlayer);

        nextPlayer.play();

      }

    });

    play.setOnAction(new EventHandler<ActionEvent>() {

      @Override public void handle(ActionEvent actionEvent) {

        if ("Pause".equals(play.getText())) {

          mediaView.getMediaPlayer().pause();

          play.setText("Play");

        } else {

          mediaView.getMediaPlayer().play();

          play.setText("Pause");

        }

      }

    });

    mediaView.mediaPlayerProperty().addListener(new ChangeListener<MediaPlayer>() {

      @Override public void changed(ObservableValue<? extends MediaPlayer> observableValue, MediaPlayer oldPlayer, MediaPlayer newPlayer) {

        setCurrentlyPlaying(newPlayer);

      }

    });

   

    mediaView.setMediaPlayer(players.get(0));

    mediaView.getMediaPlayer().play();

    setCurrentlyPlaying(mediaView.getMediaPlayer());

    Button invisiblePause = new Button("Pause");

    invisiblePause.setVisible(false);

    play.prefHeightProperty().bind(invisiblePause.heightProperty());

    play.prefWidthProperty().bind(invisiblePause.widthProperty());

    metadataTable.setStyle("-fx-font-size: 13px;");

    TableColumn<Map, String> tagColumn = new TableColumn<>(TAG_COLUMN_NAME);

    tagColumn.setPrefWidth(150);

    TableColumn<Map, Object> valueColumn = new TableColumn<>(VALUE_COLUMN_NAME);

    valueColumn.setPrefWidth(400);

    tagColumn.setCellValueFactory(new MapValueFactory<>(TAG_COLUMN_NAME));

    valueColumn.setCellValueFactory(new MapValueFactory<>(VALUE_COLUMN_NAME));

    metadataTable.setEditable(true);

    metadataTable.getSelectionModel().setCellSelectionEnabled(true);

    metadataTable.getColumns().setAll(tagColumn, valueColumn);

    valueColumn.setCellFactory(new Callback<TableColumn<Map, Object>, TableCell<Map, Object>>() {

      @Override

      public TableCell<Map, Object> call(TableColumn<Map, Object> column) {

        return new TableCell<Map, Object>() {

          @Override

          protected void updateItem(Object item, boolean empty) {

            super.updateItem(item, empty);

            if (item != null) {

              if (item instanceof String) {

                setText((String) item);

                setGraphic(null);

              } else if (item instanceof Integer) {

                setText(Integer.toString((Integer) item));

                setGraphic(null);

              } else if (item instanceof Image) {

                setText(null);

                ImageView imageView = new ImageView((Image) item);

                imageView.setFitWidth(200);

              imageView.setPreserveRatio(true);

                setGraphic(imageView);

              } else {

                setText("N/A");

                setGraphic(null);

              }

            } else {

              setText(null);

              setGraphic(null);

            }

          }

        };

      }

    });

    final StackPane layout = new StackPane();

    layout.setStyle("-fx-background-color: cornsilk; -fx-font-size: 20; -fx-padding: 20; -fx-alignment: center;");

    final HBox progressReport = new HBox(10);

    progressReport.setAlignment(Pos.CENTER);

    progressReport.getChildren().setAll(skip, play, progress, mediaView);

    final VBox content = new VBox(10);

    content.getChildren().setAll(

        currentlyPlaying,

        progressReport,

        metadataTable

    );

    layout.getChildren().addAll(

      invisiblePause,

      content

    );

    progress.setMaxWidth(Double.MAX_VALUE);

    HBox.setHgrow(progress, Priority.ALWAYS);

    VBox.setVgrow(metadataTable, Priority.ALWAYS);

    Scene scene = new Scene(layout, 600, 400);

    stage.setScene(scene);

    stage.show();

}

private void setCurrentlyPlaying(final MediaPlayer newPlayer) {

    newPlayer.seek(Duration.ZERO);

    progress.setProgress(0);

    progressChangeListener = new ChangeListener<Duration>() {

      @Override public void changed(ObservableValue<? extends Duration> observableValue, Duration oldValue, Duration newValue) {

        progress.setProgress(1.0 * newPlayer.getCurrentTime().toMillis() / newPlayer.getTotalDuration().toMillis());

      }

    };

    newPlayer.currentTimeProperty().addListener(progressChangeListener);

    String source = newPlayer.getMedia().getSource();

    source = source.substring(0, source.length() - FILE_EXTENSION_LEN);

    source = source.substring(source.lastIndexOf("/") + 1).replaceAll("%20", " ");

    currentlyPlaying.setText("Now Playing: " + source);

    setMetaDataDisplay(newPlayer.getMedia().getMetadata());

}

private void setMetaDataDisplay(ObservableMap<String, Object> metadata) {

    metadataTable.getItems().setAll(convertMetadataToTableData(metadata));

    metadataChangeListener = new MapChangeListener<String, Object>() {

      @Override

      public void onChanged(Change<? extends String, ?> change) {

        metadataTable.getItems().setAll(convertMetadataToTableData(metadata));

      }

    };

    metadata.addListener(metadataChangeListener);

}

private ObservableList<Map> convertMetadataToTableData(ObservableMap<String, Object> metadata) {

    ObservableList<Map> allData = FXCollections.observableArrayList();

    for (String key: metadata.keySet()) {

      Map<String, Object> dataRow = new HashMap<>();

      dataRow.put(TAG_COLUMN_NAME,   key);

      dataRow.put(VALUE_COLUMN_NAME, metadata.get(key));

      allData.add(dataRow);

    }

    return allData;

}

private MediaPlayer createPlayer(String mediaSource) {

    final Media media = new Media(mediaSource);

    final MediaPlayer player = new MediaPlayer(media);

    player.setOnError(new Runnable() {

      @Override public void run() {

        System.out.println("Media error occurred: " + player.getError());

      }

    });

    return player;

}

}