Шрифт:
Интервал:
Закладка:
display.setCurrent (a, AddressBookMain.get Instance ());
})
catch (RecordStoreException re)
re.printStackTrace(); Alert a = new Alert("Error retrieving record",
"Error retrieving record.", AlertType.CONFIRMATION);
a. setTimeout(Alert.FOREVER); display.setCurrent (a, this);
catch (lOException ioe)
}
ioe.printStackTrace();
}
finally
{
return numRecords;
{
public void coramandAction(Command c, Displayable d)
if (c == back)
AddressBookMain.getlnstancel). display ();
}
}
}
Метод buildRecordList() использует составление списка для получения всех записей, хранящихся в хранилище записей, а затем извлекает поле имени каждой из них, чтобы создать список всех имен. Вызов enumerateRecords () выдает RecordEnumeration, содержащий все записи. С помощью методов hasNextRecord() и nextRecord() цикл while просто извлекает имена из каждой записи и добавляет их в объект List для отображения.
Для каждой записи вы должны расшифровать байтовый массив обратно тому процессу, согласно которому вы создали запись ранее. Вы знаете, что первый элемент, имя, является string, так что вы можете преобразовать его из байтов в String. Обратите внимание, что та же самая идиома потока ввода-вывода Java используется здесь для создания DatalnputStream, который поддерживает API для легкого преобразования встроенных типов Java.
Фильтры записейСледующий пример не осуществляет поиска определенных записей. Однако существует способ, при котором вы можете использовать списки для извлечения некоторого подмножества записей хранилища. Вы можете использовать списки для вывода записей, которые удовлетворяют некоторым критериям, которые вы указали.
Первый аргумент в методе enumerateRecords() указывает фильтр записей. Фильтр является объектом, определяющим семантику соответствия записи набору критериев, которые определяют, должна ли запись включаться в набор списка.
Фильтр записей является классом, реализующим интерфейс RecordFilter, который определяется в пакете javax.microedition.rms. Этот интерфейс определяет единственный метод boolean matches (byte [] candidate). Ваш подкласс RecordFilter задает этот метод и устанавливает критерии фильтрации записей, указанных в списке всех записей хранилища записей. Метод enumerateRecords() активизирует вашу реализацию на каждой записи, извлеченной из хранилища записей.
В листинге 7.3 показан код класса SearchScreen. Java. Он ищет записи, которые начинаются с подстроки, введенной пользователем, или эквивалентные указанной пользователем строке.
Листинг 7.3. Поиск имен, которые начинаются с подстроки, введенной пользователем, использует API в классе AddressBook, определяющем семантику поиска
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStoreException;
import Java.util.Enumeration;
import Java.util.Vector;
/**
Этот класс внедряет экран, который дает возможность пользователю искать одну или несколько определенных записей в адресной книге. Пользователь вводит имя или префикс, который представляет имя одной или нескольких записей в адресной книге.
*/
public class SearchScreen extends Form
implements CommandListener
{
private static Command go =
new Command("Go", Command.SCREEN, 1);
private static Command back = new Command("Back", Command.BACK, 1);
private static SearchScreen instance; private Display display;
private AddressBookMain addressBook; private TextField keyEntry;
/**
Конструктор.
*/
public SearchScreen(}
(
super("Search for entry");
instance = this;
PersistenceDerao pDemo = PersistenceDemo.getlnstance ();
display = Display.getDisplay (pDerno);
addressBook = AddressBookMain.getlnstance ();
keyEntry = new TextField("Enter name",
null, 20, TextFieid.ANY); append(keyEntry);
addCommand(go); addCommand(back);
setCoramandListener(this);
}
/**
Возвращает один экземпляр данного класса.
Вызов данного метода до создания объекта возвращает нулевой указатель.
/**
возвращает экземпляр данного класса.
**/
public static SearchScreen getlnstance ()
return instance;) void display!)
(display.setCurrentlthis);
}
/**
Отображает данные, переданные на экран.
На самом деле этот метод передает обязанности по отображению данных экземпляру SearchResultScreen. Этот метод, однако, устанавливает новый экземпляр данного класса на текущее отображение.
Затрата выражается в Vector записей из хранилища записей адресной книги.
*/
void displaySearchResults(Vector results)
SearchResultScreen screen =
new SearchResultScreen (results);
display. setCurrenJ: (screen);
)
Создает конечный набор записей, соответствующих указанному имени.
Критерии отбора заключаются в том, что запись должна соответствовать имени, введенному пользователем в TextField «keyEntry». Этот метод задействует метод AddressBook.getMatchesByName() для применения специального фильтра, определяющего соответствие этого имени.
*/
Vector buildSearchResults()
{
AddressBook addressBook =
AddressBookMain.getInstance(). getAddressBook();
String matchKey = keyEntry.getString(); Vector results = new Vector();
try
{
RecordEnuraeration re =
addressBook.getMatchesByName(matchKey);
byte [] record = null;
while (re.hasNextElement())
record = re.nextRecord (); results.addElement(record);
}
}
catch (RecordStoreException rse)
}
rse.printStackTracet);
)
return results;
)
/**
Создает результаты поиска и отображает их на экране.
class BuildSearchResultsAction implements Runnable
{
public void run ()
Vector results = buildSearchResults ();
displaySearchResults(results);
}
}
public void commandAction(Command c, Displayable d);
if (c == go)
Runnable action = new BuildSearchResultsAction();
action.run ();
)
else if (c == beck)
}
AddressBookMain.getInstanced.display!);
}
}
}
Метод buildSearchResults() в классе SearchScreen получает список записей, вызывая метод getMatchesByName (String matchKey) в классе AddressBook. Этот метод фильтрует записи для вывода лишь тех, в которых поле имени начинается с matchKey.
Метод getMatchesByName () выполняет эту фильтрацию, пересылая фильтр записей как первый аргумент в метод enumerateRecords (). Экземпляр MatchAllNamesFilter определяет семантику фильтра для нахождения всех записей, которые начинаются с подстроки matchKey.
Метод enumerateRecords () обращается к следующему методу объекта фильтра для каждой записи в хранилище:
boolean matches(byte [] candidate)
Если в результате выводится true, он включает эту запись в набор списка. Теоретически это сходно с определением запроса SQL в системе родственных баз данных. Объект RecordFilter определяет критерии поиска.
Обратите внимание, что в листинге 7.2 аргумент RecordFilter был равен нулю. Таким образом класс RecordList может вывести все записи в списке, фильтр не применяется.
Вы можете описать несколько фильтров для поддержки поиска по различным критериям. Следуя программе листинга 7.4, вы можете определить несколько внутренних классов, которые реализуют RecordFilter и используют внутренний класс, соответствующий осуществляемому поиску.
Компараторы записейВы, несомненно, заметили, что второй аргумент, пересланный в enumerateRecords () в предыдущих примерах, был равен нулю. Этот второй параметр является «заполнителем» для компаратора записей. Компаратор записей — это объект, который сравнивает две записи для определения их упорядочивания или сортировки. Компараторы предоставляют приложениям возможность выполнять различную сортировку.
Как и фильтры, компараторы определяют семантику функции сравнения. Компаратор записей является реализацией интерфейса RecordComparator, который определяет единственный метод
int ccmparefbyte [] recordl, byte [] record2)
Компаратор также определяет три константы, описанные в таблице 7.1, которые ваша реализация должна использовать как текущие выводимые значения данного метода.
Таблица 7.1. Константы RecordComparator
Константа — Описание
public static int EQUIVALENT — Две записи эквивалентны в соответствии с семантикой сравнения
public static int FOLLOWS — Запись 1 «больше», чем запись 2, в соответствии с семантикой сравнения
public static int PRECEDES — Запись 1 «меньше», чем запись 2, в соответствии с семантикой сравнения
Идея использования компараторов сходна с понятием фильтрации записей. Вы определяете класс, который реализует интерфейс javax.microedition.rras.RecordComparator. Вы передаете его экземпляр в вызов enumerateRecords (). Записи, извлеченные из хранилища записей, сравниваются друг с другом, по две одновременно, а затем сортируются в соответствии с результатами сравнения. Вы можете таким образом извлекать записи из списка в порядке, определяемом компаратором.
В листинге 7.4 демонстрируется использование компаратора записей. Он определяет новый внутренний класс класса AddressBook, который вы видели в листинге 7.1. Новый внутренний класс AlphabeticalOrdering реализует RecordComparator. Его метод сравнения извлекает поле имени из каждого параметра байтового массива и сравнивает их лексикографически (по словам).
- Русский справочник по Win32 API - Тарас Сорока - Программирование
- 97 этюдов для архитекторов программных систем - Нил Форд - Программирование
- Программирование - Ирина Козлова - Программирование