<?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="component-and-container">
    <properties>
        <title>Component &amp; Container</title>
    </properties>

    <body>
        <p>
            All Pivot components ultimately extend the base <tt>Component</tt> class. This class,
            in conjunction with the similarly abstract <tt>Container</tt> class, defines the APIs
            that specify where a component will appear on screen, what it will look like, and how a
            user will interact with it.
        </p>

        <h3>Visual and ConstrainedVisual</h3>

        <p><img src="component_and_container/visuals.png"/></p>

        <p>
            As shown in the diagram, <tt>Component</tt> implements the <tt>ConstrainedVisual</tt>
            interface. This interface extends the <tt>Visual</tt> interface, which defines methods
            common to all visual elements in Pivot. The <tt>org.apache.pivot.wtk.media.Image</tt>
            class also implements the <tt>Visual</tt> interface:
        </p>

        <p>
            <tt>public int getWidth()</tt><br/>
            <tt>public int getHeight()</tt><br/>
            <tt>public int getBaseline()</tt><br/>
            <tt>public void paint(Graphics2D graphics)</tt><br/>
        </p>

        <p>
            A visual's size (reported by the <tt>getWidth()</tt> and <tt>getHeight()</tt> methods)
            is specified in "device-independent units". Though these generally map
            one-to-one to actual pixels on an output device, they are not required to do so. This
            allows Pivot applications to be written in a resolution-independent manner, supporting
            UI scaling either for accessibility purposes or for very high resolution output devices.
        </p>

        <p>
            The <tt>getBaseline()</tt> method allows a visual to report a baseline offset, which
            is used by containers that support it to align components to a common baseline.
            The <tt>paint()</tt> method is called as needed to ensure that the visual's current
            state is correctly represented on-screen. For example, a component may need to be
            repainted when an internal value, such as a button's label, has changed, or when some
            part of the component has been exposed due to an overlapping window or other component
            having been moved or resized.
        </p>

        <p>
            <tt>ConstrainedVisual</tt> adds methods to support layout, which is discussed in more
            detail below:
        </p>

        <p>
            <tt>public void setSize(int width, int height)</tt><br/>
            <tt>public int getPreferredWidth(int height)</tt><br/>
            <tt>public int getPreferredHeight(int width)</tt><br/>
            <tt>public Dimensions getPreferredSize()</tt><br/>
            <tt>public int getBaseline(int width, int height)</tt><br/>
        </p>

        <p>
            In addition to <tt>Component</tt>, the <tt>Skin</tt> and <tt>Renderer</tt> interfaces
            also extend <tt>ConstrainedVisual</tt>. In Pivot, a component's "skin" is responsible
            for the visual representation of the component. As a result, <tt>Component</tt>
            delegates the implementation of all <tt>ConstrainedVisual</tt> methods to the skin.
            The skin may, in turn, delegate some renderering responsibility to one or more
            renderers, which are used to paint some components' content (such as a button label or
            a list item); this relationship is represented by the dotted line in the diagram.
            Renderers are often implemented as extensions of the <tt>Component</tt> class, allowing
            the component's implementation of <tt>ConstrainedVisual</tt> to be re-used (and giving
            rise to the notion of renderers as "lightweight components").
        </p>

        <p>
            Components are painted in the order in which they are defined in the parent container's
            component sequence. The component sequence thus defines the "z-order" of the components
            in the container: components are painted in ascending order, allowing higer components
            to overlap lower ones. Z-order is often only noticeable at the window level - individual
            components within an application are generally arranged such that the user can see and
            readily interact with them. This process, called "layout management", is generally
            handled automatically in a Pivot application, and is discussed next.
        </p>

        <h3>Layout</h3>

        <p>
            "Layout management" is the process of automatically determining how components should
            be arranged on screen, as opposed to requiring the the developer to explicitly set
            component size and position. Layout management is performed by all Pivot containers,
            and is the responsibility of a container's skin.
        </p>

        <p>
            <tt>ConstrainedVisual</tt>'s preferred size methods, <tt>getPreferredWidth()</tt>,
            <tt>getPreferredHeight()</tt>, and <tt>getPreferredSize()</tt>, return information
            about the size the visual "wants" to be. This is generally determined based on
            attributes such as font size and border thickness, or, in the case of containers, by
            recursively asking subcomponents about their own preferred sizes. Containers may use
            this information to determine how to arrange their subcomponents during layout.
        </p>

        <p>
            In Pivot, preferred sizes may optionally be constrained by passing a height constraint
            value to <tt>getPreferredWidth()</tt> or a width constraint value to
            <tt>getPreferredHeight()</tt>. This allows components to "wrap" their contents. For
            example, a <tt>Label</tt> component with the "wrapText" style set to <tt>true</tt> will
            report a preferred height that is tall enough to render its entire content by applying
            line break logic using the given width constraint.
        </p>

        <p>
            <tt>ConstrainedVisual</tt> defines an additional signature for <tt>getBaseline()</tt>
            that takes <tt>width</tt> and <tt>height</tt> arguments. This allows a component to
            report a constrained baseline given a possible width and height (for example, a
            label whose content is vertically aligned to bottom will report a different baseline
            than one that is vertically aligned to top when it is given more than its preferred
            height).
        </p>

        <h3>Location and Visibility</h3>

        <p>
            <tt>Component</tt> defines several additional methods that are used by containers
            during layout:
        </p>

        <p>
            <tt>public int getX()</tt><br/>
            <tt>public int getY()</tt><br/>
            <tt>public Point getLocation()</tt><br/>
            <tt>public void setLocation(int x, int y)</tt><br/>
            <tt>public final void setLocation(Point location)</tt><br/>
        </p>

        <p>
            These methods are used to manage a component's location, which is defined as an (x, y)
            coordinate pair that is relative to the origin of its parent container.
        </p>

        <p>
            <tt>public boolean isVisible()</tt><br/>
            <tt>public void setVisible(boolean visible)</tt><br/>
        </p>

        <p>
            These methods manage a component's visibility. A component that is not visible is not
            painted. Layout containers will generally also exclude non-visible components from
            layout.
        </p>

        <p>
            Container skins use the preferred size and visibility values to determine how to
            arrange their subcomponents. They first query the subcomponents for the preferred
            values, and then use these values to set the components' actual size and location. As
            a result, callers should generally not invoke the methods that set these properties
            directly, since the container is likely to override any values set by the caller
            during layout.
        </p>

        <p>
            It is important to note that containers are not required to respect a component's
            preferred size or visibility. For example, <tt>CardPane</tt> sets the size of its
            subcomponent to the maximum preferred size of all its child components, and
            <tt>TablePane</tt> sets the size of its components based on the width of its rows and
            columns. However, most respect at least one, and many respect both.
        </p>

        <h3>Disabled Components</h3>

        <p>
            A component that is "enabled" is currently capable of receiving user input. A component
            may be "disabled" to prevent it from receiving input from the user. For example,
            buttons are often disabled to prevent a user from initiating an action that would not
            be appropriate for the current state of the application. Most components display a
            disabled state to indicate to the user that interaction is currently forbidden.
        </p>

        <p>
            Note that, while a user is prevented from interacting with a disabled component,
            programmatic interaction is still allowed. For example, it is still valid to set the
            selection state of a disabled list view component in code, even though the user cannot
            click on an item in the list to change the list's selection state.
        </p>

        <p>
            Also note that disabling a container will prevent all child components of the container
            from receiving input as well. Thus, there is no need to propagate the enabled state of
            a container down to its children. When a component is either disabled or one of its
            ancestors is disabled, it is said to be "blocked".
        </p>

        <h3>Focus Management</h3>

        <p>
            A component that is eligible to receive keyboard input is said to have the "input
            focus", or simply "focus". Only one component is allowed to have the focus at any given
            time. Not all components are focusable, though many are, including text inputs, buttons,
            and list views, among others. It is up to a component's skin to decide whether or not it
            is capable of receiving focus. In order to receive the focus, a component (and its
            ancestry) must be enabled, visible, and focusable.
        </p>

        <p>
            Generally, a focusable component will paint a slightly different state when it has the
            focus as a visual cue to the user. For example, a text input may show a blinking
            cursor, while a button might draw a dotted line around its label.
        </p>

        <p>
            Clicking on a component with the mouse will usually transfer focus to that component.
            However, focus can also be transferred between using the Tab (or Shift-Tab) key. This
            is called "focus traversal". Each container provides a "focus traversal policy" that
            defines how focus management is performed within the container. By default, most
            containers use a default traversal policy that simply traverses child components in the
            order in which they appear in the container's component sequence. However, windows use
            a traversal policy that ensures that focus is never transferred out of the window
            itself; tab panes employ a similar policy. However, callers and skin developers are
            free to override these defaults and can install a custom traversal policy on any
            container.
        </p>

        <h3>Cursors</h3>

        <p>
            A component's skin will generally ensure that an appropriate cursor is displayed when
            the mouse is over the component. However, a caller may customize the component's cursor
            using the <tt>setCursor()</tt> method of <tt>Component</tt>. Valid cursor values are
            defined by the <tt>Cursor</tt> enum.
        </p>

        <h3>Styles</h3>

        <p>
            Styles are a means of customizing a component's appearance. They are implemented as
            named properties exposed by a skin via the component. For example, a label skin might
            define styles such as "font", "color", and "textDecoration", and a list view skin might
            define styles including "font", "color", "selectionColor" and
            "selectionBackgroundColor". These properties correspond directly to the Java bean
            getters and setters defined by the skin class.
        </p>

        <p>
            By design, skins are programmatically hidden from the developer; a caller interacts
            with a skin's styles via the component's style collection, an instance of
            <tt>org.apache.pivot.wtk.Component.StyleDictionary</tt> returned by
            <tt>Component#getStyles()</tt>:
        </p>

        <p>
            <tt>public Object get(String key) - returns the value of a given style</tt><br/>
            <tt>public Object put(String key, Object value) - sets a style value</tt><br/>
        </p>

        <p>
            This facilitates a loose, flexible coupling between an application and a skin: an
            application need not be tied to a particular skin implementation, and skin developers
            are free to add or remove styles without the risk of breaking existing applications.
            However, it becomes the responsibility of the caller to be aware of the styles
            supported by the current skin. Attempting to set a non-existent style value will
            simply generate a warning, but passing an invalid type for a valid style will throw
            an exception.
        </p>

        <p>
            Style values can be set in BXML using the "styles" attribute. The value of this
            attribute is a JSON-formatted string representing the style values to be applied to
            the component after it is constructed. For example, the following attribute applied to
            the Label element would produce a bold, 24-point Arial label with red text:
        </p>

        <p>
            <tt>styles="{font:'Arial bold 24', color:'#ff0000'}"</tt><br/>
        </p>

        <p>
            Styles can also be set using a <tt>&lt;styles&gt;</tt> sub-element:
        </p>

        <p>
            <tt>&lt;styles font="Arial bold 24" color="#ff0000"&gt;</tt><br/>
        </p>

        <p>
            Finally, styles can be applied via CSS-like stylesheets. Both typed and untyped
            selectors are supported. For example:
        </p>

        <source type="jscript">
        {  Button: {
                color: "#aa0000"
            },

            RadioButton: {
                color: "#00aa00"
            },

            "org.apache.pivot.wtk.PushButton": {
                color: "#0000aa"
            },

            heading: {
                font: {
                    size: "120%",
                    bold: true
                },

                color: "#000000"
            },

            subHeading: {
                font: {
                    size: "110%",
                    italic: true
                },

                color: "#666666"
            }
        }
        </source>

        <h3>Attributes</h3>

        <p>
            Attributes are a means of attaching container-specific properties to a component.
            Attributes are typed values defined by containers that support or require them. For
            example, <tt>TabPane</tt> defines a "label" attribute that allows a caller to specify
            the text that is displayed on the tab button for the component; <tt>TablePane</tt>
            defines a "rowSpan" attribute that determines how a cell is laid out. Attributes
            effectively allow a caller to "tag" a component with values that are relevant only to
            its parent container (and the container's skin).
        </p>

        <p>
            Callers can set attribute values programmatically using a static setter method of
            the <tt>Container</tt> subclass (e.g. <tt>TabPane#setLabel(Component, String)</tt>).
            Alternatively, attributes can be specified in BXML. For example, the sub-elements of
            a <tt>TabPane</tt> can provide a <tt>TabPane.label</tt> attribute to specify the value
            that should be used as the text label for that component.
         </p>

        <h3>Events</h3>

        <p>
            In GUI programming, the term "event" generally refers to a notification sent by a
            program in response to some triggering action. The trigger may have been input from
            the user, a response from a remote server, or a change in some internal state.
        </p>

        <p>
            Pivot components rely heavily on events, both to respond to change notifications from
            data models or other components and to notify external listeners of changes to their
            own states. Each concrete component class defines a set of events specific to its own
            implementation, and all components inherit a set of common events defined by the base
            <tt>Component</tt> and <tt>Container</tt> classes.
        </p>

        <p>
            Events are often placed into groups that share some common
            characteristics. For example, <tt>Component</tt> defines a set of mouse button events
            that include "mouse down", "mouse up", and "mouse click". Components maintain a list
            of listeners who have registered interest in a particular group of events, and each
            listener is notified, in turn, as events occur.
        </p>

        <p>
            Event listeners implement a listener interface defined for a particular group. For
            example, component mouse listeners implement the ComponentMouseListener interface,
            which defines the following methods:
        </p>

        <p>
            <tt>public void mouseMove(Component component, int x, int y)</tt><br/>
            <tt>public void mouseOver(Component component)</tt><br/>
            <tt>public void mouseOut(Component component)</tt><br/>
        </p>

        <p>
            A caller that implements the <tt>ComponentMouseListener</tt> interface can add itself
            as a listener by calling <tt>Component#getComponentMouseListeners().add()</tt>.
            Conversely, a listener can remove itself via the
            <tt>Component#getComponentMouseButtonListeners().remove()</tt> method. Other event
            listeners are registered and unregistered similarly.
        </p>

        <p>
            <tt>Component</tt> defines the following event listener interfaces that are inherited
            by all component subclasses:
        </p>

        <ul>
            <li>
                <p>
                    <b>ComponentListener</b> - defines events related to core component properties
                    including location, size, visibility, etc.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentStateListener</b> - defines events related to component enabled and
                    focus state.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentStyleListener</b> - defines events related to component
                    styles.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentDecoratorListener</b> - defines events related to component
                    decorators.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentMouseListener</b> - defines events that are fired when the mouse
                    is positioned over the component.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentMouseButtonListener</b> - defines mouse button events.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentMouseWheelListener</b> - defines mouse wheel events.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentKeyListener</b> - defines events that are fired when the component
                    has the input focus.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentTooltipListener</b> - defines events that are related to component
                    tooltips.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentDataListener</b> - defines events that are fired when component
                    user data changes.
                </p>
            </li>
            <li>
                <p>
                    <b>ComponentClassListener</b> - defines events that are fired when class-level
                    component properties change.
                </p>
            </li>
        </ul>

        <p>
            The <tt>Container</tt> class defines the following additional events that are inherited
            by its subclasses:
        </p>

        <ul>
            <li>
                <p>
                    <b>ContainerListener</b> - defines events related to core container properties
                    including insertion/removal of components.
                </p>
            </li>
            <li>
                <p>
                    <b>ContainerMouseListener</b> - defines events that are fired when the mouse
                    is positioned over the container.
                </p>
            </li>
        </ul>

        <p>
            Note that both <tt>Component</tt> and <tt>Container</tt> define interfaces related to
            mouse events. Container mouse events are "tunneling" events, and are fired as an event
            is propagated down the container hierarchy, whereas component mouse events are
            "bubbling" events, and are fired as the event moves up the container hierarchy. In
            other words, the parent of a component will receive a container mouse event before the
            component does, but the component will recieve a component mouse event before its
            parent does.
        </p>

        <p>
            Tunneling and bubbling events can be "consumed" by a listener. When a tunneling event
            is consumed, it will not be propagated further down the component hierarchy.
            Conversely, when a bubbling event is consumed, it will not be propagated further up
            the hierarchy. This allows a caller to prevent a descendant from receiving a tunneling
            event or an ancestor from receiving a bubbling event. Note, however, that it does
            not prevent other listeners at the same level in the hierarchy from receiving the event.
            Consuming an event only prevents it from progressing further up or down the hierarchy.
        </p>
    </body>
</document>
