-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAddressBook.java
More file actions
550 lines (493 loc) · 21.9 KB
/
AddressBook.java
File metadata and controls
550 lines (493 loc) · 21.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* An interactive contact address book - starter code
* CSCU9P2 assignment Spring 2022
*
* THIS STARTER CODE WORKS PARTIALLY BUT SOME METHODS REQUIRE COMPLETING - SEE FURTHER DOWN IN THIS COMMENT
*
* The contact address book contains a 'database' of names, addresses and other details
* - quite small in this version, but in principle it could be quite large.
* At any one time the details of just one of the contacts will be on display.
*
* Buttons are provided to allow the user:
* o to step forwards and backwards through the entries in the address book
* o to add a new contact
* o to delete the current or all contacts
* o to search for a contact by exact name match
* o to search for a contact by case insensitive match to any part of a name
* o to re-order the contacts in ascending name order
* o to re-order the contacts in descending name order
*
* Of course, in this exercise, the 'database' is a little unrealistic:
* the information is built-in to the program (whereas in a 'serious' system it would,
* perhaps, be read in from a file).
*
* *** TO BE DONE: ***
* The navigation buttons function correctly.
* The add new contact button is ALMOST CORRECT.
* The core data processing methods for the other six buttons REQUIRE COMPLETING.
*
* You should insert your student number instead of 1234567 in line 117.
*
* All other work is on the METHOD BODIES BELOW line 445 (see /////////////////////////////):
*
* You must complete the addContact method, and implement full method bodies for
* deleteContact, clearContacts, findContact, findPartial, sortAtoZ and sortZtoA.
*
* You MUST NOT alter any other parts of the program:
* o the GUI parts are complete and correct
* o the array declarations are complete and correct
* o the method headers are complete and correct.
*
* @author
* @version 2022
*/
public class AddressBook extends JFrame implements ActionListener
{
/** Configuration: custom screen colours, layout constants and custom fonts. */
private final Color
veryLightGrey = new Color(240, 240, 240),
darkBlue = new Color(0, 0, 150),
backGroundColour = veryLightGrey,
navigationBarColour = Color.lightGray,
textColour = darkBlue;
private static final int
windowWidth = 450, windowHeight = 600, // Overall frame dimensions
windowLocationX = 200, windowLocationY = 100; // and position
private final int
panelWidth = 450, panelHeight = 250, // The drawing panel dimensions
leftMargin = 50, // All text and images start here
mainHeadingY = 30, // Main heading this far down the panel
detailsY = mainHeadingY+40, // Details display starts this far down the panel
detailsLineSep = 30; // Separation of details text lines
private final Font
mainHeadingFont = new Font("SansSerif", Font.BOLD, 20),
detailsFont = new Font("SansSerif", Font.PLAIN, 14);
/** The navigation buttons. */
private JButton
first = new JButton("|<"), // For "move to first contact" action
previous = new JButton("<"), // For "move to previous contact" action
next = new JButton(">"), // For "move to next contact" action
last = new JButton(">|"); // For "move to final contact" action
/** The action buttons */
private JButton
addContact = new JButton("Add new contact"), // To request adding a new contact
deleteContact = new JButton("Delete contact"), // To delete the currently selected contact
deleteAll = new JButton("Delete all"), // To delete all contacts
findContact = new JButton("Find exact name"), // To find contact by exact match of name
findPartial = new JButton("Find partial name"),// To find contact by partial, case insensitive match of name
sortAtoZ = new JButton("Sort A to Z"), // To request re-ordering the contact by names A to Z
sortZtoA = new JButton("Sort Z to A"); // To request re-ordering the contacts by name Z to A
/** Text fields for data entry for adding new contact and finding a contact */
private JTextField
nameField = new JTextField(20), // For entering a new name, or a name to find
addressField = new JTextField(30), // For entering a new address
mobileField = new JTextField(12), // For entering a new mobile number
emailField = new JTextField(30); // For entering a new email address
/** The contact details drawing panel. */
private JPanel contactDetails = new JPanel()
{
// paintComponent is called automatically when a screen refresh is needed
public void paintComponent(Graphics g)
{
// g is a cleared panel area
super.paintComponent(g); // Paint the panel's background
paintScreen(g); // Then the required graphics
}
};
/**
* The main program launcher for the AddressBook class.
*
* @param args The command line arguments (ignored here).
*/
/** Organizes overall set up of the address book data at launch time. */
public void setUpAddressBook()
{
// Set up the contacts' details in the database
currentSize = 0; // No contacts initially
addContact("John", "12 Cottrell Street, Stirling", "07999232321", "john@cs.isp.com");
addContact("Paul", "23 Beatle Street, London", "0033998877", "paul@paul.net");
addContact("George", "34 Beatle Street, New York", "01222 78160", "georgie@stirling.com");
addContact("Simon", "45 Pathfoot Lane, Bridge of Allan", "0999 8888", "simon@simon.net");
addContact("Leslie", "Box 3, Glasgow", "", "");
// currentSize should now be 5
// Initially selected contact - the first in the database
currentContact = 0;
} // End of setUpAddressBook
/** Sets up the graphical user interface.
*
* Some extra embedded JPanels are used to improve layout a little
*/
public void setUpGUI()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout(new FlowLayout());
window.setBackground(navigationBarColour);
// Set up the GUI buttons
// The widget order is:
// first (|<), previous (<), next (>), last (>|)
window.add(new JLabel("Navigation:"));
window.add(first);
first.addActionListener(this);
window.add(previous);
previous.addActionListener(this);
window.add(next);
next.addActionListener(this);
window.add(last);
last.addActionListener(this);
// Set up the details graphics panel
contactDetails.setPreferredSize(new Dimension(panelWidth, panelHeight));
contactDetails.setBackground(backGroundColour);
window.add(contactDetails);
// Set up action buttons
JPanel addDelPanel = new JPanel();
addDelPanel.add(addContact);
addContact.addActionListener(this);
addDelPanel.add(deleteContact);
deleteContact.addActionListener(this);
addDelPanel.add(deleteAll);
deleteAll.addActionListener(this);
window.add(addDelPanel);
JPanel findPanel = new JPanel();
findPanel.add(findContact);
findContact.addActionListener(this);
findPanel.add(findPartial);
findPartial.addActionListener(this);
window.add(findPanel);
JPanel sortPanel = new JPanel();
sortPanel.add(sortAtoZ);
sortAtoZ.addActionListener(this);
sortPanel.add(sortZtoA);
sortZtoA.addActionListener(this);
window.add(sortPanel);
// Set up text fields for data entry
// (using extra JPanels to improve layout control)
JPanel namePanel = new JPanel();
namePanel.add(new JLabel("New/find name:"));
namePanel.add(nameField);
window.add(namePanel);
JPanel addressPanel = new JPanel();
addressPanel.add(new JLabel("New address:"));
addressPanel.add(addressField);
window.add(addressPanel);
JPanel mobilePanel = new JPanel();
mobilePanel.add(new JLabel("New mobile:"));
mobilePanel.add(mobileField);
window.add(mobilePanel);
JPanel emailPanel = new JPanel();
emailPanel.add(new JLabel("New email:"));
emailPanel.add(emailField);
window.add(emailPanel);
} // End of setUpGUI
/**
* Display non-background colour areas, heading and currently selected database contact.
*
* @param g The Graphics area to be drawn on, already cleared.
*/
private void paintScreen(Graphics g)
{
// Main heading
g.setColor(textColour);
g.setFont(mainHeadingFont);
g.drawString("Contact details", leftMargin, mainHeadingY);
// Current details
displayCurrentDetails(g);
} // End of paintScreen
/**
* Display the currently selected contact.
*
* @param g The Graphics area to be drawn on.
*/
private void displayCurrentDetails(Graphics g)
{
g.setColor(textColour);
g.setFont(detailsFont);
if (currentContact == -1) // Check if no contact is selected, that is there are no contacts
g.drawString("There are no contacts", leftMargin, detailsY);
else
{ // Display selected contact
g.drawString(name[currentContact], leftMargin, detailsY);
g.drawString(address[currentContact], leftMargin, detailsY + detailsLineSep);
g.drawString("Mobile: " + mobile[currentContact], leftMargin, detailsY + 2 * detailsLineSep);
g.drawString("Email: " + email[currentContact], leftMargin, detailsY + 3 * detailsLineSep);
}
} // End of displayCurrentDetails
/**
* Handle the various button clicks.
*
* @param e Information about the button click
*/
public void actionPerformed(ActionEvent e)
{
// If first is clicked: Cause the 0th contact to become selected (or -1 if there are none)
if (e.getSource() == first)
if (currentContact >= 0)
currentContact = 0;
else
currentContact = -1;
// If previous is clicked: Cause the previous contact to become selected, if there is one
if (e.getSource() == previous && currentContact > 0)
currentContact--;
// If next is clicked: Cause the next contact to become selected, if there is one
if (e.getSource() == next && currentContact < currentSize - 1)
currentContact++;
// If last is clicked: Cause the final available contact to become selected (or -1 if there are none)
if (e.getSource() == last)
currentContact = currentSize - 1;
// Add a new contact
if (e.getSource() == addContact)
doAddContact();
// Delete the current contact
if (e.getSource() == deleteContact)
doDeleteContact();
// Delete all contacts
if (e.getSource() == deleteAll)
doDeleteAll();
// Find a contact with exact name match
if (e.getSource() == findContact)
doFindContact();
// Find a contact with partial, case insensitive name match
if (e.getSource() == findPartial)
doFindPartial();
// Re-order the contacts by name A to Z
if (e.getSource() == sortAtoZ)
doSortAtoZ();
// Re-order the contacts by name Z to A
if (e.getSource() == sortZtoA)
doSortZtoA();
// And refresh the display
repaint();
} // End of actionPerformed
/**
* Add a new contact using data from the entry text fields
*
* Only adds if the name field is not empty (other fields do not matter),
* and if there is space in the arrays.
* Pops up dialogue box giving reason if contact is not added.
* The new contact is selected immediately.
*/
private void doAddContact()
{
String newName = nameField.getText(); nameField.setText("");
String newAddress = addressField.getText(); addressField.setText("");
String newMobile = mobileField.getText(); mobileField.setText("");
String newEmail = emailField.getText(); emailField.setText("");
if (newName.length() == 0) // Check and exit if the new name is empty
{
JOptionPane.showMessageDialog(null, "No name entered");
return;
}
try{
int index = addContact(newName, newAddress, newMobile, newEmail); // index is where added, or -1
if(index==databaseSize){
JOptionPane.showMessageDialog(null, "Database Size is full!");
}
if (index == -1) // Check for success
JOptionPane.showMessageDialog(null, "No space for new name");
else
currentContact = index; // Immediately select the new contact
} // End of doAddContact
catch (ArrayIndexOutOfBoundsException e){
JOptionPane.showMessageDialog(null, "Cannot enter data Database Size is Full!");
}
}
/**
* Delete the currently selected contact
*
* If there are no contacts, then notify the user, but otherwise no action.
* Otherwise delete, and the following remaining contact becomes selected.
* If there is no following contact (that is, just deleted the highest indexed contact),
* then the previous becomes selected.
* If there is no previous (that is, just deleted contact 0), then all contacts have
* been deleted and so no contact is selected.
*/
private void doDeleteContact()
{
if (currentSize == 0) // No contacts? If so do nothing
{
JOptionPane.showMessageDialog(null, "No contacts to delete");
return;
}
deleteContact(currentContact);
// currentContact is OK as the selected contact index, unless:
if (currentContact == currentSize) // Just deleted the highest indexed contact?
currentContact--; // Adjust down to previous (or -1 if all deleted)
} // End of doDeleteContact
/**
* Delete all the contacts - clear the list
*/
private void doDeleteAll()
{
clearContacts();
currentContact = -1; // No contact selected
} // End of doDeleteAll
/**
* Search for the contact whose name is an exact match to the name given in the name text field.
*
* The search name must not be empty.
* If found then the contact becomes selected.
* If not found then the user is notified, and the selected contact does not change.
*/
private void doFindContact()
{
String searchName = nameField.getText();
if (searchName.length() == 0) // Check and exit if the search name is empty
{
JOptionPane.showMessageDialog(null, "Name must not be empty");
return;
}
int location = findContact(searchName); // Location is where found, or -1
if (location == -1) // Check result: not found?
JOptionPane.showMessageDialog(null, "Name not found");
else
{
currentContact = location; // Select the found contact
nameField.setText(""); // And clear the search field
}
} // End of doFindContact
/**
* Search for the contact whose name contains the text given in the name text field,
* case insensitively.
*
* The search text must not be empty.
* If found then the contact becomes selected.
* If not found then the user is notified, and the selected contact does not change.
*/
private void doFindPartial()
{
String searchText = nameField.getText();
if (searchText.length() == 0) // Check and exit if the search text is empty
{
JOptionPane.showMessageDialog(null, "Search text must not be empty");
return;
}
int location = findPartial(searchText); // Location is where found, or -1
if (location == -1) // Check result: not found?
JOptionPane.showMessageDialog(null, "Name not found");
else
{
currentContact = location; // Select the found contact
nameField.setText(""); // And clear the search field
}
} // End of doFindPartial
/**
* Re-order the contacts in the database so that the names are in ascending alphabetic order
*
* The first contact becomes selected, provided that there is one.
*/
private void doSortAtoZ()
{
sortAtoZ();
if (currentSize > 0)
currentContact = 0; // Index of the first contact
else
currentContact = -1;
} // End of doSortAtoZ
/**
* Re-order the contacts in the database so that the names are in descending alphabetic order
*
* The first contact becomes selected, provided that there is one.
*/
private void doSortZtoA()
{
sortZtoA();
if (currentSize > 0)
currentContact = 0; // Index of the first contact
else
currentContact = -1;
} // End of doSortZtoA
//////////////////////////////////////////////////////////////////////////////////////////////
/** Maximum capacity of the database. */
private final int databaseSize = 10;
/** To hold contacts' names, addresses, etc. */
private String[]
name = new String[databaseSize],
address = new String[databaseSize],
mobile = new String[databaseSize],
email = new String[databaseSize];
/** The current number of entries - always a value in range 0 .. databaseSize.
*
* The entries are held in elements 0 .. currentSize-1 of the arrays.
*/
private int currentSize = 0;
/** To hold index of currently selected contact
*
* There is always one selected contact, unless there are no entries at all in the database.
* If there are one or more entries, then currentContact has a value in range 0 .. currentSize-1.
* If there are no entries, then currentContact is -1.
*/
private int currentContact = -1;
/**
* Add a new contact to the database in the next available location, if there is space.
*
* Return the index where added if successful, or -1 if no space so not added.
*/
private int addContact(String newName, String newAddress, String newMobile, String newEmail)
{
// TO BE DONE: Need to check if there is space available, and return -1 if not
if(currentSize==databaseSize){
}
name[currentSize] = newName; // Add data at first free element in each array
address[currentSize] = newAddress;
mobile[currentSize] = newMobile;
email[currentSize] = newEmail;
currentSize++; // Count one more contact
return currentSize-1; // Success, return where added
} // End of addContact
/**
* Delete the indicated contact from the database
*
* All contacts in subsequent (higher indexed) elements of the arrays are moved "down" to fill the "gap".
* The order of the remaining contacts is unchanged (for example, if previously sorted alphabetically,
* then so will they be after deletion).
*/
private void deleteContact(int index)
{
// TO BE DONE: Implement this method body - see comments above
} // End of deleteContact
/**
* Clear the contacts database - set to empty
*/
private void clearContacts()
{
} // End of clearContacts
/**
* Search the database for an exact match for the given name.
*
* Return the index of the match found, or -1 if no match found.
*/
private int findContact(String searchName)
{
// TO BE DONE: Implement this method body - see comments above
return -1; // Return where found or -1
} // End of findContact
/**
* Search the database for a contact whose name contains the given search text, case insensitively.
*
* Return the index of the match found, or -1 if no match found.
*/
private int findPartial(String searchText)
{
;// TO BE DONE: Implement this method body - see comments above
return -1; // Return where found or -1
} // End of findPartial
/**
* Re-order the contacts in the database so that the names are in ascending alphabetic order
*/
private void sortAtoZ()
{
// TO BE DONE: Implement this method body - see comments above
}
/**
* Re-order the contacts in the database so that the names are in descending alphabetic order
*/
private void sortZtoA()
{
// TO BE DONE: Implement this method body - see comments above
}
} // End of AddressBook