blob: e924a6b268322ec7215b86ad7393deffcb2521cf [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<document id="stock-tracker.events">
<properties>
<title>Event Handling</title>
</properties>
<body>
<p>
While BXML is often used to declare the <i>structure</i> of an application, the
application's <i>behavior</i> is still defined in code (either Java or a JVM-compatible
scripting language). Most application logic is executed in response to an "event"
triggered by some external source, such as user input or the completion of an asynchronous
operation running in a background thread.
</p>
<h3>Loading the UI</h3>
<p>
In general, a Pivot application will load its user interface in the <tt>startup()</tt>
method of the main application class. This method, along with the <tt>shutdown()</tt>,
<tt>suspend()</tt>, and <tt>resume()</tt> methods, is defined by the <tt>Application</tt>
interface, which all Pivot applications must implement.
</p>
<p>
The <tt>StockTracker</tt> class implements the <tt>Application</tt> interface for the
Stock Tracker application. <tt>StockTracker</tt>'s <tt>startup()</tt> method is shown
below:
</p>
<source type="java">
<![CDATA[
@Override
public void startup(Display display, Map<String, String> properties) throws Exception {
String language = properties.get(LANGUAGE_KEY);
Locale locale = (language == null) ? Locale.getDefault() : new Locale(language);
Resources resources = new Resources(StockTrackerWindow.class.getName(), locale);
BXMLSerializer bxmlSerializer = new BXMLSerializer();
window = (StockTrackerWindow)bxmlSerializer.readObject(getClass().getResource("stock_tracker_window.bxml"),
resources);
window.open(display);
}
]]>
</source>
<p>
This code creates an instance of <tt>BXMLSerializer</tt> and loads the BXML source for
the main window. It then opens the main window, causing the application to appear on
the screen.
</p>
<h3>Adding Event Listeners</h3>
<p>
At this point, the application is visible and the user can begin interacting with it.
Pivot applications respond to user actions by firing "events". For example, Pivot
components fire such events as "mouse moved", "button pressed", or "selected index
changed". 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.
</p>
<p>
In the following code snippet taken from <tt>StockTrackerWindow#initialize()</tt>, two
event handlers are created: a selection change listener on the stock quote table view
and a button press listener on the Yahoo! Finance link button. The first listenener
is called when the selection changes in the quote table view, and the second when
the user clicks on the link:
</p>
<source type="java">
<![CDATA[
@Override
public void initialize(Map<String, Object> namespace, URL location, Resources resources) {
...
stocksTableView.getTableViewSelectionListeners().add(new TableViewSelectionListener.Adapter() {
@Override
public void selectedRangesChanged(TableView tableView, Sequence<Span> previousSelectedRanges) {
...
}
});
...
addSymbolButton.setAction(addSymbolAction);
removeSymbolsButton.setAction(removeSymbolsAction);
...
yahooFinanceButton.getButtonPressListeners().add(new ButtonPressListener() {
@Override
public void buttonPressed(Button button) {
...
}
});
}
]]>
</source>
<p>
Some listener interfaces, such as <tt>ButtonPressListener</tt>, define only a single
event handler method, but others (including <tt>TableViewSelectionListener</tt>) define
more than one and serve as a grouping of related events. Interfaces with multiple
handler methods generally define an inner <tt>Adapter</tt> class that can be used to
simplify subclassing, as shown above.
</p>
<p>
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. It is also possible to define listeners in script within the
BXML file itself; this is discussed in more detail in the
<a href="scripting.html">Scripting</a> section.
</p>
<h3>Actions</h3>
<p>
Though the "add symbol" and "remove symbol" operations could be performed in a button
press listener attached to their respective buttons, they have been abstracted in the
Stock Tracker example application into "actions". An action in Pivot is a class that
extends the abstract <tt>org.apache.pivot.wtk.Action</tt> class. This class defines
a single abstract <tt>perform()</tt> method that is called to invoke the action:
</p>
<source type="java">
<![CDATA[
private Action addSymbolAction = new Action(false) {
@Override
@SuppressWarnings("unchecked")
public void perform(Component source) {
...
}
};
]]>
</source>
<p>
Actions can be assigned to multiple elements within an application (for example,
to a toolbar button, a menu item, and to a keystroke combination). This allows the
same code to be executed in response to multiple user gestures without the need to
write redundant event listeners. Actions also support an enabled state that is mirrored
by any component attached to the action; this allows an application to easily manage
the set of allowed actions given the current application state.
</p>
</body>
</document>