I ran into a bind whereby I had to sort the data read from the phones PIM. In doing this I lost the other to which each contact field was referenced to the telephone number because I made use of 2 separate vectors as illustrated below
Before sorting
Nna - +445535533
Ex - +373773737
Ab - +234575757
After sorting.(Which shouldn't be)
Ab - +445535533
Ex - +373773737
Nna - +234575757
This gives an undesired behavior since the sort removes the index to index pointer of the vectors and a selected name (in a Multiple list Box) will get a wrong number.
Alternatively,
I used a hashtable, with the intention of using the names as keys and numbers as the values.
But this pairing means duplicate names being used as keys will not be allowed. Thus I made it a i.e the phone number as keys instead.
I don't want to sound like a cry baby so I stop here for a while and so you the code with a hope u guys would understand it
MY QUESTION
1. Is there a better way/algorithm to implement this?
2. How do I implement the getSelectedItems() in such a ways that it grabs the numbers of the selected indexes of a MULTIPLE CHOICE LIST from a hashTable
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import javax.microedition.lcdui.List;
import javax.microedition.pim.Contact;
import javax.microedition.pim.ContactList;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMException;
/**
*
* @author nnanna
*/
public class LoadContacts implements Operation {
private boolean available;
private Vector telNames = new Vector();
Vector telNumbers = new Vector();
Hashtable Listcontact = new Hashtable();
private String[] names;
public Vector getTelNames() {
return telNames;
}
public Hashtable getListcontact() {
return Listcontact;
}
public void execute() {
try {
// go through all the lists
String[] allContactLists = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST);
if (allContactLists.length != 0) {
for (int i = 0; i < allContactLists.length; i++) {
System.out.println(allContactLists[i]);
System.out.println(allContactLists.length);
loadNames(allContactLists[i]);
System.out.println("Execute()");
}
} else {
available = false;
}
} catch (PIMException e) {
available = false;
} catch (SecurityException e) {
available = false;
}
}
private void loadNames(String name) throws PIMException, SecurityException {
ContactList contactList = null;
try {
contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY, name);
// First check that the fields we are interested in are supported(MODULARIZE)
if (contactList.isSupportedField(Contact.FORMATTED_NAME) && contactList.isSupportedField(Contact.TEL)) {
Enumeration items = contactList.items();
Hashtable temp = new Hashtable();
while (items.hasMoreElements()) {
Contact contact = (Contact) items.nextElement();
int telCount = contact.countValues(Contact.TEL);
int nameCount = contact.countValues(Contact.FORMATTED_NAME);
if (telCount > 0 && nameCount > 0) {
String contactName = contact.getString(Contact.FORMATTED_NAME, 0);
// go through all the phone availableContacts
for (int i = 0; i < telCount; i++) {
System.out.println("Read Telno");
int telAttributes = contact.getAttributes(Contact.TEL, i);
String telNumber = contact.getString(Contact.TEL, i);
Listcontact.put(telNumber, contactName);
temp.put(contactName, telNumber);
}
names = getSortedList();
// Listcontact = temp;
System.out.println(temp + "-------");
System.out.println(Listcontact + "*******");
shortenName(contactName, 20);
}
available = true;
}
} else {
available = false;
}
} finally {
// always close it
if (contactList != null) {
contactList.close();
}
}
}
private void shortenName(String name, int length) {
if (name.length() > length) {
name = name.substring(0, 17) + "...";
}
}
public Vector getSelectedItems(List lbx) {
boolean[] arrSel = new boolean[lbx.size()];
Vector selectedNumbers = new Vector();
int selected = lbx.getSelectedFlags(arrSel);
String selectedString;
String result = "";
for (int i = 0; i < arrSel.length; i++) {
if (arrSel[i]) {
selectedString = lbx.getString(lbx.getSelectedFlags(arrSel));
result = result + " " + i;
System.out.println(Listcontact.get(selectedString));
// System.out.println(telNumbers.elementAt(i));
}
}
return selectedNumbers;
}
private String[] sortResults(String data[]) {
RecordSorter sorter = new RecordSorter();
boolean changed = true;
while (changed) {
changed = false;
for (int j = 0; j < (data.length - 1); j++) {
String a = data[j], b = data[j + 1];
if (a != null && b != null) {
int order = sorter.compare(a.getBytes(), b.getBytes());
if (order == RecordSorter.FOLLOWS) {
changed = true;
data[j] = b;
data[j + 1] = a;
}
}
}
}
return data;
}
public String[] getNames() {
return names;
}
Vector elements = new Vector();
private String[] getValueArray(Hashtable value) {
System.out.println(Listcontact + " c");
Enumeration e = value.elements();
while (e.hasMoreElements()) {
elements.addElement(e.nextElement());
}
String[] elementsArray = new String[elements.size()];
elements.copyInto(elementsArray);
elements.removeAllElements();
System.out.println(elementsArray + " k");
return elementsArray;
}
public void getDuplicates(Vector realValue) {
Vector duplicate = new Vector();
Enumeration e = realValue.elements();
for (int i = 0; e.hasMoreElements(); i++) {
if (duplicate.isEmpty() || !duplicate.elementAt(i).equals(e.nextElement())) {
break;
} else {
duplicate.addElement(e.nextElement());
}
}
}
public String[] getSortedList() {
return sortResults(getValueArray(Listcontact));
}
}
Let me reiterate you requirement: You want a method that will sort the contacts read from native phonebook, then alphabetically sort them on name.
Following is the approach,
Replace the vectors and hash-tables in your code with a single vector, say
contactListVector
, containing elements of typeContactItem
, don't worry this class is explained below. Fundamentally the contact's name and number(s) are linked together in aContactItem
, hence you do not have to worry about there mappings which reduces the usage of redundant data structures.You can reuse the sorting algorithm on
contactListVector
by comparing the member variableContactItem.name
of the vector element. Also you can deploy different sorts on member variables numbers and/or names. Also there are lots of libraries for JavaME available that have better sorting algorithm's implemented if need be use them.I would recommend you to perform the sorting once on the
contactListVector
elements at the end of your methodloadNames(...)
maybe in the finally block triggered by some boolean variable. The current sorting call in each iteration onitems
enumeration is expensive and time consuming.Also you can serialize / deserialize the
ContactItem
thus persist your contact list.Let me know if you need detailed explanation.