Статьи

Pivot: практический пример, часть 2 — обработка событий

Это вторая из пяти статей, в которых рассказывается о реализации простого, но практичного приложения Pivot под названием Stock Tracker . В предыдущей статье обсуждалось создание пользовательского интерфейса с использованием WTKX, языка разметки Pivot XML. Этот раздел посвящен обработке событий. В следующей статье будут рассмотрены «веб-запросы», родные средства связи Pivot с удаленными службами данных.

Файлы WTKX не содержат никакого кода — вся логика в приложении Pivot реализована на Java. Большая часть этой логики выполняется в ответ на «событие», инициируемое некоторым внешним источником, таким как пользовательский ввод или завершение асинхронной операции, выполняющейся в фоновом потоке.

В общем случае приложение Pivot загружает свой пользовательский интерфейс и подключает обработчики событий в методе startup () основного класса приложения. Этот метод вместе с методами shutdown () , suspend () и resume () определяется интерфейсом Application, который должны реализовывать все приложения Pivot.

Загрузка пользовательского интерфейса

Интерфейс приложения в демонстрационной версии Stock Tracker реализован классом StockTracker . Код в этом файле упоминается на протяжении всего раздела. Фрагмент кода из метода startup () StockTracker показан ниже:

ApplicationContext applicationContext = ApplicationContext.getInstance();

// Set the locale
String language = applicationContext.getProperty(LANGUAGE_PROPERTY_NAME);
locale = (language == null) ? Locale.getDefault() : new Locale(language);

// Set the application context title
ResourceBundle resourceBundle =
ResourceBundle.getBundle(StockTracker.class.getName(), locale);

applicationContext.setTitle(resourceBundle.getString("stockTracker"));

// Load the application's UI
ComponentLoader.initialize();
ComponentLoader componentLoader = new ComponentLoader(locale);

Component content = componentLoader.load("pivot/tutorials/stocktracker/stocktracker.wtkx",
getClass().getName());

Этот код делает следующее:

  • Получает ссылку на контекст приложения, одноэлементный класс, который обеспечивает доступ к ряду функций и свойств системного уровня.

  • Извлекает аргумент «langauge», который был предоставлен контексту приложения при его создании — для настольных приложений это аргумент командной строки; в браузере он передается как аргумент строки запроса или как параметр апплета

  • Создает экземпляр локали, соответствующий аргументу языка

  • Получает комплект ресурсов для текущей локали

  • Устанавливает заголовок контекста приложения (отражается в заголовке фрейма при запуске в контексте настольного приложения)

  • Создает новый загрузчик компонента, используя текущую локаль

  • Загружает пользовательский интерфейс Stock Tracker из stocktracker.wtkx

Этот последний шаг создает иерархию компонентов, определенную в файлах WTKX, и выполняет любые необходимые замены ресурсов. Результатом является новый экземпляр компонента, который может быть установлен как содержимое окна и показан пользователю.

Добавление прослушивателей событий

На данный момент весь пользовательский интерфейс был создан, но он еще не виден. Даже если бы это было так, это бы не помогло, так как обработчики событий не были добавлены. Следующее, что делает метод startup (), это добавляет несколько обработчиков событий:

stocksTableView = (TableView)componentLoader.getComponent("stocksTableView");
stocksTableView.getTableViewSelectionListeners().add(new TableViewSelectionListener() {
public void selectionChanged(TableView tableView) {
refreshDetail();
}
});
...

addSymbolButton = (Button)componentLoader.getComponent("addSymbolButton");
addSymbolButton.getButtonPressListeners().add(new ButtonPressListener() {
public void buttonPressed(Button button) {
addSymbol();
}
});
...

This code demonstrates how to obtain a reference to a component defined in a WTKX file and attach an event handler to it. Component references are retrieved from a loaded WTKX file via the getComponent() method of the ComponentLoader class. In this example, the components are defined in the top-level WTKX file, so no namespace prefix is necessary. Nested components can be retrieved using the fully qualified path (including namespaces) to the component. The sample code obtains references to two components: the table view that will contain the stock quotes and the «add symbol» button. Note that the return value of getComponent() must be cast to an appropriate type.

A caller signals its interest in a particular event by implementing an interface that defines an event handler method and adding itself as an event lister on the event source. In the example above, two event handlers are created: a selection change listener on the stock quote table view and a button press listener on the «add symbol» button. Some listener interfaces, such as those shown here, define only a single event handler method, but others define more than one and serve as a grouping of related events.

Note that, though these handlers are implemented as anonymous inner classes, this is not required — any class that implements the appropriate listener interface can register as a listener.

Displaying the Content

Finally, the application is ready to be shown. The component hierarchy loaded from the WTKX files is added to a Window and the window is opened, making the application visible and allowing the user to begin interacting with it:

window = new Window();
window.setContent(content);
window.getAttributes().put(Display.MAXIMIZED_ATTRIBUTE, Boolean.TRUE);
window.open();

refreshTable();

ApplicationContext.setInterval(new Runnable() {
public void run() {
refreshTable();
}
}, REFRESH_INTERVAL);

Component.setFocusedComponent(symbolTextInput);

The application creates an instance of the undecorated Window class, sets the content component, and opens the window. The MAXIMIZED_ATTRIBUTE of the Display class is set to true so that, when opened, the window will be sized to fit the entire display area.

The code then calls refreshTable() to load the stock quote data and sets a timer interval to reload the data every 15 seconds. Finally, it sets the focus to the symbol text input, so a user can easily add a new stock to track.