<?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>
