first commit
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
#BlueJ class context
|
||||
comment0.params=
|
||||
comment0.target=AddressBook()
|
||||
comment0.text=\n\ Perform\ any\ initialization\ for\ the\ address\ book.\n
|
||||
comment1.params=key
|
||||
comment1.target=ContactDetails\ getDetails(java.lang.String)
|
||||
comment1.text=\n\ Look\ up\ a\ name\ or\ phone\ number\ and\ return\ the\n\ corresponding\ contact\ details.\n\ @param\ key\ The\ name\ or\ number\ to\ be\ looked\ up.\n\ @return\ The\ details\ corresponding\ to\ the\ key.\n
|
||||
comment2.params=key
|
||||
comment2.target=boolean\ keyInUse(java.lang.String)
|
||||
comment2.text=\n\ Return\ whether\ or\ not\ the\ current\ key\ is\ in\ use.\n\ @param\ key\ The\ name\ or\ number\ to\ be\ looked\ up.\n\ @return\ true\ if\ the\ key\ is\ in\ use,\ false\ otherwise.\n
|
||||
comment3.params=details
|
||||
comment3.target=void\ addDetails(ContactDetails)
|
||||
comment3.text=\n\ Add\ a\ new\ set\ of\ details\ to\ the\ address\ book.\n\ @param\ details\ The\ details\ to\ associate\ with\ the\ person.\n
|
||||
comment4.params=oldKey\ details
|
||||
comment4.target=void\ changeDetails(java.lang.String,\ ContactDetails)
|
||||
comment4.text=\n\ Change\ the\ details\ previously\ stored\ under\ the\ given\ key.\n\ @param\ oldKey\ One\ of\ the\ keys\ used\ to\ store\ the\ details.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ This\ should\ be\ a\ key\ that\ is\ currently\ in\ use.\n\ @param\ details\ The\ replacement\ details.\ Must\ not\ be\ null.\n\ @throws\ IllegalArgumentException\ If\ either\ argument\ is\ null.\n
|
||||
comment5.params=keyPrefix
|
||||
comment5.target=ContactDetails[]\ search(java.lang.String)
|
||||
comment5.text=\n\ Search\ for\ all\ details\ stored\ under\ a\ key\ that\ starts\ with\n\ the\ given\ prefix.\n\ @param\ keyPrefix\ The\ key\ prefix\ to\ search\ on.\ This\ may\ be\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ of\ zero\ length,\ but\ must\ not\ be\ null.\n\ @return\ An\ array\ of\ those\ details\ that\ have\ been\ found.\n
|
||||
comment6.params=
|
||||
comment6.target=int\ getNumberOfEntries()
|
||||
comment6.text=\n\ Return\ the\ number\ of\ entries\ currently\ in\ the\n\ address\ book.\n\ @return\ The\ number\ of\ entries.\n
|
||||
comment7.params=key
|
||||
comment7.target=void\ removeDetails(java.lang.String)
|
||||
comment7.text=\n\ Remove\ the\ entry\ with\ the\ given\ key\ from\ the\ address\ book.\n\ The\ key\ should\ be\ one\ that\ is\ currently\ in\ use.\n\ @param\ key\ One\ of\ the\ keys\ of\ the\ entry\ to\ be\ removed.\n\ @throws\ IllegalArgumentException\ If\ the\ key\ is\ null.\n
|
||||
comment8.params=
|
||||
comment8.target=java.lang.String\ listDetails()
|
||||
comment8.text=\n\ Return\ all\ the\ contact\ details,\ sorted\ according\n\ to\ the\ sort\ order\ of\ the\ ContactDetails\ class.\n\ @return\ A\ sorted\ list\ of\ the\ details.\n
|
||||
numComments=9
|
@@ -0,0 +1,166 @@
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* A class to maintain an arbitrary number of contact details.
|
||||
* Details are indexed by both name and phone number.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class AddressBook
|
||||
{
|
||||
// Storage for an arbitrary number of details.
|
||||
private TreeMap<String, ContactDetails> book;
|
||||
private int numberOfEntries;
|
||||
|
||||
/**
|
||||
* Perform any initialization for the address book.
|
||||
*/
|
||||
public AddressBook()
|
||||
{
|
||||
book = new TreeMap<>();
|
||||
numberOfEntries = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a name or phone number and return the
|
||||
* corresponding contact details.
|
||||
* @param key The name or number to be looked up.
|
||||
* @return The details corresponding to the key.
|
||||
*/
|
||||
public ContactDetails getDetails(String key)
|
||||
{
|
||||
return book.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the current key is in use.
|
||||
* @param key The name or number to be looked up.
|
||||
* @return true if the key is in use, false otherwise.
|
||||
*/
|
||||
public boolean keyInUse(String key)
|
||||
{
|
||||
return book.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new set of details to the address book.
|
||||
* @param details The details to associate with the person.
|
||||
*/
|
||||
public void addDetails(ContactDetails details)
|
||||
{
|
||||
if(details == null) {
|
||||
throw new IllegalArgumentException("Null details passed to addDetails.");
|
||||
}
|
||||
book.put(details.getName(), details);
|
||||
book.put(details.getPhone(), details);
|
||||
numberOfEntries++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the details previously stored under the given key.
|
||||
* @param oldKey One of the keys used to store the details.
|
||||
This should be a key that is currently in use.
|
||||
* @param details The replacement details. Must not be null.
|
||||
* @throws IllegalArgumentException If either argument is null.
|
||||
*/
|
||||
public void changeDetails(String oldKey,
|
||||
ContactDetails details)
|
||||
{
|
||||
if(details == null) {
|
||||
throw new IllegalArgumentException("Null details passed to changeDetails.");
|
||||
}
|
||||
if(oldKey == null){
|
||||
throw new IllegalArgumentException("Null key passed to changeDetails.");
|
||||
}
|
||||
if(keyInUse(oldKey)){
|
||||
removeDetails(oldKey);
|
||||
addDetails(details);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for all details stored under a key that starts with
|
||||
* the given prefix.
|
||||
* @param keyPrefix The key prefix to search on. This may be
|
||||
* of zero length, but must not be null.
|
||||
* @return An array of those details that have been found.
|
||||
*/
|
||||
public ContactDetails[] search(String keyPrefix)
|
||||
{
|
||||
// Build a list of the matches.
|
||||
List<ContactDetails> matches = new LinkedList<>();
|
||||
if(keyPrefix != null) {
|
||||
// Find keys that are equal-to or greater-than the prefix.
|
||||
SortedMap<String, ContactDetails> tail = book.tailMap(keyPrefix);
|
||||
Iterator<String> it = tail.keySet().iterator();
|
||||
// Stop when we find a mismatch.
|
||||
boolean endOfSearch = false;
|
||||
while(!endOfSearch && it.hasNext()) {
|
||||
String key = it.next();
|
||||
if(key.startsWith(keyPrefix)) {
|
||||
matches.add(book.get(key));
|
||||
}
|
||||
else {
|
||||
endOfSearch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ContactDetails[] results = new ContactDetails[matches.size()];
|
||||
matches.toArray(results);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of entries currently in the
|
||||
* address book.
|
||||
* @return The number of entries.
|
||||
*/
|
||||
public int getNumberOfEntries()
|
||||
{
|
||||
return numberOfEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the entry with the given key from the address book.
|
||||
* The key should be one that is currently in use.
|
||||
* @param key One of the keys of the entry to be removed.
|
||||
* @throws IllegalArgumentException If the key is null.
|
||||
*/
|
||||
public void removeDetails(String key)
|
||||
{
|
||||
if(key == null){
|
||||
throw new IllegalArgumentException("Null key passed to removeDetails.");
|
||||
}
|
||||
if(keyInUse(key)) {
|
||||
ContactDetails details = book.get(key);
|
||||
book.remove(details.getName());
|
||||
book.remove(details.getPhone());
|
||||
numberOfEntries--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the contact details, sorted according
|
||||
* to the sort order of the ContactDetails class.
|
||||
* @return A sorted list of the details.
|
||||
*/
|
||||
public String listDetails()
|
||||
{
|
||||
// Because each entry is stored under two keys, it is
|
||||
// necessary to build a set of the ContactDetails. This
|
||||
// eliminates duplicates.
|
||||
StringBuilder allEntries = new StringBuilder();
|
||||
Set<ContactDetails> sortedDetails = new TreeSet<>(book.values());
|
||||
for(ContactDetails details : sortedDetails) {
|
||||
allEntries.append(details).append("\n\n");
|
||||
}
|
||||
return allEntries.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
#BlueJ class context
|
||||
comment0.params=
|
||||
comment0.target=AddressBookDemo()
|
||||
comment0.text=\n\ Setup\ an\ AddressBook\ with\ sample\ data.\n\ The\ address\ book\ is\ passed\ to\ a\ GUI\ to\ provide\n\ a\ view\ of\ the\ data.\n
|
||||
comment1.params=
|
||||
comment1.target=void\ showInterface()
|
||||
comment1.text=\n\ Allow\ the\ user\ to\ interact\ with\ the\ address\ book.\n
|
||||
comment2.params=
|
||||
comment2.target=AddressBook\ getBook()
|
||||
comment2.text=\n\ @return\ The\ sample\ address\ book.\n
|
||||
numComments=3
|
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Provide a simple demonstration of the AddressBook class.
|
||||
* Sample data is added to the address book,
|
||||
* and a text interface is provided.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class AddressBookDemo
|
||||
{
|
||||
private AddressBook book;
|
||||
private AddressBookTextInterface interaction;
|
||||
|
||||
/**
|
||||
* Setup an AddressBook with sample data.
|
||||
* The address book is passed to a GUI to provide
|
||||
* a view of the data.
|
||||
*/
|
||||
public AddressBookDemo()
|
||||
{
|
||||
ContactDetails[] sampleDetails = {
|
||||
new ContactDetails("david", "08459 100000", "address 1"),
|
||||
new ContactDetails("michael", "08459 200000", "address 2"),
|
||||
new ContactDetails("john", "08459 300000", "address 3"),
|
||||
new ContactDetails("helen", "08459 400000", "address 4"),
|
||||
new ContactDetails("emma", "08459 500000", "address 5"),
|
||||
new ContactDetails("kate", "08459 600000", "address 6"),
|
||||
new ContactDetails("chris", "08459 700000", "address 7"),
|
||||
new ContactDetails("ruth", "08459 800000", "address 8"),
|
||||
};
|
||||
book = new AddressBook();
|
||||
for(ContactDetails details : sampleDetails) {
|
||||
book.addDetails(details);
|
||||
}
|
||||
interaction = new AddressBookTextInterface(book);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the user to interact with the address book.
|
||||
*/
|
||||
public void showInterface()
|
||||
{
|
||||
interaction.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The sample address book.
|
||||
*/
|
||||
public AddressBook getBook()
|
||||
{
|
||||
return book;
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
#BlueJ class context
|
||||
comment0.params=book
|
||||
comment0.target=AddressBookTextInterface(AddressBook)
|
||||
comment0.text=\n\ Constructor\ for\ objects\ of\ class\ AddressBookTextInterface\n\ @param\ book\ The\ address\ book\ to\ be\ manipulated.\n
|
||||
comment1.params=
|
||||
comment1.target=void\ run()
|
||||
comment1.text=\n\ Read\ a\ series\ of\ commands\ from\ the\ user\ to\ interact\n\ with\ the\ address\ book.\ Stop\ when\ the\ user\ types\ 'quit'.\n
|
||||
comment2.params=
|
||||
comment2.target=void\ add()
|
||||
comment2.text=\n\ Add\ a\ new\ entry.\n
|
||||
comment3.params=
|
||||
comment3.target=void\ get()
|
||||
comment3.text=\n\ Find\ an\ entry\ matching\ a\ key.\n
|
||||
comment4.params=
|
||||
comment4.target=void\ remove()
|
||||
comment4.text=\n\ Remove\ an\ entry\ matching\ a\ key.\n
|
||||
comment5.params=
|
||||
comment5.target=void\ find()
|
||||
comment5.text=\n\ Find\ entries\ matching\ a\ key\ prefix.\n
|
||||
comment6.params=
|
||||
comment6.target=void\ help()
|
||||
comment6.text=\n\ List\ the\ available\ commands.\n
|
||||
comment7.params=
|
||||
comment7.target=void\ list()
|
||||
comment7.text=\n\ List\ the\ address\ book's\ contents.\n
|
||||
numComments=8
|
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Provide a textual interface to an AddressBook.
|
||||
* Different commands provide access to the data in the address book.
|
||||
*
|
||||
* One to search the address book.
|
||||
*
|
||||
* One to allow a set of contact details to be entered.
|
||||
*
|
||||
* One to show all the entries in the book.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class AddressBookTextInterface
|
||||
{
|
||||
// The address book to be viewed and manipulated.
|
||||
private AddressBook book;
|
||||
// A parser for handling user commands.
|
||||
private Parser parser;
|
||||
|
||||
/**
|
||||
* Constructor for objects of class AddressBookTextInterface
|
||||
* @param book The address book to be manipulated.
|
||||
*/
|
||||
public AddressBookTextInterface(AddressBook book)
|
||||
{
|
||||
this.book = book;
|
||||
parser = new Parser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a series of commands from the user to interact
|
||||
* with the address book. Stop when the user types 'quit'.
|
||||
*/
|
||||
public void run()
|
||||
{
|
||||
System.out.println("Address Book.");
|
||||
System.out.println("Type 'help' for a list of commands.");
|
||||
|
||||
String command;
|
||||
do{
|
||||
command = parser.getCommand();
|
||||
if(command.equals("add")){
|
||||
add();
|
||||
}
|
||||
else if(command.equals("get")){
|
||||
get();
|
||||
}
|
||||
else if(command.equals("list")){
|
||||
list();
|
||||
}
|
||||
else if(command.equals("search")){
|
||||
find();
|
||||
}
|
||||
else if(command.equals("remove")){
|
||||
remove();
|
||||
}
|
||||
else if(command.equals("help")){
|
||||
help();
|
||||
}
|
||||
else{
|
||||
// Do nothing.
|
||||
}
|
||||
} while(!(command.equals("quit")));
|
||||
|
||||
System.out.println("Goodbye.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new entry.
|
||||
*/
|
||||
private void add()
|
||||
{
|
||||
System.out.print("Name: ");
|
||||
String name = parser.readLine();
|
||||
System.out.print("Phone: ");
|
||||
String phone = parser.readLine();
|
||||
System.out.print("Address: ");
|
||||
String address = parser.readLine();
|
||||
book.addDetails(new ContactDetails(name, phone, address));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an entry matching a key.
|
||||
*/
|
||||
private void get()
|
||||
{
|
||||
System.out.println("Type the key of the entry.");
|
||||
String key = parser.readLine();
|
||||
ContactDetails result = book.getDetails(key);
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an entry matching a key.
|
||||
*/
|
||||
private void remove()
|
||||
{
|
||||
System.out.println("Type the key of the entry.");
|
||||
String key = parser.readLine();
|
||||
book.removeDetails(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find entries matching a key prefix.
|
||||
*/
|
||||
private void find()
|
||||
{
|
||||
System.out.println("Type a prefix of the key to be found.");
|
||||
String prefix = parser.readLine();
|
||||
ContactDetails[] results = book.search(prefix);
|
||||
for(int i = 0; i < results.length; i++){
|
||||
System.out.println(results[i]);
|
||||
System.out.println("=====");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available commands.
|
||||
*/
|
||||
private void help()
|
||||
{
|
||||
parser.showCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* List the address book's contents.
|
||||
*/
|
||||
private void list()
|
||||
{
|
||||
System.out.println(book.listDetails());
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
#BlueJ class context
|
||||
comment0.params=
|
||||
comment0.target=CommandWords()
|
||||
comment0.text=\n\ Constructor\ for\ CommandWords\n
|
||||
comment1.params=aString
|
||||
comment1.target=boolean\ isCommand(java.lang.String)
|
||||
comment1.text=\n\ Check\ whether\ a\ given\ String\ is\ a\ valid\ command\ word.\n\ @param\ aString\ The\ string\ to\ be\ checked.\n\ @return\ true\ if\ it\ is\ valid,\ false\ if\ it\ isn't.\n
|
||||
comment2.params=
|
||||
comment2.target=void\ showAll()
|
||||
comment2.text=\n\ Print\ all\ valid\ commands\ to\ System.out.\n
|
||||
numComments=3
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* This class holds an enumeration of all command words known
|
||||
* to the program.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class CommandWords
|
||||
{
|
||||
// a constant array that holds all valid command words
|
||||
private static final String validCommands[] = {
|
||||
"add", "get", "search", "list", "remove", "help", "quit",
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor for CommandWords
|
||||
*/
|
||||
public CommandWords()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given String is a valid command word.
|
||||
* @param aString The string to be checked.
|
||||
* @return true if it is valid, false if it isn't.
|
||||
*/
|
||||
public boolean isCommand(String aString)
|
||||
{
|
||||
if(aString != null){
|
||||
for(int i = 0; i < validCommands.length; i++) {
|
||||
if(validCommands[i].equals(aString))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// if we get here, the string was not found in the commands
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print all valid commands to System.out.
|
||||
*/
|
||||
public void showAll()
|
||||
{
|
||||
for(String command : validCommands) {
|
||||
System.out.print(command + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
#BlueJ class context
|
||||
comment0.params=name\ phone\ address
|
||||
comment0.target=ContactDetails(java.lang.String,\ java.lang.String,\ java.lang.String)
|
||||
comment0.text=\n\ Set\ up\ the\ contact\ details.\ All\ details\ are\ trimmed\ to\ remove\n\ trailing\ white\ space.\n\ @param\ name\ The\ name.\n\ @param\ phone\ The\ phone\ number.\n\ @param\ address\ The\ address.\n\ @throws\ IllegalStateException\ If\ both\ name\ and\ phone\ are\ blank.\n
|
||||
comment1.params=
|
||||
comment1.target=java.lang.String\ getName()
|
||||
comment1.text=\n\ @return\ The\ name.\n
|
||||
comment2.params=
|
||||
comment2.target=java.lang.String\ getPhone()
|
||||
comment2.text=\n\ @return\ The\ telephone\ number.\n
|
||||
comment3.params=
|
||||
comment3.target=java.lang.String\ getAddress()
|
||||
comment3.text=\n\ @return\ The\ address.\n
|
||||
comment4.params=other
|
||||
comment4.target=boolean\ equals(java.lang.Object)
|
||||
comment4.text=\n\ Test\ for\ content\ equality\ between\ two\ objects.\n\ @param\ other\ The\ object\ to\ compare\ to\ this\ one.\n\ @return\ true\ if\ the\ argument\ object\ is\ a\ set\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ of\ contact\ details\ with\ matching\ attributes.\n
|
||||
comment5.params=otherDetails
|
||||
comment5.target=int\ compareTo(ContactDetails)
|
||||
comment5.text=\n\ Compare\ these\ details\ against\ another\ set,\ for\ the\ purpose\n\ of\ sorting.\ The\ fields\ are\ sorted\ by\ name,\ phone,\ and\ address.\n\ @param\ otherDetails\ The\ details\ to\ be\ compared\ against.\n\ @return\ a\ negative\ integer\ if\ this\ comes\ before\ the\ parameter,\n\ \ \ \ \ \ \ \ \ zero\ if\ they\ are\ equal\ and\ a\ positive\ integer\ if\ this\n\ \ \ \ \ \ \ \ \ comes\ after\ the\ second.\n
|
||||
comment6.params=
|
||||
comment6.target=java.lang.String\ toString()
|
||||
comment6.text=\n\ @return\ A\ multi-line\ string\ containing\ the\ name,\ phone,\ and\ address.\n
|
||||
comment7.params=
|
||||
comment7.target=int\ hashCode()
|
||||
comment7.text=\n\ Compute\ a\ hashcode\ using\ the\ rules\ to\ be\ found\ in\n\ "Effective\ Java",\ by\ Joshua\ Bloch.\n\ @return\ A\ hashcode\ for\ ContactDetails.\n
|
||||
numComments=8
|
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Name, address and telephone number details.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class ContactDetails implements Comparable<ContactDetails>
|
||||
{
|
||||
private String name;
|
||||
private String phone;
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* Set up the contact details. All details are trimmed to remove
|
||||
* trailing white space.
|
||||
* @param name The name.
|
||||
* @param phone The phone number.
|
||||
* @param address The address.
|
||||
* @throws IllegalStateException If both name and phone are blank.
|
||||
*/
|
||||
public ContactDetails(String name, String phone, String address)
|
||||
{
|
||||
// Use blank strings if any of the arguments is null.
|
||||
if(name == null) {
|
||||
name = "";
|
||||
}
|
||||
if(phone == null) {
|
||||
phone = "";
|
||||
}
|
||||
if(address == null) {
|
||||
address = "";
|
||||
}
|
||||
|
||||
this.name = name.trim();
|
||||
this.phone = phone.trim();
|
||||
this.address = address.trim();
|
||||
|
||||
if(this.name.isEmpty() && this.phone.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"Either the name or phone must not be blank.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The telephone number.
|
||||
*/
|
||||
public String getPhone()
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The address.
|
||||
*/
|
||||
public String getAddress()
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for content equality between two objects.
|
||||
* @param other The object to compare to this one.
|
||||
* @return true if the argument object is a set
|
||||
* of contact details with matching attributes.
|
||||
*/
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if(other instanceof ContactDetails) {
|
||||
ContactDetails otherDetails = (ContactDetails) other;
|
||||
return name.equals(otherDetails.getName()) &&
|
||||
phone.equals(otherDetails.getPhone()) &&
|
||||
address.equals(otherDetails.getAddress());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare these details against another set, for the purpose
|
||||
* of sorting. The fields are sorted by name, phone, and address.
|
||||
* @param otherDetails The details to be compared against.
|
||||
* @return a negative integer if this comes before the parameter,
|
||||
* zero if they are equal and a positive integer if this
|
||||
* comes after the second.
|
||||
*/
|
||||
public int compareTo(ContactDetails otherDetails)
|
||||
{
|
||||
int comparison = name.compareTo(otherDetails.getName());
|
||||
if(comparison != 0){
|
||||
return comparison;
|
||||
}
|
||||
comparison = phone.compareTo(otherDetails.getPhone());
|
||||
if(comparison != 0){
|
||||
return comparison;
|
||||
}
|
||||
return address.compareTo(otherDetails.getAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A multi-line string containing the name, phone, and address.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return name + "\n" + phone + "\n" + address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a hashcode using the rules to be found in
|
||||
* "Effective Java", by Joshua Bloch.
|
||||
* @return A hashcode for ContactDetails.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
int code = 17;
|
||||
code = 37 * code + name.hashCode();
|
||||
code = 37 * code + phone.hashCode();
|
||||
code = 37 * code + address.hashCode();
|
||||
return code;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
#BlueJ class context
|
||||
comment0.params=key
|
||||
comment0.target=NoMatchingDetailsException(java.lang.String)
|
||||
comment0.text=\n\ Store\ the\ details\ in\ error.\n\ @param\ key\ The\ key\ with\ no\ match.\n
|
||||
comment1.params=
|
||||
comment1.target=java.lang.String\ getKey()
|
||||
comment1.text=\n\ @return\ The\ key\ in\ error.\n
|
||||
comment2.params=
|
||||
comment2.target=java.lang.String\ toString()
|
||||
comment2.text=\n\ @return\ A\ diagnostic\ string\ containing\ the\ key\ in\ error.\n
|
||||
numComments=3
|
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Capture a key that failed to match an entry
|
||||
* in the address book.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class NoMatchingDetailsException extends Exception
|
||||
{
|
||||
// The key with no match.
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* Store the details in error.
|
||||
* @param key The key with no match.
|
||||
*/
|
||||
public NoMatchingDetailsException(String key)
|
||||
{
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The key in error.
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A diagnostic string containing the key in error.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "No details matching: " + key + " were found.";
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
#BlueJ class context
|
||||
comment0.params=
|
||||
comment0.target=Parser()
|
||||
comment1.params=
|
||||
comment1.target=java.lang.String\ getCommand()
|
||||
comment1.text=\n\ Read\ the\ next\ command\ from\ the\ user.\n\ The\ returned\ command\ will\ be\ valid.\n\ @return\ A\ valid\ command.\n
|
||||
comment2.params=
|
||||
comment2.target=void\ showCommands()
|
||||
comment2.text=\n\ Print\ out\ a\ list\ of\ valid\ command\ words.\n
|
||||
comment3.params=
|
||||
comment3.target=java.lang.String\ readLine()
|
||||
comment3.text=\n\ @return\ A\ line\ of\ text\ from\ the\ user.\n
|
||||
numComments=4
|
@@ -0,0 +1,65 @@
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* A class that reads input lines from the user.
|
||||
* Input is filtered via getCommand for valid commands.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class Parser
|
||||
{
|
||||
// Hold all valid command words.
|
||||
private CommandWords commands;
|
||||
private Scanner reader;
|
||||
|
||||
public Parser()
|
||||
{
|
||||
commands = new CommandWords();
|
||||
reader = new Scanner(System.in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the next command from the user.
|
||||
* The returned command will be valid.
|
||||
* @return A valid command.
|
||||
*/
|
||||
public String getCommand()
|
||||
{
|
||||
String command = null;
|
||||
do {
|
||||
// Print a prompt.
|
||||
System.out.print("> ");
|
||||
|
||||
String word = reader.next();
|
||||
// Discard the rest of the line.
|
||||
readLine();
|
||||
if(commands.isCommand(word)) {
|
||||
command = word;
|
||||
}
|
||||
else{
|
||||
System.out.println("Unrecognized command: " + word);
|
||||
System.out.print("Valid commands are: ");
|
||||
commands.showAll();
|
||||
}
|
||||
} while(command == null);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print out a list of valid command words.
|
||||
*/
|
||||
public void showCommands()
|
||||
{
|
||||
commands.showAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A line of text from the user.
|
||||
*/
|
||||
public String readLine()
|
||||
{
|
||||
return reader.nextLine();
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
Project: address-book-v3t
|
||||
Authors: David J. Barnes and Michael Kölling
|
||||
|
||||
This project is part of the material for chapter 12 of the book
|
||||
|
||||
Objects First with Java - A Practical Introduction using BlueJ
|
||||
Sixth edition
|
||||
David J. Barnes and Michael Kölling
|
||||
Pearson Education, 2016
|
||||
|
||||
A simple address-book implementation.
|
||||
This version includes some argument-validity checking.
|
||||
|
||||
How to start this project:
|
||||
Either: Create an AddressBook object and add
|
||||
contact details (such as name, address, and phone) to it.
|
||||
Or: create an AddressBookDemo and call its showInterface method.
|
||||
This will create a sample AddressBook along with a text
|
||||
interface for the purposes of interactive experimentation.
|
@@ -0,0 +1,131 @@
|
||||
#BlueJ package file
|
||||
dependency1.from=Parser
|
||||
dependency1.to=CommandWords
|
||||
dependency1.type=UsesDependency
|
||||
dependency2.from=AddressBook
|
||||
dependency2.to=ContactDetails
|
||||
dependency2.type=UsesDependency
|
||||
dependency3.from=AddressBookDemo
|
||||
dependency3.to=AddressBook
|
||||
dependency3.type=UsesDependency
|
||||
dependency4.from=AddressBookDemo
|
||||
dependency4.to=AddressBookTextInterface
|
||||
dependency4.type=UsesDependency
|
||||
dependency5.from=AddressBookDemo
|
||||
dependency5.to=ContactDetails
|
||||
dependency5.type=UsesDependency
|
||||
dependency6.from=AddressBookTextInterface
|
||||
dependency6.to=AddressBook
|
||||
dependency6.type=UsesDependency
|
||||
dependency7.from=AddressBookTextInterface
|
||||
dependency7.to=Parser
|
||||
dependency7.type=UsesDependency
|
||||
dependency8.from=AddressBookTextInterface
|
||||
dependency8.to=ContactDetails
|
||||
dependency8.type=UsesDependency
|
||||
objectbench.height=76
|
||||
objectbench.width=949
|
||||
package.editor.height=500
|
||||
package.editor.width=841
|
||||
package.editor.x=70
|
||||
package.editor.y=80
|
||||
package.numDependencies=8
|
||||
package.numTargets=7
|
||||
package.showExtends=true
|
||||
package.showUses=true
|
||||
project.charset=UTF-8
|
||||
readme.editor.height=588
|
||||
readme.editor.width=813
|
||||
readme.editor.x=36
|
||||
readme.editor.y=23
|
||||
target1.editor.height=735
|
||||
target1.editor.width=862
|
||||
target1.editor.x=53
|
||||
target1.editor.y=23
|
||||
target1.height=60
|
||||
target1.name=AddressBook
|
||||
target1.naviview.expanded=true
|
||||
target1.showInterface=false
|
||||
target1.type=ClassTarget
|
||||
target1.typeParameters=
|
||||
target1.width=120
|
||||
target1.x=180
|
||||
target1.y=220
|
||||
target2.editor.height=748
|
||||
target2.editor.width=826
|
||||
target2.editor.x=50
|
||||
target2.editor.y=52
|
||||
target2.height=60
|
||||
target2.name=ContactDetails
|
||||
target2.naviview.expanded=true
|
||||
target2.showInterface=false
|
||||
target2.type=ClassTarget
|
||||
target2.typeParameters=
|
||||
target2.width=130
|
||||
target2.x=280
|
||||
target2.y=340
|
||||
target3.editor.height=744
|
||||
target3.editor.width=820
|
||||
target3.editor.x=50
|
||||
target3.editor.y=56
|
||||
target3.height=60
|
||||
target3.name=AddressBookDemo
|
||||
target3.naviview.expanded=true
|
||||
target3.showInterface=false
|
||||
target3.type=ClassTarget
|
||||
target3.typeParameters=
|
||||
target3.width=130
|
||||
target3.x=90
|
||||
target3.y=30
|
||||
target4.editor.height=738
|
||||
target4.editor.width=823
|
||||
target4.editor.x=153
|
||||
target4.editor.y=42
|
||||
target4.height=60
|
||||
target4.name=NoMatchingDetailsException
|
||||
target4.naviview.expanded=true
|
||||
target4.showInterface=false
|
||||
target4.type=ClassTarget
|
||||
target4.typeParameters=
|
||||
target4.width=190
|
||||
target4.x=590
|
||||
target4.y=110
|
||||
target5.editor.height=700
|
||||
target5.editor.width=900
|
||||
target5.editor.x=37
|
||||
target5.editor.y=23
|
||||
target5.height=60
|
||||
target5.name=AddressBookTextInterface
|
||||
target5.naviview.expanded=true
|
||||
target5.showInterface=false
|
||||
target5.type=ClassTarget
|
||||
target5.typeParameters=
|
||||
target5.width=180
|
||||
target5.x=360
|
||||
target5.y=110
|
||||
target6.editor.height=730
|
||||
target6.editor.width=843
|
||||
target6.editor.x=50
|
||||
target6.editor.y=60
|
||||
target6.height=60
|
||||
target6.name=CommandWords
|
||||
target6.naviview.expanded=true
|
||||
target6.showInterface=false
|
||||
target6.type=ClassTarget
|
||||
target6.typeParameters=
|
||||
target6.width=140
|
||||
target6.x=600
|
||||
target6.y=340
|
||||
target7.editor.height=712
|
||||
target7.editor.width=845
|
||||
target7.editor.x=50
|
||||
target7.editor.y=60
|
||||
target7.height=60
|
||||
target7.name=Parser
|
||||
target7.naviview.expanded=true
|
||||
target7.showInterface=false
|
||||
target7.type=ClassTarget
|
||||
target7.typeParameters=
|
||||
target7.width=110
|
||||
target7.x=510
|
||||
target7.y=220
|
Reference in New Issue
Block a user