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,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\ @param\ details\ The\ replacement\ details.\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.\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\ an\ entry\ with\ the\ given\ key\ from\ the\ address\ book.\n\ @param\ key\ One\ of\ the\ keys\ of\ the\ entry\ to\ be\ removed.\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

View File

@@ -0,0 +1,143 @@
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)
{
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.
* @param details The replacement details.
*/
public void changeDetails(String oldKey,
ContactDetails details)
{
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.
* @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<>();
// 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 an entry with the given key from the address book.
* @param key One of the keys of the entry to be removed.
*/
public void removeDetails(String 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();
}
}

View File

@@ -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

View File

@@ -0,0 +1,55 @@
/**
* Provide a simple demonstration of the AddressBook class.
* Sample data is added to the address book,
* and a GUI view is provided.
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class AddressBookDemo
{
private AddressBook book;
private AddressBookGUI interact;
/**
* 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);
}
// Provide a GUI view of the address book.
interact = new AddressBookGUI(book);
}
/**
* Allow the user to interact with the address book.
*/
public void showInterface()
{
interact.setVisible(true);
}
/**
* @return The sample address book.
*/
public AddressBook getBook()
{
return book;
}
}

View File

@@ -0,0 +1,31 @@
#BlueJ class context
comment0.params=book
comment0.target=AddressBookGUI(AddressBook)
comment0.text=\n\ Create\ the\ frame\ with\ its\ panels.\n\ @param\ book\ The\ address\ book\ to\ be\ manipulated.\n
comment1.params=ev
comment1.target=void\ windowClosing(java.awt.event.WindowEvent)
comment10.params=
comment10.target=java.awt.Container\ setupListArea()
comment10.text=\n\ Set\ up\ the\ panel\ for\ listing\ the\ entries.\n\ @return\ The\ completed\ panel.\n
comment2.params=
comment2.target=void\ showWindow()
comment2.text=\n\ Show\ the\ window\ if\ it\ has\ been\ closed.\n
comment3.params=
comment3.target=java.awt.Dimension\ getPreferredSize()
comment3.text=\n\ @return\ The\ preferred\ size\ of\ this\ window.\n
comment4.params=
comment4.target=java.awt.Container\ setupDataEntry()
comment4.text=\n\ Set\ up\ the\ panel\ for\ data\ entry.\n\ @return\ The\ completed\ panel.\n
comment5.params=
comment5.target=java.awt.Container\ setupSearchArea()
comment5.text=\n\ Set\ up\ the\ panel\ for\ searching\ the\ entries.\n\ @return\ The\ completed\ panel.\n
comment6.params=ev
comment6.target=void\ changedUpdate(javax.swing.event.DocumentEvent)
comment7.params=ev
comment7.target=void\ insertUpdate(javax.swing.event.DocumentEvent)
comment8.params=ev
comment8.target=void\ removeUpdate(javax.swing.event.DocumentEvent)
comment9.params=
comment9.target=void\ research()
comment9.text=\n\ Search\ the\ address\ book\ and\ present\ the\ results\ unless\n\ the\ search\ string\ is\ empty,\ in\ which\ case\ the\ results\n\ area\ is\ cleared.\n
numComments=11

View File

@@ -0,0 +1,248 @@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
/**
* Provide a GUI view of an AddressBook.
* Different panes 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.
* The add button adds the data to the address book.
*
* One to show all the entries in the book.
*
* @author David J. Barnes and Michael Kölling.
* @version 2016.02.29
*/
public class AddressBookGUI extends JFrame
{
// Size preferences for this frame.
private static final int PREFERRED_WIDTH = 500;
private static final int PREFERRED_HEIGHT = 500;
private static final Dimension PREFERRED_SIZE =
new Dimension(PREFERRED_WIDTH,PREFERRED_HEIGHT);
// The address book to be viewed and manipulated.
private AddressBook book;
/**
* Create the frame with its panels.
* @param book The address book to be manipulated.
*/
public AddressBookGUI(AddressBook book)
{
this.book = book;
setTitle("Address Book");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev)
{
setVisible(false);
}
});
final Container contentPane = getContentPane();
JTabbedPane tabbedArea = new JTabbedPane();
tabbedArea.add("Search the Entries", setupSearchArea());
tabbedArea.add("Enter New Details", setupDataEntry());
tabbedArea.add("List the Entries", setupListArea());
contentPane.add(tabbedArea);
setSize(PREFERRED_SIZE);
}
/**
* Show the window if it has been closed.
*/
public void showWindow()
{
setVisible(true);
}
/**
* @return The preferred size of this window.
*/
public Dimension getPreferredSize()
{
return PREFERRED_SIZE;
}
/**
* Set up the panel for data entry.
* @return The completed panel.
*/
private Container setupDataEntry()
{
// Set up the name field.
Box nameLabelArea = Box.createHorizontalBox();
nameLabelArea.add(new JLabel("Name", JLabel.LEFT));
nameLabelArea.add(Box.createGlue());
final JTextField nameField = new JTextField(50);
Box nameArea = Box.createVerticalBox();
nameArea.add(nameLabelArea);
nameArea.add(nameField);
// Set up the phone number area.
Box phoneLabelArea = Box.createHorizontalBox();
phoneLabelArea.add(new JLabel("Phone", JLabel.LEFT));
phoneLabelArea.add(Box.createGlue());
final JTextField phoneField = new JTextField(50);
Box phoneArea = Box.createVerticalBox();
phoneArea.add(phoneLabelArea);
phoneArea.add(phoneField);
// Set up the address area.
Box addressLabelArea = Box.createHorizontalBox();
addressLabelArea.add(new JLabel("Address", JLabel.LEFT));
addressLabelArea.add(Box.createGlue());
Box addressArea = Box.createVerticalBox();
final JTextArea address = new JTextArea(10, 50);
addressArea.add(addressLabelArea);
addressArea.add(address);
// Layout the entry-details fields in a panel.
Box singleLineFields = Box.createVerticalBox();
singleLineFields.add(nameArea);
singleLineFields.add(phoneArea);
JPanel detailsPanel = new JPanel();
detailsPanel.setLayout(new BorderLayout());
detailsPanel.add(singleLineFields, BorderLayout.NORTH);
detailsPanel.add(addressArea, BorderLayout.CENTER);
// Set up the buttons.
JPanel buttonArea = new JPanel();
JButton add = new JButton("Add");
JButton clear = new JButton("Clear");
// Take the necessary action to add the new details.
add.addActionListener(e -> {
book.addDetails(
new ContactDetails(nameField.getText(),
phoneField.getText(),
address.getText()));
}
);
// Clear the data-entry areas.
clear.addActionListener(e -> {
nameField.setText("");
phoneField.setText("");
address.setText("");
}
);
buttonArea.add(add);
buttonArea.add(clear);
// Layout the details area above the button area.
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(detailsPanel, BorderLayout.CENTER);
panel.add(buttonArea, BorderLayout.SOUTH);
return panel;
}
/**
* Set up the panel for searching the entries.
* @return The completed panel.
*/
private Container setupSearchArea()
{
// Set up the area for entering the search string.
Box searchLabelArea = Box.createHorizontalBox();
searchLabelArea.add(new JLabel("Search", JLabel.LEFT));
searchLabelArea.add(Box.createGlue());
final JTextField searchField = new JTextField(50);
Box searchArea = Box.createHorizontalBox();
searchArea.add(searchLabelArea);
searchArea.add(searchField);
// Set up the area where the resuts will be displayed.
final JTextArea resultList = new JTextArea(10,50);
resultList.setEditable(false);
JScrollPane scrollArea =
new JScrollPane(resultList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
// Any change to the name field causes a new search of
// the address book to be made.
searchField.getDocument().addDocumentListener(new DocumentListener(){
public void changedUpdate(DocumentEvent ev)
{
research();
}
public void insertUpdate(DocumentEvent ev)
{
research();
}
public void removeUpdate(DocumentEvent ev)
{
research();
}
/**
* Search the address book and present the results unless
* the search string is empty, in which case the results
* area is cleared.
*/
private void research()
{
String searchString = searchField.getText();
StringBuilder buffer = new StringBuilder();
if(searchString.length() > 0) {
ContactDetails[] results = book.search(searchString);
for(int i = 0; i < results.length; i++) {
buffer.append(results[i]).append("\n\n");
}
}
resultList.setText(buffer.toString());
}
});
JPanel listArea = new JPanel();
listArea.setLayout(new BorderLayout());
listArea.add(searchArea, BorderLayout.NORTH);
listArea.add(scrollArea, BorderLayout.CENTER);
return listArea;
}
/**
* Set up the panel for listing the entries.
* @return The completed panel.
*/
private Container setupListArea()
{
// Set up the area where the details will be displayed.
final JTextArea details = new JTextArea(10, 50);
details.setEditable(false);
JScrollPane scrollArea =
new JScrollPane(details,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
// Set up the buttons.
JPanel buttonArea = new JPanel();
JButton list = new JButton("List");
JButton clear = new JButton("Clear");
// List all of the entries.
list.addActionListener(e -> details.setText(book.listDetails()));
// Clear the details area.
clear.addActionListener(e -> details.setText(""));
buttonArea.add(list);
buttonArea.add(clear);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(scrollArea, BorderLayout.CENTER);
panel.add(buttonArea, BorderLayout.SOUTH);
return panel;
}
}

View File

@@ -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
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

View File

@@ -0,0 +1,122 @@
/**
* 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.
*/
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();
}
/**
* @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;
}
}

View File

@@ -0,0 +1,18 @@
Project: address-book-v1g
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.
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 GUI for
the purposes of interactive experimentation.

View File

@@ -0,0 +1,86 @@
#BlueJ package file
dependency1.from=AddressBook
dependency1.to=ContactDetails
dependency1.type=UsesDependency
dependency2.from=AddressBookGUI
dependency2.to=AddressBook
dependency2.type=UsesDependency
dependency3.from=AddressBookDemo
dependency3.to=AddressBook
dependency3.type=UsesDependency
dependency4.from=AddressBookDemo
dependency4.to=AddressBookGUI
dependency4.type=UsesDependency
dependency5.from=AddressBookDemo
dependency5.to=ContactDetails
dependency5.type=UsesDependency
dependency6.from=AddressBookGUI
dependency6.to=ContactDetails
dependency6.type=UsesDependency
objectbench.height=76
objectbench.width=842
package.editor.height=444
package.editor.width=734
package.editor.x=70
package.editor.y=80
package.numDependencies=6
package.numTargets=4
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.editor.height=597
readme.editor.width=794
readme.editor.x=43
readme.editor.y=23
target1.editor.height=777
target1.editor.width=1237
target1.editor.x=43
target1.editor.y=23
target1.height=60
target1.name=AddressBookGUI
target1.naviview.expanded=false
target1.showInterface=false
target1.type=ClassTarget
target1.typeParameters=
target1.width=120
target1.x=240
target1.y=130
target2.editor.height=777
target2.editor.width=1181
target2.editor.x=43
target2.editor.y=23
target2.height=60
target2.name=AddressBook
target2.naviview.expanded=true
target2.showInterface=false
target2.type=ClassTarget
target2.typeParameters=
target2.width=110
target2.x=370
target2.y=220
target3.editor.height=700
target3.editor.width=900
target3.editor.x=86
target3.editor.y=86
target3.height=60
target3.name=ContactDetails
target3.naviview.expanded=true
target3.showInterface=false
target3.type=ClassTarget
target3.typeParameters=
target3.width=120
target3.x=510
target3.y=310
target4.editor.height=728
target4.editor.width=825
target4.editor.x=50
target4.editor.y=60
target4.height=60
target4.name=AddressBookDemo
target4.naviview.expanded=true
target4.showInterface=false
target4.type=ClassTarget
target4.typeParameters=
target4.width=130
target4.x=90
target4.y=40