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,17 @@
#BlueJ class context
comment0.params=
comment0.target=Auction()
comment0.text=\n\ Create\ a\ new\ auction.\n
comment1.params=description
comment1.target=void\ enterLot(java.lang.String)
comment1.text=\n\ Enter\ a\ new\ lot\ into\ the\ auction.\n\ @param\ description\ A\ description\ of\ the\ lot.\n
comment2.params=
comment2.target=void\ showLots()
comment2.text=\n\ Show\ the\ full\ list\ of\ lots\ in\ this\ auction.\n
comment3.params=lotNumber\ bidder\ value
comment3.target=void\ makeABid(int,\ Person,\ long)
comment3.text=\n\ Make\ a\ bid\ for\ a\ lot.\n\ A\ message\ is\ printed\ indicating\ whether\ the\ bid\ is\n\ successful\ or\ not.\n\ \n\ @param\ lotNumber\ The\ lot\ being\ bid\ for.\n\ @param\ bidder\ The\ person\ bidding\ for\ the\ lot.\n\ @param\ value\ \ The\ value\ of\ the\ bid.\n
comment4.params=lotNumber
comment4.target=Lot\ getLot(int)
comment4.text=\n\ Return\ the\ lot\ with\ the\ given\ number.\ Return\ null\n\ if\ a\ lot\ with\ this\ number\ does\ not\ exist.\n\ @param\ lotNumber\ The\ number\ of\ the\ lot\ to\ return.\n
numComments=5

View File

@@ -0,0 +1,104 @@
import java.util.ArrayList;
/**
* A simple model of an auction.
* The auction maintains a list of lots of arbitrary length.
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class Auction
{
// The list of Lots in this auction.
private ArrayList<Lot> lots;
// The number that will be given to the next lot entered
// into this auction.
private int nextLotNumber;
/**
* Create a new auction.
*/
public Auction()
{
lots = new ArrayList<>();
nextLotNumber = 1;
}
/**
* Enter a new lot into the auction.
* @param description A description of the lot.
*/
public void enterLot(String description)
{
lots.add(new Lot(nextLotNumber, description));
nextLotNumber++;
}
/**
* Show the full list of lots in this auction.
*/
public void showLots()
{
for(Lot lot : lots) {
System.out.println(lot.toString());
}
}
/**
* Make a bid for a lot.
* A message is printed indicating whether the bid is
* successful or not.
*
* @param lotNumber The lot being bid for.
* @param bidder The person bidding for the lot.
* @param value The value of the bid.
*/
public void makeABid(int lotNumber, Person bidder, long value)
{
Lot selectedLot = getLot(lotNumber);
if(selectedLot != null) {
Bid bid = new Bid(bidder, value);
boolean successful = selectedLot.bidFor(bid);
if(successful) {
System.out.println("The bid for lot number " +
lotNumber + " was successful.");
}
else {
// Report which bid is higher.
Bid highestBid = selectedLot.getHighestBid();
System.out.println("Lot number: " + lotNumber +
" already has a bid of: " +
highestBid.getValue());
}
}
}
/**
* Return the lot with the given number. Return null
* if a lot with this number does not exist.
* @param lotNumber The number of the lot to return.
*/
public Lot getLot(int lotNumber)
{
if((lotNumber >= 1) && (lotNumber < nextLotNumber)) {
// The number seems to be reasonable.
Lot selectedLot = lots.get(lotNumber - 1);
// Include a confidence check to be sure we have the
// right lot.
if(selectedLot.getNumber() != lotNumber) {
System.out.println("Internal error: Lot number " +
selectedLot.getNumber() +
" was returned instead of " +
lotNumber);
// Don't return an invalid lot.
selectedLot = null;
}
return selectedLot;
}
else {
System.out.println("Lot number: " + lotNumber +
" does not exist.");
return null;
}
}
}

View File

@@ -0,0 +1,11 @@
#BlueJ class context
comment0.params=bidder\ value
comment0.target=Bid(Person,\ long)
comment0.text=\n\ Create\ a\ bid.\n\ @param\ bidder\ Who\ is\ bidding\ for\ the\ lot.\n\ @param\ value\ The\ value\ of\ the\ bid.\n
comment1.params=
comment1.target=Person\ getBidder()
comment1.text=\n\ @return\ The\ bidder.\n
comment2.params=
comment2.target=long\ getValue()
comment2.text=\n\ @return\ The\ value\ of\ the\ bid.\n
numComments=3

View File

@@ -0,0 +1,42 @@
/**
* A class that models an auction bid.
* It contains a reference to the Person bidding and the amount bid.
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class Bid
{
// The person making the bid.
private final Person bidder;
// The value of the bid. This could be a large number so
// the long type has been used.
private final long value;
/**
* Create a bid.
* @param bidder Who is bidding for the lot.
* @param value The value of the bid.
*/
public Bid(Person bidder, long value)
{
this.bidder = bidder;
this.value = value;
}
/**
* @return The bidder.
*/
public Person getBidder()
{
return bidder;
}
/**
* @return The value of the bid.
*/
public long getValue()
{
return value;
}
}

View File

@@ -0,0 +1,20 @@
#BlueJ class context
comment0.params=number\ description
comment0.target=Lot(int,\ java.lang.String)
comment0.text=\n\ Construct\ a\ Lot,\ setting\ its\ number\ and\ description.\n\ @param\ number\ The\ lot\ number.\n\ @param\ description\ A\ description\ of\ this\ lot.\n
comment1.params=bid
comment1.target=boolean\ bidFor(Bid)
comment1.text=\n\ Attempt\ to\ bid\ for\ this\ lot.\ A\ successful\ bid\n\ must\ have\ a\ value\ higher\ than\ any\ existing\ bid.\n\ @param\ bid\ A\ new\ bid.\n\ @return\ true\ if\ successful,\ false\ otherwise\n
comment2.params=
comment2.target=java.lang.String\ toString()
comment2.text=\n\ @return\ A\ string\ representation\ of\ this\ lot's\ details.\n
comment3.params=
comment3.target=int\ getNumber()
comment3.text=\n\ @return\ The\ lot's\ number.\n
comment4.params=
comment4.target=java.lang.String\ getDescription()
comment4.text=\n\ @return\ The\ lot's\ description.\n
comment5.params=
comment5.target=Bid\ getHighestBid()
comment5.text=\n\ @return\ The\ highest\ bid\ for\ this\ lot.\n\ \ \ \ \ \ \ \ \ This\ could\ be\ null\ if\ there\ is\n\ \ \ \ \ \ \ \ \ no\ current\ bid.\n
numComments=6

View File

@@ -0,0 +1,94 @@
/**
* A class to model an item (or set of items) in an
* auction: a lot.
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class Lot
{
// A unique identifying number.
private final int number;
// A description of the lot.
private String description;
// The current highest bid for this lot.
private Bid highestBid;
/**
* Construct a Lot, setting its number and description.
* @param number The lot number.
* @param description A description of this lot.
*/
public Lot(int number, String description)
{
this.number = number;
this.description = description;
this.highestBid = null;
}
/**
* Attempt to bid for this lot. A successful bid
* must have a value higher than any existing bid.
* @param bid A new bid.
* @return true if successful, false otherwise
*/
public boolean bidFor(Bid bid)
{
if(highestBid == null) {
// There is no previous bid.
highestBid = bid;
return true;
}
else if(bid.getValue() > highestBid.getValue()) {
// The bid is better than the previous one.
highestBid = bid;
return true;
}
else {
// The bid is not better.
return false;
}
}
/**
* @return A string representation of this lot's details.
*/
public String toString()
{
String details = number + ": " + description;
if(highestBid != null) {
details += " Bid: " +
highestBid.getValue();
}
else {
details += " (No bid)";
}
return details;
}
/**
* @return The lot's number.
*/
public int getNumber()
{
return number;
}
/**
* @return The lot's description.
*/
public String getDescription()
{
return description;
}
/**
* @return The highest bid for this lot.
* This could be null if there is
* no current bid.
*/
public Bid getHighestBid()
{
return highestBid;
}
}

View File

@@ -0,0 +1,8 @@
#BlueJ class context
comment0.params=name
comment0.target=Person(java.lang.String)
comment0.text=\n\ Create\ a\ new\ person\ with\ the\ given\ name.\n\ @param\ name\ The\ person's\ name.\n
comment1.params=
comment1.target=java.lang.String\ getName()
comment1.text=\n\ @return\ The\ person's\ name.\n
numComments=2

View File

@@ -0,0 +1,27 @@
/**
* Maintain details of someone who participates in an auction.
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class Person
{
// The name of this person.
private final String name;
/**
* Create a new person with the given name.
* @param name The person's name.
*/
public Person(String name)
{
this.name = name;
}
/**
* @return The person's name.
*/
public String getName()
{
return name;
}
}

View File

@@ -0,0 +1,26 @@
Project: auction
Authors: David J. Barnes and Michael Kölling
This project is part of the supplementary material for
chapter 4 of the book
Objects First with Java - A Practical Introduction using BlueJ
Sixth edition
David J. Barnes and Michael Kölling
Pearson Education, 2016
Purpose of project: To demonstrate collections of objects
How to start this project:
+ Create an Auction object.
+ Enter a few lots via its enterLot method. Only String
descriptions of the lots are required.
+ Create one or more Person objects to represent bidders.
+ Show the lots and decide on one to bid for. Make a note
of the lot number.
+ Enter a bid for the lot by calling the makeABid method on
the Auction object. Pass the number of the lot, the Person
who is bidding, and the amount of the bid.

View File

@@ -0,0 +1,83 @@
#BlueJ package file
dependency1.from=Auction
dependency1.to=Lot
dependency1.type=UsesDependency
dependency2.from=Auction
dependency2.to=Person
dependency2.type=UsesDependency
dependency3.from=Auction
dependency3.to=Bid
dependency3.type=UsesDependency
dependency4.from=Lot
dependency4.to=Bid
dependency4.type=UsesDependency
dependency5.from=Bid
dependency5.to=Person
dependency5.type=UsesDependency
objectbench.height=76
objectbench.width=774
package.editor.height=429
package.editor.width=666
package.editor.x=70
package.editor.y=80
package.numDependencies=5
package.numTargets=4
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=722
readme.editor.width=842
readme.editor.x=64
readme.editor.y=23
target1.editor.height=705
target1.editor.width=876
target1.editor.x=109
target1.editor.y=42
target1.height=60
target1.name=Lot
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=110
target1.x=220
target1.y=210
target2.editor.height=720
target2.editor.width=886
target2.editor.x=55
target2.editor.y=93
target2.height=60
target2.name=Auction
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=110
target2.x=100
target2.y=80
target3.editor.height=706
target3.editor.width=926
target3.editor.x=114
target3.editor.y=60
target3.height=60
target3.name=Bid
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=110
target3.x=460
target3.y=140
target4.editor.height=711
target4.editor.width=847
target4.editor.x=114
target4.editor.y=60
target4.height=60
target4.name=Person
target4.naviview.expanded=true
target4.showInterface=false
target4.type=ClassTarget
target4.typeParameters=
target4.width=110
target4.x=340
target4.y=320

View File

@@ -0,0 +1,11 @@
#BlueJ class context
comment0.params=
comment0.target=Club()
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ Club\n
comment1.params=member
comment1.target=void\ join(Membership)
comment1.text=\n\ Add\ a\ new\ member\ to\ the\ club's\ list\ of\ members.\n\ @param\ member\ The\ member\ object\ to\ be\ added.\n
comment2.params=
comment2.target=int\ numberOfMembers()
comment2.text=\n\ @return\ The\ number\ of\ members\ (Membership\ objects)\ in\n\ \ \ \ \ \ \ \ \ the\ club.\n
numComments=3

View File

@@ -0,0 +1,36 @@
/**
* Store details of club memberships.
*
* @author (your name)
* @version (a version number or a date)
*/
public class Club
{
// Define any necessary fields here ...
/**
* Constructor for objects of class Club
*/
public Club()
{
// Initialise any fields here ...
}
/**
* Add a new member to the club's list of members.
* @param member The member object to be added.
*/
public void join(Membership member)
{
}
/**
* @return The number of members (Membership objects) in
* the club.
*/
public int numberOfMembers()
{
return 0;
}
}

View File

@@ -0,0 +1,8 @@
#BlueJ class context
comment0.params=
comment0.target=ClubDemo()
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ ClubDemo\n
comment1.params=
comment1.target=void\ demo()
comment1.text=\n\ Add\ some\ members\ to\ the\ club,\ and\ then\n\ show\ how\ many\ there\ are.\n\ Further\ example\ calls\ could\ be\ added\ if\ more\ functionality\n\ is\ added\ to\ the\ Club\ class.\n
numComments=2

View File

@@ -0,0 +1,36 @@
/**
* Provide a demonstration of the Club and Membership
* classes.
*
* @author (your name)
* @version (a version number or a date)
*/
public class ClubDemo
{
// instance variables - replace the example below with your own
private Club club;
/**
* Constructor for objects of class ClubDemo
*/
public ClubDemo()
{
club = new Club();
}
/**
* Add some members to the club, and then
* show how many there are.
* Further example calls could be added if more functionality
* is added to the Club class.
*/
public void demo()
{
club.join(new Membership("David", 2, 2004));
club.join(new Membership("Michael", 1, 2004));
System.out.println("The club has " +
club.numberOfMembers() +
" members.");
}
}

View File

@@ -0,0 +1,17 @@
#BlueJ class context
comment0.params=name\ month\ year
comment0.target=Membership(java.lang.String,\ int,\ int)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ Membership.\n\ @param\ name\ The\ name\ of\ the\ member.\n\ @param\ month\ The\ month\ in\ which\ they\ joined.\ (1\ ...\ 12)\n\ @param\ year\ The\ year\ in\ which\ they\ joined.\n
comment1.params=
comment1.target=java.lang.String\ getName()
comment1.text=\n\ @return\ The\ member's\ name.\n
comment2.params=
comment2.target=int\ getMonth()
comment2.text=\n\ @return\ The\ month\ in\ which\ the\ member\ joined.\n\ \ \ \ \ \ \ \ \ A\ value\ in\ the\ range\ 1\ ...\ 12\n
comment3.params=
comment3.target=int\ getYear()
comment3.text=\n\ @return\ The\ year\ in\ which\ the\ member\ joined.\n
comment4.params=
comment4.target=java.lang.String\ toString()
comment4.text=\n\ @return\ A\ string\ representation\ of\ this\ membership.\n
numComments=5

View File

@@ -0,0 +1,68 @@
/**
* Store details of a club membership.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class Membership
{
// The name of the member.
private String name;
// The month in which the membership was taken out.
private int month;
// The year in which the membership was taken out.
private int year;
/**
* Constructor for objects of class Membership.
* @param name The name of the member.
* @param month The month in which they joined. (1 ... 12)
* @param year The year in which they joined.
*/
public Membership(String name, int month, int year)
throws IllegalArgumentException
{
if(month < 1 || month > 12) {
throw new IllegalArgumentException(
"Month " + month + " out of range. Must be in the range 1 ... 12");
}
this.name = name;
this.month = month;
this.year = year;
}
/**
* @return The member's name.
*/
public String getName()
{
return name;
}
/**
* @return The month in which the member joined.
* A value in the range 1 ... 12
*/
public int getMonth()
{
return month;
}
/**
* @return The year in which the member joined.
*/
public int getYear()
{
return year;
}
/**
* @return A string representation of this membership.
*/
public String toString()
{
return "Name: " + name +
" joined in month " +
month + " of " + year;
}
}

View File

@@ -0,0 +1,152 @@
BlueJ project "club".
Authors: David J. Barnes and Michael Kölling
This project is supplementary 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
Purpose of the project
=======================
The project is intended to extend understanding of object
collections. The exercises could be tackled after completing
Section 4.6 of Chapter 4.
The exercise
============
Membership of a club is represented by an instance of the
Membership class. A complete version of the Membership class
is already provided for you in the club project, and it should
not need any modification. Each Membership object contains
details of a person's name, and the month and year in which
they joined the club. All membership details are filled out
when a Membership object is created.
Your task is to complete the Club class, an outline of which
has been also been provided in the club project.
The Club class is intended to store Membership objects in a
flexible-size collection.
A new Membership object is added to a Club object's collection
via the Club object's join method, which has the following
signature and description:
/**
* Add a new member to the club's collection of members.
* @param member The member object to be added.
*/
public void join(Membership member)
You may assume that the Membership object passed as a
parameter has already been created and is fully initialized.
The Club class also defines a method to return how many
members are in the club. It has the following signature and
description:
/**
* @return The number of members (Membership objects) in
* the club.
*/
public int numberOfMembers()
The number of members corresponds to the number of Membership
objects currently stored in the flexible-size collection.
Complete the definition of the Club class. This should
include:
+ A field to refer to a flexible-size collection
object.
+ A no-arg constructor that sets up an appropriate
flexible-size collection object to store Membership
objects.
+ A full definition of the join method.
+ A full definition of the numberOfMembers method.
Below are some further challenge exercises for those who wish
to experiment with additional features of collections.
Possible Staged Implementation
==============================
This task has been broken down into suggested separate stages
to help you create the finished version in small steps. You
are recommended to compile and run the program after each
stage to check that the changes you have made are correct.
1. Define a field that will be used to refer to a
flexible-size collection object. Use an appropriate import
statement for this collection. In the constructor, create the
collection object and assign it to the field.
2. Complete the numberOfMembers method to return the current
size of the collection object. Of course, until you have
completed the join method, this will always return zero, but it
will be ready for further testing when the join method is
done.
3. Complete the join method.
When you wish to add a new Membership object to the Club
object from the object bench, there are two ways you can do
this.
+ Either create a new Membership object on the object
bench, call the join method on the Club object, and click
on the Membership object to supply the parameter.
+ Or call the join method on the Club object and type:
new Membership("members name here ...", month-number-here, year-number-here)
into the constructor's parameter dialogue box.
When you have added a new member use the numberOfMembers
method to check: a) That the join method is adding to the
collection, and b)That the numberOfMembers method is
working.
Challenge Exercises
===================
These challenge exercises are designed to take the club
project further towards a complete application. They
could be tackled after completing Section 4.9 of Chapter 4.
+ Define a method in the Club class with the following
signature and description:
/**
* Return how many members joined in the given month.
* @param month The month we are interested in.
* @return How many members joined in the given month.
*/
public int joinedInMonth(int month)
If the month parameter is outside the valid range of 1-12,
print an error message and return zero.
+ Define a method in the Club class with the following
signature and description:
/**
* Remove from the club's collection all members who joined
* in the given month, and return them stored in a separate
* collection object.
* @param month The month of the Membership.
* @param year The year of the Membership.
*/
public ArrayList purge(int month, int year)
If the month parameter is outside the valid range of 1-12,
print an error message and return a collection object with no
objects stored in it.
Note: the purge method is significantly harder to write than
any of the others.

View File

@@ -0,0 +1,64 @@
#BlueJ package file
dependency1.from=ClubDemo
dependency1.to=Club
dependency1.type=UsesDependency
dependency2.from=ClubDemo
dependency2.to=Membership
dependency2.type=UsesDependency
dependency3.from=Club
dependency3.to=Membership
dependency3.type=UsesDependency
objectbench.height=76
objectbench.width=823
package.editor.height=429
package.editor.width=715
package.editor.x=70
package.editor.y=80
package.numDependencies=3
package.numTargets=3
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=700
readme.editor.width=900
readme.editor.x=69
readme.editor.y=65
target1.editor.height=700
target1.editor.width=900
target1.editor.x=101
target1.editor.y=57
target1.height=60
target1.name=ClubDemo
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=120
target1.x=90
target1.y=70
target2.editor.height=700
target2.editor.width=900
target2.editor.x=64
target2.editor.y=23
target2.height=60
target2.name=Club
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=110
target2.x=290
target2.y=180
target3.editor.height=700
target3.editor.width=900
target3.editor.x=64
target3.editor.y=42
target3.height=60
target3.name=Membership
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=130
target3.x=460
target3.y=310

View File

@@ -0,0 +1,17 @@
#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\ file\ to\ the\ collection.\n\ @param\ filename\ The\ file\ to\ be\ added.\n
comment2.params=
comment2.target=int\ getNumberOfFiles()
comment2.text=\n\ Return\ the\ number\ of\ files\ in\ the\ collection.\n\ @return\ The\ number\ of\ files\ in\ the\ collection.\n
comment3.params=index
comment3.target=void\ listFile(int)
comment3.text=\n\ List\ a\ file\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ listed.\n
comment4.params=index
comment4.target=void\ removeFile(int)
comment4.text=\n\ Remove\ a\ file\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ removed.\n
numComments=5

View File

@@ -0,0 +1,62 @@
import java.util.ArrayList;
/**
* A class to hold details of audio files.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class MusicOrganizer
{
// An ArrayList for storing the file names of music files.
private ArrayList<String> files;
/**
* Create a MusicOrganizer
*/
public MusicOrganizer()
{
files = new ArrayList<>();
}
/**
* Add a file to the collection.
* @param filename The file to be added.
*/
public void addFile(String filename)
{
files.add(filename);
}
/**
* Return the number of files in the collection.
* @return The number of files in the collection.
*/
public int getNumberOfFiles()
{
return files.size();
}
/**
* List a file from the collection.
* @param index The index of the file to be listed.
*/
public void listFile(int index)
{
if(index >= 0 && index < files.size()) {
String filename = files.get(index);
System.out.println(filename);
}
}
/**
* Remove a file from the collection.
* @param index The index of the file to be removed.
*/
public void removeFile(int index)
{
if(index >= 0 && index < files.size()) {
files.remove(index);
}
}
}

View File

@@ -0,0 +1,17 @@
Project: music-organizer-v1. 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 MusicOrganizer object on the object bench.
Use its methods to add, show, and remove files.

View File

@@ -0,0 +1,29 @@
#BlueJ package file
objectbench.height=100
objectbench.width=757
package.editor.height=379
package.editor.width=954
package.editor.x=70
package.editor.y=80
package.numDependencies=0
package.numTargets=1
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=649
readme.editor.width=817
readme.editor.x=46
readme.editor.y=23
target1.editor.height=702
target1.editor.width=785
target1.editor.x=72
target1.editor.y=84
target1.height=60
target1.name=MusicOrganizer
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=120
target1.x=180
target1.y=110

View File

@@ -0,0 +1,23 @@
#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\ file\ to\ the\ collection.\n\ @param\ filename\ The\ file\ to\ be\ added.\n
comment2.params=
comment2.target=int\ getNumberOfFiles()
comment2.text=\n\ Return\ the\ number\ of\ files\ in\ the\ collection.\n\ @return\ The\ number\ of\ files\ in\ the\ collection.\n
comment3.params=index
comment3.target=void\ listFile(int)
comment3.text=\n\ List\ a\ file\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ listed.\n
comment4.params=index
comment4.target=void\ removeFile(int)
comment4.text=\n\ Remove\ a\ file\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ removed.\n
comment5.params=index
comment5.target=void\ startPlaying(int)
comment5.text=\n\ Start\ playing\ a\ file\ in\ the\ collection.\n\ Use\ stopPlaying()\ to\ stop\ it\ playing.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ played.\n
comment6.params=
comment6.target=void\ stopPlaying()
comment6.text=\n\ Stop\ the\ player.\n
numComments=7

View File

@@ -0,0 +1,85 @@
import java.util.ArrayList;
/**
* A class to hold details of audio files.
* This version can play the files.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class MusicOrganizer
{
// An ArrayList for storing the file names of music files.
private ArrayList<String> files;
// A player for the music files.
private MusicPlayer player;
/**
* Create a MusicOrganizer
*/
public MusicOrganizer()
{
files = new ArrayList<>();
player = new MusicPlayer();
}
/**
* Add a file to the collection.
* @param filename The file to be added.
*/
public void addFile(String filename)
{
files.add(filename);
}
/**
* Return the number of files in the collection.
* @return The number of files in the collection.
*/
public int getNumberOfFiles()
{
return files.size();
}
/**
* List a file from the collection.
* @param index The index of the file to be listed.
*/
public void listFile(int index)
{
if(index >= 0 && index < files.size()) {
String filename = files.get(index);
System.out.println(filename);
}
}
/**
* Remove a file from the collection.
* @param index The index of the file to be removed.
*/
public void removeFile(int index)
{
if(index >= 0 && index < files.size()) {
files.remove(index);
}
}
/**
* Start playing a file in the collection.
* Use stopPlaying() to stop it playing.
* @param index The index of the file to be played.
*/
public void startPlaying(int index)
{
String filename = files.get(index);
player.startPlaying(filename);
}
/**
* Stop the player.
*/
public void stopPlaying()
{
player.stop();
}
}

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,17 @@
Project: music-organizer-v2. 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 MusicOrganizer object on the object bench.
Use its methods to add, remove, and play files.

View File

@@ -0,0 +1,45 @@
#BlueJ package file
dependency1.from=MusicOrganizer
dependency1.to=MusicPlayer
dependency1.type=UsesDependency
objectbench.height=76
objectbench.width=755
package.editor.height=385
package.editor.width=647
package.editor.x=70
package.editor.y=80
package.numDependencies=1
package.numTargets=2
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=652
readme.editor.width=874
readme.editor.x=41
readme.editor.y=23
target1.editor.height=700
target1.editor.width=900
target1.editor.x=76
target1.editor.y=35
target1.height=60
target1.name=MusicPlayer
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=130
target1.x=310
target1.y=210
target2.editor.height=699
target2.editor.width=758
target2.editor.x=529
target2.editor.y=23
target2.height=60
target2.name=MusicOrganizer
target2.naviview.expanded=false
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=130
target2.x=150
target2.y=110

View File

@@ -0,0 +1,32 @@
#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\ file\ to\ the\ collection.\n\ @param\ filename\ The\ file\ to\ be\ added.\n
comment2.params=
comment2.target=int\ getNumberOfFiles()
comment2.text=\n\ Return\ the\ number\ of\ files\ in\ the\ collection.\n\ @return\ The\ number\ of\ files\ in\ the\ collection.\n
comment3.params=index
comment3.target=void\ listFile(int)
comment3.text=\n\ List\ a\ file\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ listed.\n
comment4.params=
comment4.target=void\ listAllFiles()
comment4.text=\n\ Show\ a\ list\ of\ all\ the\ files\ in\ the\ collection.\n
comment5.params=index
comment5.target=void\ removeFile(int)
comment5.text=\n\ Remove\ a\ file\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ removed.\n
comment6.params=index
comment6.target=void\ startPlaying(int)
comment6.text=\n\ Start\ playing\ a\ file\ in\ the\ collection.\n\ Use\ stopPlaying()\ to\ stop\ it\ playing.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ played.\n
comment7.params=
comment7.target=void\ stopPlaying()
comment7.text=\n\ Stop\ the\ player.\n
comment8.params=index
comment8.target=void\ playAndWait(int)
comment8.text=\n\ Play\ a\ file\ in\ the\ collection.\ Only\ return\ once\ playing\ has\ finished.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ played.\n
comment9.params=index
comment9.target=boolean\ validIndex(int)
comment9.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
numComments=10

View File

@@ -0,0 +1,134 @@
import java.util.ArrayList;
/**
* A class to hold details of audio files.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class MusicOrganizer
{
// An ArrayList for storing the file names of music files.
private ArrayList<String> files;
// A player for the music files.
private MusicPlayer player;
/**
* Create a MusicOrganizer
*/
public MusicOrganizer()
{
files = new ArrayList<>();
player = new MusicPlayer();
}
/**
* Add a file to the collection.
* @param filename The file to be added.
*/
public void addFile(String filename)
{
files.add(filename);
}
/**
* Return the number of files in the collection.
* @return The number of files in the collection.
*/
public int getNumberOfFiles()
{
return files.size();
}
/**
* List a file from the collection.
* @param index The index of the file to be listed.
*/
public void listFile(int index)
{
if(validIndex(index)) {
String filename = files.get(index);
System.out.println(filename);
}
}
/**
* Show a list of all the files in the collection.
*/
public void listAllFiles()
{
for(String filename : files) {
System.out.println(filename);
}
}
/**
* Remove a file from the collection.
* @param index The index of the file to be removed.
*/
public void removeFile(int index)
{
if(validIndex(index)) {
files.remove(index);
}
}
/**
* Start playing a file in the collection.
* Use stopPlaying() to stop it playing.
* @param index The index of the file to be played.
*/
public void startPlaying(int index)
{
if(validIndex(index)) {
String filename = files.get(index);
player.startPlaying(filename);
}
}
/**
* Stop the player.
*/
public void stopPlaying()
{
player.stop();
}
/**
* Play a file in the collection. Only return once playing has finished.
* @param index The index of the file to be played.
*/
public void playAndWait(int index)
{
if(validIndex(index)) {
String filename = files.get(index);
player.playSample(filename);
}
}
/**
* 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 validIndex(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 >= files.size()) {
System.out.println("Index is too large: " + index);
valid = false;
}
else {
valid = true;
}
return valid;
}
}

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-v3. 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 MusicOrganizer object on the object bench.
Use its methods to add, remove, and play files. The listAllFiles
method prints a list of the collection.

View File

@@ -0,0 +1,45 @@
#BlueJ package file
dependency1.from=MusicOrganizer
dependency1.to=MusicPlayer
dependency1.type=UsesDependency
objectbench.height=76
objectbench.width=771
package.editor.height=390
package.editor.width=663
package.editor.x=70
package.editor.y=80
package.numDependencies=1
package.numTargets=2
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=654
readme.editor.width=869
readme.editor.x=39
readme.editor.y=23
target1.editor.height=700
target1.editor.width=900
target1.editor.x=181
target1.editor.y=51
target1.height=60
target1.name=MusicPlayer
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=130
target1.x=300
target1.y=220
target2.editor.height=766
target2.editor.width=888
target2.editor.x=23
target2.editor.y=27
target2.height=60
target2.name=MusicOrganizer
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=130
target2.x=150
target2.y=120

View File

@@ -0,0 +1,32 @@
#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\ file\ to\ the\ collection.\n\ @param\ filename\ The\ file\ to\ be\ added.\n
comment2.params=
comment2.target=int\ getNumberOfFiles()
comment2.text=\n\ Return\ the\ number\ of\ files\ in\ the\ collection.\n\ @return\ The\ number\ of\ files\ in\ the\ collection.\n
comment3.params=index
comment3.target=void\ listFile(int)
comment3.text=\n\ List\ a\ file\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ listed.\n
comment4.params=
comment4.target=void\ listAllFiles()
comment4.text=\n\ Show\ a\ list\ of\ all\ the\ files\ in\ the\ collection.\n
comment5.params=searchString
comment5.target=void\ listMatching(java.lang.String)
comment5.text=\n\ List\ the\ names\ of\ files\ matching\ the\ given\ search\ string.\n\ @param\ searchString\ The\ string\ to\ match.\n
comment6.params=searchString
comment6.target=int\ findFirst(java.lang.String)
comment6.text=\n\ Find\ the\ index\ of\ the\ first\ file\ matching\ the\ given\n\ search\ string.\n\ @param\ searchString\ The\ string\ to\ match.\n\ @return\ The\ index\ of\ the\ first\ occurrence,\ or\ -1\ if\n\ \ \ \ \ \ \ \ \ no\ match\ is\ found.\n
comment7.params=index
comment7.target=void\ removeFile(int)
comment7.text=\n\ Remove\ a\ file\ from\ the\ collection.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ removed.\n
comment8.params=index
comment8.target=void\ startPlaying(int)
comment8.text=\n\ Start\ playing\ a\ file\ in\ the\ collection.\n\ Use\ stopPlaying()\ to\ stop\ it\ playing.\n\ @param\ index\ The\ index\ of\ the\ file\ to\ be\ played.\n
comment9.params=
comment9.target=void\ stopPlaying()
comment9.text=\n\ Stop\ the\ player.\n
numComments=10

View File

@@ -0,0 +1,144 @@
import java.util.ArrayList;
import java.util.OptionalInt;
import java.util.stream.IntStream;
/**
* A class to hold details of audio files.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class MusicOrganizer
{
// An ArrayList for storing the file names of music files.
private ArrayList<String> files;
// A player for the music files.
private MusicPlayer player;
/**
* Create a MusicOrganizer
*/
public MusicOrganizer()
{
files = new ArrayList<>();
player = new MusicPlayer();
}
/**
* Add a file to the collection.
* @param filename The file to be added.
*/
public void addFile(String filename)
{
files.add(filename);
}
/**
* Return the number of files in the collection.
* @return The number of files in the collection.
*/
public int getNumberOfFiles()
{
return files.size();
}
/**
* List a file from the collection.
* @param index The index of the file to be listed.
*/
public void listFile(int index)
{
if(index >= 0 && index < files.size()) {
String filename = files.get(index);
System.out.println(filename);
}
}
/**
* Show a list of all the files in the collection.
*/
public void listAllFiles()
{
for(String filename : files) {
System.out.println(filename);
}
}
/**
* List the names of files matching the given search string.
* @param searchString The string to match.
*/
public void listMatching(String searchString)
{
for(String filename : files) {
if(filename.contains(searchString)) {
// A match.
System.out.println(filename);
}
}
}
/**
* Find the index of the first file matching the given
* search string.
* @param searchString The string to match.
* @return The index of the first occurrence, or -1 if
* no match is found.
*/
public int findFirst(String searchString)
{
int index = 0;
// Record that we will be searching until a match is found.
boolean searching = true;
while(searching && index < files.size()) {
String filename = files.get(index);
if(filename.contains(searchString)) {
// A match. We can stop searching.
searching = false;
}
else {
// Move on.
index++;
}
}
if(searching) {
// We didn't find it.
return -1;
}
else {
// Return where it was found.
return index;
}
}
/**
* Remove a file from the collection.
* @param index The index of the file to be removed.
*/
public void removeFile(int index)
{
if(index >= 0 && index < files.size()) {
files.remove(index);
}
}
/**
* Start playing a file in the collection.
* Use stopPlaying() to stop it playing.
* @param index The index of the file to be played.
*/
public void startPlaying(int index)
{
String filename = files.get(index);
player.startPlaying(filename);
}
/**
* Stop the player.
*/
public void stopPlaying()
{
player.stop();
}
}

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,24 @@
Project: music-organizer-v4. 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 MusicOrganizer object on the object bench.
Use its methods to add, remove, and play files.
The listMatching method prints all files matching a
given string the collection.
The findFirst method finds the index of a file that
matches a search string.

View File

@@ -0,0 +1,45 @@
#BlueJ package file
dependency1.from=MusicOrganizer
dependency1.to=MusicPlayer
dependency1.type=UsesDependency
objectbench.height=100
objectbench.width=774
package.editor.height=390
package.editor.width=971
package.editor.x=70
package.editor.y=80
package.numDependencies=1
package.numTargets=2
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=664
readme.editor.width=812
readme.editor.x=37
readme.editor.y=23
target1.editor.height=700
target1.editor.width=900
target1.editor.x=90
target1.editor.y=53
target1.height=60
target1.name=MusicPlayer
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=130
target1.x=310
target1.y=200
target2.editor.height=657
target2.editor.width=819
target2.editor.x=95
target2.editor.y=143
target2.height=60
target2.name=MusicOrganizer
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=140
target2.x=140
target2.y=120

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

View File

@@ -0,0 +1,23 @@
#BlueJ class context
comment0.params=id\ name
comment0.target=Product(int,\ java.lang.String)
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ Product.\n\ The\ initial\ stock\ quantity\ is\ zero.\n\ @param\ id\ The\ product's\ identifying\ number.\n\ @param\ name\ The\ product's\ name.\n
comment1.params=
comment1.target=int\ getID()
comment1.text=\n\ @return\ The\ product's\ id.\n
comment2.params=
comment2.target=java.lang.String\ getName()
comment2.text=\n\ @return\ The\ product's\ name.\n
comment3.params=
comment3.target=int\ getQuantity()
comment3.text=\n\ @return\ The\ quantity\ in\ stock.\n
comment4.params=
comment4.target=java.lang.String\ toString()
comment4.text=\n\ @return\ The\ id,\ name\ and\ quantity\ in\ stock.\n
comment5.params=amount
comment5.target=void\ increaseQuantity(int)
comment5.text=\n\ Restock\ with\ the\ given\ amount\ of\ this\ product.\n\ The\ current\ quantity\ is\ incremented\ by\ the\ given\ amount.\n\ @param\ amount\ The\ number\ of\ new\ items\ added\ to\ the\ stock.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ This\ must\ be\ greater\ than\ zero.\n
comment6.params=
comment6.target=void\ sellOne()
comment6.text=\n\ Sell\ one\ of\ these\ products.\n\ An\ error\ is\ reported\ if\ there\ appears\ to\ be\ no\ stock.\n
numComments=7

View File

@@ -0,0 +1,96 @@
/**
* Model some details of a product sold by a company.
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class Product
{
// An identifying number for this product.
private int id;
// The name of this product.
private String name;
// The quantity of this product in stock.
private int quantity;
/**
* Constructor for objects of class Product.
* The initial stock quantity is zero.
* @param id The product's identifying number.
* @param name The product's name.
*/
public Product(int id, String name)
{
this.id = id;
this.name = name;
quantity = 0;
}
/**
* @return The product's id.
*/
public int getID()
{
return id;
}
/**
* @return The product's name.
*/
public String getName()
{
return name;
}
/**
* @return The quantity in stock.
*/
public int getQuantity()
{
return quantity;
}
/**
* @return The id, name and quantity in stock.
*/
public String toString()
{
return id + ": " +
name +
" stock level: " + quantity;
}
/**
* Restock with the given amount of this product.
* The current quantity is incremented by the given amount.
* @param amount The number of new items added to the stock.
* This must be greater than zero.
*/
public void increaseQuantity(int amount)
{
if(amount > 0) {
quantity += amount;
}
else {
System.out.println("Attempt to restock " +
name +
" with a non-positive amount: " +
amount);
}
}
/**
* Sell one of these products.
* An error is reported if there appears to be no stock.
*/
public void sellOne()
{
if(quantity > 0) {
quantity--;
}
else {
System.out.println(
"Attempt to sell an out of stock item: " + name);
}
}
}

View File

@@ -0,0 +1,133 @@
BlueJ project "products".
Authors: David J. Barnes and Michael Kölling
This project is supplementary 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
Purpose of the project
=======================
The project is intended to extend understanding of object
collections, including the use of loops, iterators and
casting. The exercises could be tackled after completing
Section 4.9 of Chapter 4.
The exercises
=============
A company records stock levels of the products it sells.
A StockManager object maintains an arbitrary-length list
of Product objects. Your task is to complete the outline
implementation of the StockManger class.
The StockDemo class has been provided to help demonstrate ways
in which StockManager and Product objects might be used. You
can create a StockDemo object on the object bench and call its
demo method. As you develop the StockManager class, this demo
should demonstrate increasing functionality.
The StockManager Class
======================
The StockManager class uses a LinkedList object to store zero
or more Product items. Its addProduct method adds a new
product to the collection. The following methods need
completing: delivery, findProduct, printProductDetails, and
numberInStock.
+ The delivery method should find the Product with the given
ID in the list of products and then call its increaseQuantity
method.
+ The findProduct method should look through the collection
for a product whose id field matches the id argument of this
method. If a matching product is found, that Product should be
returned as the method's result. If no matching product is
found, return null from the method.
+ The printProductDetails method should iterate over the list
of products and print the result of calling the toString()
method on each.
+ The numberInStock method should locate a product in the
collection with a matching ID, and return the current quantity
of that product as a method result. If no product with a
matching ID is found, return zero.
The Product Class
=================
This class has been provided for you, and you should not need
to make any alterations to it.
Each product sold by the company is represented by an instance
of the Product class, which records a product's ID, name and
how many of that product are currently in stock. The Product
class defines the increaseQuantity method to record increases
in the stock level of that product. The sellOne method
records that one item of that product has been sold by
reducing the quantity field level by one.
Staged Implementation
=====================
The overall task has been broken down into suggested separate
stages to help you create the finished version in small steps.
You are recommended to compile and run the program after each
stage to check that the changes you have made are correct.
1. Implement the printProductDetails method to ensure that you
are able to iterate over the collection of Products. Just
print out each product using System.out. Using an Iterator is
the preferred approach, but use an integer index variable if
you find that easier to understand.
2. Implement the findProduct method. This differs from the
printProductDetails method in that it will not necessarily
have to examine every product in the collection before a match
is found. For instance, if the first product in the
collection matches the product name, iteration can finish and
that first Product returned. On the other hand, it is
possible that there might be no match for the name in the
collection. In that case, the whole collection will be
examined, without finding a product to return. In this case
the null value should be returned.
When looking for a match, you will need to call the getID
method on a Product. This means that you will need to use a
cast when you retrieve an item from the list. You can read
about casts in the discussion of the auction project in
Chapter 4. In particular, section 4.9.3 on page 92 is about
casting.
3. Implement the numberInStock method. This is relatively
simple to implement once the findProduct method has been
completed. For instance, numberInStock can call the
findProduct method to do the searching, and then call the
getQuantity method on the result. Watch out for products that
cannot be found, though.
4. Implement the delivery method using a similar approach to
that used in numberInStock.
Optional Challenge Exercises
============================
+ Implement a method in StockManager to print details of
all products with stock levels below a given value (passed
as a parameter to the method).
+ Modify the addProduct method so that a new product
cannot be added to the product list with the same ID
as an existing one.
+ Add to StockManager a method that finds a product from its
name rather than its ID:
public Product findProduct(String name)
In order to do this, you need to know that two String objects
s1 and s2 can be tested for equality with the boolean
expression:
s1.equals(s2)
More detail on this can be found in Chapter 5, page 115.

View File

@@ -0,0 +1,20 @@
#BlueJ class context
comment0.params=
comment0.target=StockDemo()
comment0.text=\n\ Create\ a\ StockManager\ and\ populate\ it\ with\ a\ few\n\ sample\ products.\n
comment1.params=
comment1.target=void\ demo()
comment1.text=\n\ Provide\ a\ very\ simple\ demonstration\ of\ how\ a\ StockManager\n\ might\ be\ used.\ Details\ of\ one\ product\ are\ shown,\ the\n\ product\ is\ restocked,\ and\ then\ the\ details\ are\ shown\ again.\n
comment2.params=id
comment2.target=void\ showDetails(int)
comment2.text=\n\ Show\ details\ of\ the\ given\ product.\ If\ found,\n\ its\ name\ and\ stock\ quantity\ will\ be\ shown.\n\ @param\ id\ The\ ID\ of\ the\ product\ to\ look\ for.\n
comment3.params=id
comment3.target=void\ sellProduct(int)
comment3.text=\n\ Sell\ one\ of\ the\ given\ item.\n\ Show\ the\ before\ and\ after\ status\ of\ the\ product.\n\ @param\ id\ The\ ID\ of\ the\ product\ being\ sold.\n
comment4.params=id
comment4.target=Product\ getProduct(int)
comment4.text=\n\ Get\ the\ product\ with\ the\ given\ id\ from\ the\ manager.\n\ An\ error\ message\ is\ printed\ if\ there\ is\ no\ match.\n\ @param\ id\ The\ ID\ of\ the\ product.\n\ @return\ The\ Product,\ or\ null\ if\ no\ matching\ one\ is\ found.\n
comment5.params=
comment5.target=StockManager\ getManager()
comment5.text=\n\ @return\ The\ stock\ manager.\n
numComments=6

View File

@@ -0,0 +1,92 @@
/**
* Demonstrate the StockManager and Product classes.
* The demonstration becomes properly functional as
* the StockManager class is completed.
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class StockDemo
{
// The stock manager.
private StockManager manager;
/**
* Create a StockManager and populate it with a few
* sample products.
*/
public StockDemo()
{
manager = new StockManager();
manager.addProduct(new Product(132, "Clock Radio"));
manager.addProduct(new Product(37, "Mobile Phone"));
manager.addProduct(new Product(23, "Microwave Oven"));
}
/**
* Provide a very simple demonstration of how a StockManager
* might be used. Details of one product are shown, the
* product is restocked, and then the details are shown again.
*/
public void demo()
{
// Show details of all of the products.
manager.printProductDetails();
// Take delivery of 5 items of one of the products.
manager.delivery(132, 5);
manager.printProductDetails();
}
/**
* Show details of the given product. If found,
* its name and stock quantity will be shown.
* @param id The ID of the product to look for.
*/
public void showDetails(int id)
{
Product product = getProduct(id);
if(product != null) {
System.out.println(product.toString());
}
}
/**
* Sell one of the given item.
* Show the before and after status of the product.
* @param id The ID of the product being sold.
*/
public void sellProduct(int id)
{
Product product = getProduct(id);
if(product != null) {
showDetails(id);
product.sellOne();
showDetails(id);
}
}
/**
* Get the product with the given id from the manager.
* An error message is printed if there is no match.
* @param id The ID of the product.
* @return The Product, or null if no matching one is found.
*/
public Product getProduct(int id)
{
Product product = manager.findProduct(id);
if(product == null) {
System.out.println("Product with ID: " + id +
" is not recognised.");
}
return product;
}
/**
* @return The stock manager.
*/
public StockManager getManager()
{
return manager;
}
}

View File

@@ -0,0 +1,20 @@
#BlueJ class context
comment0.params=
comment0.target=StockManager()
comment0.text=\n\ Initialise\ the\ stock\ manager.\n
comment1.params=item
comment1.target=void\ addProduct(Product)
comment1.text=\n\ Add\ a\ product\ to\ the\ list.\n\ @param\ item\ The\ item\ to\ be\ added.\n
comment2.params=id\ amount
comment2.target=void\ delivery(int,\ int)
comment2.text=\n\ Receive\ a\ delivery\ of\ a\ particular\ product.\n\ Increase\ the\ quantity\ of\ the\ product\ by\ the\ given\ amount.\n\ @param\ id\ The\ ID\ of\ the\ product.\n\ @param\ amount\ The\ amount\ to\ increase\ the\ quantity\ by.\n
comment3.params=id
comment3.target=Product\ findProduct(int)
comment3.text=\n\ Try\ to\ find\ a\ product\ in\ the\ stock\ with\ the\ given\ id.\n\ @return\ The\ identified\ product,\ or\ null\ if\ there\ is\ none\n\ \ \ \ \ \ \ \ \ with\ a\ matching\ ID.\n
comment4.params=id
comment4.target=int\ numberInStock(int)
comment4.text=\n\ Locate\ a\ product\ with\ the\ given\ ID,\ and\ return\ how\n\ many\ of\ this\ item\ are\ in\ stock.\ If\ the\ ID\ does\ not\n\ match\ any\ product,\ return\ zero.\n\ @param\ id\ The\ ID\ of\ the\ product.\n\ @return\ The\ quantity\ of\ the\ given\ product\ in\ stock.\n
comment5.params=
comment5.target=void\ printProductDetails()
comment5.text=\n\ Print\ details\ of\ all\ the\ products.\n
numComments=6

View File

@@ -0,0 +1,70 @@
import java.util.ArrayList;
/**
* Manage the stock in a business.
* The stock is described by zero or more Products.
*
* @author (your name)
* @version (a version number or a date)
*/
public class StockManager
{
// A list of the products.
private ArrayList<Product> stock;
/**
* Initialise the stock manager.
*/
public StockManager()
{
stock = new ArrayList<>();
}
/**
* Add a product to the list.
* @param item The item to be added.
*/
public void addProduct(Product item)
{
stock.add(item);
}
/**
* Receive a delivery of a particular product.
* Increase the quantity of the product by the given amount.
* @param id The ID of the product.
* @param amount The amount to increase the quantity by.
*/
public void delivery(int id, int amount)
{
}
/**
* Try to find a product in the stock with the given id.
* @return The identified product, or null if there is none
* with a matching ID.
*/
public Product findProduct(int id)
{
return null;
}
/**
* Locate a product with the given ID, and return how
* many of this item are in stock. If the ID does not
* match any product, return zero.
* @param id The ID of the product.
* @return The quantity of the given product in stock.
*/
public int numberInStock(int id)
{
return 0;
}
/**
* Print details of all the products.
*/
public void printProductDetails()
{
}
}

View File

@@ -0,0 +1,64 @@
#BlueJ package file
dependency1.from=StockDemo
dependency1.to=StockManager
dependency1.type=UsesDependency
dependency2.from=StockDemo
dependency2.to=Product
dependency2.type=UsesDependency
dependency3.from=StockManager
dependency3.to=Product
dependency3.type=UsesDependency
objectbench.height=76
objectbench.width=725
package.editor.height=398
package.editor.width=617
package.editor.x=70
package.editor.y=80
package.numDependencies=3
package.numTargets=3
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=700
readme.editor.width=900
readme.editor.x=64
readme.editor.y=23
target1.editor.height=700
target1.editor.width=900
target1.editor.x=64
target1.editor.y=23
target1.height=60
target1.name=StockManager
target1.naviview.expanded=true
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=120
target1.x=390
target1.y=160
target2.editor.height=699
target2.editor.width=936
target2.editor.x=64
target2.editor.y=23
target2.height=60
target2.name=Product
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=100
target2.x=90
target2.y=270
target3.editor.height=700
target3.editor.width=900
target3.editor.x=93
target3.editor.y=23
target3.height=60
target3.name=StockDemo
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=110
target3.x=220
target3.y=60