Scroll Bars

Like sliders, scroll bars allow the user to interactively select from a range of values. Unlike sliders, scroll bars are used to select a sub-range rather than an individual value. The size of this sub-range is known as the scroll bar's "extent". The extent, together with the start and end values of the outer range, comprise the scroll bar's "scope", represented by the ScrollBar.Scope enum.

Visually, a scroll bar is usually presented as a scroll "handle" (sometimes called the "thumb") within a larger "track", with two buttons on either end of the track to move the handle. The track represents the outer range from which the user can select, and the size of the handle represents the scroll bar's extent.

A scroll bar's value represents the start of the selected sub-range; its value plus its extent represents the end of the sub-range. Using the visual metaphor above, the start of the handle and the end of the handle represent the bounds of the selected sub-range. Note that this means that the scroll bar's value plus its extend must never exceed its scope; doing so would mean that the scroll bar's handle would have moved outside of the track.

Finally, a scroll bar has a unit increment and a block increment. These values specify how much to adjust the scroll bar's value when a user clicks on the buttons or within the track, respectively.

Scroll bars are used within scroll panes and are most often transparent to the application developer. However, they can be used directly just like any other components. The following application uses a scroll bar to represent a simple timeline.

The BXML source for this example is shown below:

            
            <Window title="Scroll Bars" maximized="true"
                WindowStateListener.windowOpened="init();"
                xmlns:bxml="http://pivot.apache.org/bxml"
                xmlns="org.apache.pivot.wtk">
                <bxml:script src="scroll_bars.js"/>

                <Border>
                    <TablePane>
                        <columns>
                            <TablePane.Column width="1*"/>
                        </columns>

                        <TablePane.Row>
                            <FlowPane styles="{padding:6}">
                                <bxml:define>
                                    <ButtonGroup bxml:id="ranges"
                                        ButtonGroupListener.selectionChanged="updateRange();"/>
                                </bxml:define>
                                <RadioButton bxml:id="dayButton"
                                    buttonGroup="$ranges" buttonData="Day"/>
                                <RadioButton bxml:id="weekButton"
                                    buttonGroup="$ranges" buttonData="Week"/>
                                <RadioButton bxml:id="fortnightButton"
                                    buttonGroup="$ranges" buttonData="Fortnight"/>
                                <RadioButton bxml:id="monthButton"
                                    buttonGroup="$ranges" buttonData="Month"/>
                            </FlowPane>
                        </TablePane.Row>
                        <TablePane.Row height="1*">
                            <BoxPane orientation="vertical" styles="{horizontalAlignment:'center',
                                verticalAlignment:'center'}">
                                <Label bxml:id="label"/>
                            </BoxPane>
                        </TablePane.Row>
                        <TablePane.Row>
                            <ScrollBar bxml:id="scrollBar" start="0" end="60"
                                ScrollBarListener.scopeChanged="updateLabel();"
                                ScrollBarValueListener.valueChanged="updateLabel();"/>
                        </TablePane.Row>
                    </TablePane>
                </Border>
            </Window>
            
        

This example places the script code in an external JavaScript file, scroll_bars.js for readability. The source of the JavaScript is as follows:

            
            /**
             * Called when the main app window is opened.
             */
            function init() {
                ranges.selection = weekButton;
            }

            /**
             * Updates the scroll bar's extent and block increment based on the selected
             * range (in the ranges button group).
             */
            function updateRange() {
                var amount;

                if (ranges.selection == dayButton) {
                    amount = 1;
                } else if (ranges.selection == weekButton) {
                    amount = 7;
                } else if (ranges.selection == fortnightButton) {
                    amount = 14;
                } else {
                    amount = 30;
                }

                scrollBar.extent = scrollBar.unitIncrement = amount;
                scrollBar.blockIncrement = 2 * amount;
            }

            /**
             * Updates the "timeline" label based on the scroll bar's value and extent.
             */
            function updateLabel() {
                var first = scrollBar.value + 1;
                var last = scrollBar.value + scrollBar.extent;
                label.setText("Days " + first + " through " + last);
            }
            
        

Since this application is written entirely in BXML and script, there is no associated Java source.

Next: Spinners