first commit

This commit is contained in:
Boris
2024-01-15 20:14:10 +00:00
commit 8c81ee28b7
3106 changed files with 474415 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
#BlueJ class context
comment0.params=
comment0.target=MusicOrganizer()
comment0.text=\n\ Create\ a\ MusicOrganizer\n
comment1.params=filename
comment1.target=void\ addFile(java.lang.String)
comment1.text=\n\ Add\ a\ track\ file\ to\ the\ collection.\n\ @param\ filename\ The\ file\ name\ of\ the\ track\ to\ be\ added.\n
comment10.params=
comment10.target=void\ stopPlaying()
comment10.text=\n\ Stop\ the\ player.\n
comment11.params=index
comment11.target=boolean\ indexValid(int)
comment11.text=\n\ Determine\ whether\ the\ given\ index\ is\ valid\ for\ the\ collection.\n\ Print\ an\ error\ message\ if\ it\ is\ not.\n\ @param\ index\ The\ index\ to\ be\ checked.\n\ @return\ true\ if\ the\ index\ is\ valid,\ false\ otherwise.\n
comment12.params=folderName
comment12.target=void\ readLibrary(java.lang.String)
comment2.params=track
comment2.target=void\ addTrack(Track)
comment2.text=\n\ Add\ a\ track\ to\ the\ collection.\n\ @param\ track\ The\ track\ to\ be\ added.\n
comment3.params=index
comment3.target=void\ playTrack(int)
comment3.text=\n\ Play\ a\ track\ in\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ track\ to\ be\ played.\n
comment4.params=
comment4.target=int\ getNumberOfTracks()
comment4.text=\n\ Return\ the\ number\ of\ tracks\ in\ the\ collection.\n\ @return\ The\ number\ of\ tracks\ in\ the\ collection.\n
comment5.params=index
comment5.target=void\ listTrack(int)
comment5.text=\n\ List\ a\ track\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ track\ to\ be\ listed.\n
comment6.params=
comment6.target=void\ listAllTracks()
comment6.text=\n\ Show\ a\ list\ of\ all\ the\ tracks\ in\ the\ collection.\n
comment7.params=artist
comment7.target=void\ listByArtist(java.lang.String)
comment7.text=\n\ List\ all\ tracks\ by\ the\ given\ artist.\n\ @param\ artist\ The\ artist's\ name.\n
comment8.params=index
comment8.target=void\ removeTrack(int)
comment8.text=\n\ Remove\ a\ track\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ track\ to\ be\ removed.\n
comment9.params=
comment9.target=void\ playFirst()
comment9.text=\n\ Play\ the\ first\ track\ in\ the\ collection,\ if\ there\ is\ one.\n
numComments=13

View File

@@ -0,0 +1,173 @@
import java.util.ArrayList;
/**
* A class to hold details of audio tracks.
* Individual tracks may be played.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class MusicOrganizer
{
// An ArrayList for storing music tracks.
private ArrayList<Track> tracks;
// A player for the music tracks.
private MusicPlayer player;
// A reader that can read music files and load them as tracks.
private TrackReader reader;
/**
* Create a MusicOrganizer
*/
public MusicOrganizer()
{
tracks = new ArrayList<>();
player = new MusicPlayer();
reader = new TrackReader();
readLibrary("../audio");
System.out.println("Music library loaded. " + getNumberOfTracks() + " tracks.");
System.out.println();
}
/**
* Add a track file to the collection.
* @param filename The file name of the track to be added.
*/
public void addFile(String filename)
{
tracks.add(new Track(filename));
}
/**
* Add a track to the collection.
* @param track The track to be added.
*/
public void addTrack(Track track)
{
tracks.add(track);
}
/**
* Play a track in the collection.
* @param index The index of the track to be played.
*/
public void playTrack(int index)
{
if(indexValid(index)) {
Track track = tracks.get(index);
player.startPlaying(track.getFilename());
System.out.println("Now playing: " + track.getArtist() + " - " + track.getTitle());
}
}
/**
* Return the number of tracks in the collection.
* @return The number of tracks in the collection.
*/
public int getNumberOfTracks()
{
return tracks.size();
}
/**
* List a track from the collection.
* @param index The index of the track to be listed.
*/
public void listTrack(int index)
{
System.out.print("Track " + index + ": ");
Track track = tracks.get(index);
System.out.println(track.getDetails());
}
/**
* Show a list of all the tracks in the collection.
*/
public void listAllTracks()
{
System.out.println("Track listing: ");
for(Track track : tracks) {
System.out.println(track.getDetails());
}
System.out.println();
}
/**
* List all tracks by the given artist.
* @param artist The artist's name.
*/
public void listByArtist(String artist)
{
for(Track track : tracks) {
if(track.getArtist().contains(artist)) {
System.out.println(track.getDetails());
}
}
}
/**
* Remove a track from the collection.
* @param index The index of the track to be removed.
*/
public void removeTrack(int index)
{
if(indexValid(index)) {
tracks.remove(index);
}
}
/**
* Play the first track in the collection, if there is one.
*/
public void playFirst()
{
if(tracks.size() > 0) {
player.startPlaying(tracks.get(0).getFilename());
}
}
/**
* Stop the player.
*/
public void stopPlaying()
{
player.stop();
}
/**
* Determine whether the given index is valid for the collection.
* Print an error message if it is not.
* @param index The index to be checked.
* @return true if the index is valid, false otherwise.
*/
private boolean indexValid(int index)
{
// The return value.
// Set according to whether the index is valid or not.
boolean valid;
if(index < 0) {
System.out.println("Index cannot be negative: " + index);
valid = false;
}
else if(index >= tracks.size()) {
System.out.println("Index is too large: " + index);
valid = false;
}
else {
valid = true;
}
return valid;
}
private void readLibrary(String folderName)
{
ArrayList<Track> tempTracks = reader.readTracks(folderName, ".mp3");
// Put all thetracks into the organizer.
for(Track track : tempTracks) {
addTrack(track);
}
}
}

View File

@@ -0,0 +1,30 @@
#BlueJ class context
comment0.params=
comment0.target=MusicPlayer()
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ MusicFilePlayer\n
comment1.params=filename
comment1.target=void\ playSample(java.lang.String)
comment1.text=\n\ Play\ a\ part\ of\ the\ given\ file.\n\ The\ method\ returns\ once\ it\ has\ finished\ playing.\n\ @param\ filename\ The\ file\ to\ be\ played.\n
comment2.params=filename
comment2.target=void\ startPlaying(java.lang.String)
comment2.text=\n\ Start\ playing\ the\ given\ audio\ file.\n\ The\ method\ returns\ once\ the\ playing\ has\ been\ started.\n\ @param\ filename\ The\ file\ to\ be\ played.\n
comment3.params=
comment3.target=void\ run()
comment4.params=
comment4.target=void\ stop()
comment5.params=filename
comment5.target=void\ setupPlayer(java.lang.String)
comment5.text=\n\ Set\ up\ the\ player\ ready\ to\ play\ the\ given\ file.\n\ @param\ filename\ The\ name\ of\ the\ file\ to\ play.\n
comment6.params=filename
comment6.target=java.io.InputStream\ getInputStream(java.lang.String)
comment6.text=\n\ Return\ an\ InputStream\ for\ the\ given\ file.\n\ @param\ filename\ The\ file\ to\ be\ opened.\n\ @throws\ IOException\ If\ the\ file\ cannot\ be\ opened.\n\ @return\ An\ input\ stream\ for\ the\ file.\n
comment7.params=
comment7.target=javazoom.jl.player.AudioDevice\ createAudioDevice()
comment7.text=\n\ Create\ an\ audio\ device.\n\ @throws\ JavaLayerException\ if\ the\ device\ cannot\ be\ created.\n\ @return\ An\ audio\ device.\n
comment8.params=
comment8.target=void\ killPlayer()
comment8.text=\n\ Terminate\ the\ player,\ if\ there\ is\ one.\n
comment9.params=filename
comment9.target=void\ reportProblem(java.lang.String)
comment9.text=\n\ Report\ a\ problem\ playing\ the\ given\ file.\n\ @param\ filename\ The\ file\ being\ played.\n
numComments=10

View File

@@ -0,0 +1,150 @@
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;
import javazoom.jl.player.advanced.AdvancedPlayer;
/**
* Provide basic playing of MP3 files via the javazoom library.
* See http://www.javazoom.net/
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class MusicPlayer
{
// The current player. It might be null.
private AdvancedPlayer player;
/**
* Constructor for objects of class MusicFilePlayer
*/
public MusicPlayer()
{
player = null;
}
/**
* Play a part of the given file.
* The method returns once it has finished playing.
* @param filename The file to be played.
*/
public void playSample(String filename)
{
try {
setupPlayer(filename);
player.play(500);
}
catch(JavaLayerException e) {
reportProblem(filename);
}
finally {
killPlayer();
}
}
/**
* Start playing the given audio file.
* The method returns once the playing has been started.
* @param filename The file to be played.
*/
public void startPlaying(final String filename)
{
try {
setupPlayer(filename);
Thread playerThread = new Thread() {
public void run()
{
try {
player.play(5000);
}
catch(JavaLayerException e) {
reportProblem(filename);
}
finally {
killPlayer();
}
}
};
playerThread.start();
}
catch (Exception ex) {
reportProblem(filename);
}
}
public void stop()
{
killPlayer();
}
/**
* Set up the player ready to play the given file.
* @param filename The name of the file to play.
*/
private void setupPlayer(String filename)
{
try {
InputStream is = getInputStream(filename);
player = new AdvancedPlayer(is, createAudioDevice());
}
catch (IOException e) {
reportProblem(filename);
killPlayer();
}
catch(JavaLayerException e) {
reportProblem(filename);
killPlayer();
}
}
/**
* Return an InputStream for the given file.
* @param filename The file to be opened.
* @throws IOException If the file cannot be opened.
* @return An input stream for the file.
*/
private InputStream getInputStream(String filename)
throws IOException
{
return new BufferedInputStream(
new FileInputStream(filename));
}
/**
* Create an audio device.
* @throws JavaLayerException if the device cannot be created.
* @return An audio device.
*/
private AudioDevice createAudioDevice()
throws JavaLayerException
{
return FactoryRegistry.systemRegistry().createAudioDevice();
}
/**
* Terminate the player, if there is one.
*/
private void killPlayer()
{
synchronized(this) {
if(player != null) {
player.stop();
player = null;
}
}
}
/**
* Report a problem playing the given file.
* @param filename The file being played.
*/
private void reportProblem(String filename)
{
System.out.println("There was a problem playing: " + filename);
}
}

View File

@@ -0,0 +1,18 @@
Project: music-organizer. A project to collect audio files.
Authors: David J. Barnes and Michael Kölling
This project is part of the material for the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
It is discussed in chapter 4.
To start:
Create a Builder object and then call its getCollection method.
Use the Get button from the result window to place the
MusicCollection object on the object bench.

View File

@@ -0,0 +1,23 @@
#BlueJ class context
comment0.params=artist\ title\ filename
comment0.target=Track(java.lang.String,\ java.lang.String,\ java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ Track.\n\ @param\ artist\ The\ track's\ artist.\n\ @param\ title\ The\ track's\ title.\n\ @param\ filename\ The\ track\ file.\ \n
comment1.params=filename
comment1.target=Track(java.lang.String)
comment1.text=\n\ Constructor\ for\ objects\ of\ class\ Track.\n\ It\ is\ assumed\ that\ the\ file\ name\ cannot\ be\n\ decoded\ to\ extract\ artist\ and\ title\ details.\n\ @param\ filename\ The\ track\ file.\ \n
comment2.params=
comment2.target=java.lang.String\ getArtist()
comment2.text=\n\ Return\ the\ artist.\n\ @return\ The\ artist.\n
comment3.params=
comment3.target=java.lang.String\ getTitle()
comment3.text=\n\ Return\ the\ title.\n\ @return\ The\ title.\n
comment4.params=
comment4.target=java.lang.String\ getFilename()
comment4.text=\n\ Return\ the\ file\ name.\n\ @return\ The\ file\ name.\n
comment5.params=
comment5.target=java.lang.String\ getDetails()
comment5.text=\n\ Return\ details\ of\ the\ track\:\ artist,\ title\ and\ file\ name.\n\ @return\ The\ track's\ details.\n
comment6.params=artist\ title\ filename
comment6.target=void\ setDetails(java.lang.String,\ java.lang.String,\ java.lang.String)
comment6.text=\n\ Set\ details\ of\ the\ track.\n\ @param\ artist\ The\ track's\ artist.\n\ @param\ title\ The\ track's\ title.\n\ @param\ filename\ The\ track\ file.\ \n
numComments=7

View File

@@ -0,0 +1,88 @@
/**
* Store the details of a music track,
* such as the artist, title, and file name.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class Track
{
// The artist.
private String artist;
// The track's title.
private String title;
// Where the track is stored.
private String filename;
/**
* Constructor for objects of class Track.
* @param artist The track's artist.
* @param title The track's title.
* @param filename The track file.
*/
public Track(String artist, String title, String filename)
{
setDetails(artist, title, filename);
}
/**
* Constructor for objects of class Track.
* It is assumed that the file name cannot be
* decoded to extract artist and title details.
* @param filename The track file.
*/
public Track(String filename)
{
setDetails("unknown", "unknown", filename);
}
/**
* Return the artist.
* @return The artist.
*/
public String getArtist()
{
return artist;
}
/**
* Return the title.
* @return The title.
*/
public String getTitle()
{
return title;
}
/**
* Return the file name.
* @return The file name.
*/
public String getFilename()
{
return filename;
}
/**
* Return details of the track: artist, title and file name.
* @return The track's details.
*/
public String getDetails()
{
return artist + ": " + title + " (file: " + filename + ")";
}
/**
* Set details of the track.
* @param artist The track's artist.
* @param title The track's title.
* @param filename The track file.
*/
private void setDetails(String artist, String title, String filename)
{
this.artist = artist;
this.title = title;
this.filename = filename;
}
}

View File

@@ -0,0 +1,11 @@
#BlueJ class context
comment0.params=
comment0.target=TrackReader()
comment0.text=\n\ Create\ the\ track\ reader,\ ready\ to\ read\ tracks\ from\ the\ music\ library\ folder.\n
comment1.params=folder\ suffix
comment1.target=java.util.ArrayList\ readTracks(java.lang.String,\ java.lang.String)
comment1.text=\n\ Read\ music\ files\ from\ the\ given\ library\ folder\n\ with\ the\ given\ suffix.\n\ @param\ folder\ The\ folder\ to\ look\ for\ files.\n\ @param\ suffix\ The\ suffix\ of\ the\ audio\ type.\n
comment2.params=file
comment2.target=Track\ decodeDetails(java.io.File)
comment2.text=\n\ Try\ to\ decode\ details\ of\ the\ artist\ and\ the\ title\n\ from\ the\ file\ name.\n\ It\ is\ assumed\ that\ the\ details\ are\ in\ the\ form\:\n\ \ \ \ \ artist-title.mp3\n\ @param\ file\ The\ track\ file.\n\ @return\ A\ Track\ containing\ the\ details.\n
numComments=3

View File

@@ -0,0 +1,82 @@
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* A helper class for our music application. This class can read files from the file system
* from a given folder with a specified suffix. It will interpret the file name as artist/
* track title information.
*
* It is expected that file names of music tracks follow a standard format of artist name
* and track name, separated by a dash. For example: TheBeatles-HereComesTheSun.mp3
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class TrackReader
{
/**
* Create the track reader, ready to read tracks from the music library folder.
*/
public TrackReader()
{
// Nothing to do here.
}
/**
* Read music files from the given library folder
* with the given suffix.
* @param folder The folder to look for files.
* @param suffix The suffix of the audio type.
*/
public ArrayList<Track> readTracks(String folder, String suffix)
{
File audioFolder = new File(folder);
File[] audioFiles = audioFolder.listFiles((dir, name) ->
name.toLowerCase().endsWith(suffix));
// Put all the matching files into the organizer.
ArrayList<Track> tracks =
Arrays.stream(audioFiles).
map(file -> decodeDetails(file)).
collect(Collectors.toCollection(ArrayList::new));
return tracks;
}
/**
* Try to decode details of the artist and the title
* from the file name.
* It is assumed that the details are in the form:
* artist-title.mp3
* @param file The track file.
* @return A Track containing the details.
*/
private Track decodeDetails(File file)
{
// The information needed.
String artist = "unknown";
String title = "unknown";
String filename = file.getPath();
// Look for artist and title in the name of the file.
String details = file.getName();
String[] parts = details.split("-");
if(parts.length == 2) {
artist = parts[0];
String titlePart = parts[1];
// Remove a file-type suffix.
parts = titlePart.split("\\.");
if(parts.length >= 1) {
title = parts[0];
}
else {
title = titlePart;
}
}
return new Track(artist, title, filename);
}
}

View File

@@ -0,0 +1,80 @@
#BlueJ package file
dependency1.from=MusicOrganizer
dependency1.to=MusicPlayer
dependency1.type=UsesDependency
dependency2.from=MusicOrganizer
dependency2.to=Track
dependency2.type=UsesDependency
dependency3.from=TrackReader
dependency3.to=Track
dependency3.type=UsesDependency
dependency4.from=MusicOrganizer
dependency4.to=TrackReader
dependency4.type=UsesDependency
objectbench.height=76
objectbench.width=1048
package.editor.height=426
package.editor.width=940
package.editor.x=70
package.editor.y=80
package.numDependencies=4
package.numTargets=4
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=687
readme.editor.width=817
readme.editor.x=38
readme.editor.y=23
target1.editor.height=700
target1.editor.width=900
target1.editor.x=151
target1.editor.y=74
target1.height=60
target1.name=MusicPlayer
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=110
target1.x=460
target1.y=170
target2.editor.height=692
target2.editor.width=790
target2.editor.x=64
target2.editor.y=23
target2.height=60
target2.name=TrackReader
target2.naviview.expanded=false
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=110
target2.x=150
target2.y=170
target3.editor.height=774
target3.editor.width=950
target3.editor.x=279
target3.editor.y=23
target3.height=60
target3.name=MusicOrganizer
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=140
target3.x=290
target3.y=50
target4.editor.height=700
target4.editor.width=900
target4.editor.x=195
target4.editor.y=51
target4.height=60
target4.name=Track
target4.naviview.expanded=true
target4.showInterface=false
target4.type=ClassTarget
target4.typeParameters=
target4.width=110
target4.x=50
target4.y=300