BBjInpuDSpinner Example

USE java.util.HashMap
USE java.util.TreeSet

rem 'Obtain the instance of the BBjAPI object
let myAPI!=BBjAPI()

rem 'Open the SysGui device
SYSGUI=UNT
OPEN (SYSGUI)"X0"

rem 'Obtain the instance of the BBjSysGui object
let mySysGui!=myAPI!.getSysGui()

rem 'Set addWindow param values
X=200
Y=200
WIDTH=350
HEIGHT=250
TITLE$="Birthday Finder"

rem 'Set the current context
mySysGui!.setContext(0)

rem 'Create a window
myWindow! = mySysGui!.addWindow(X,Y,WIDTH,HEIGHT,TITLE$,$00010083$)

rem 'All our dates are in 2006
startDate = JUL(2006, 1, 1)
endDate = JUL(2006, 12, 31)

rem 'Mask in numeric precedence order
myDateMask$ = "%Y-%Mz-%Dz"

rem 'Create date range for data.
myLowDate! = myWindow!.addInputDSpinner(101, 10, 10, 100, 25, $$, myDateMask$)
if (myLowDate!.getMinimumDate() <> startDate)
    myLowDate!.setMinimumDate(startDate)
endif
if (myLowDate!.getMaximumDate() <> endDate)
    myLowDate!.setMaximumDate(endDate)
endif
myLowDate!.setValue(startDate)
if (myLowDate!.getSpinField() <> myLowDate!.MONTH)
    myLowDate!.setSpinField(myLowDate!.MONTH)
endif
myHighDate! = myWindow!.addInputDSpinner(102, 120, 10, 100, 25, $$, myDateMask$)
if (myLowDate!.getMinimumDate() <> startDate)
    myLowDate!.setMinimumDate(startDate)
endif
if (myLowDate!.getMaximumDate() <> endDate)
    myLowDate!.setMaximumDate(endDate)
endif
myHighDate!.setValue(endDate)
if (myHighDate!.getSpinField() <> myHighDate!.MONTH)
    myHighDate!.setSpinField(myHighDate!.MONTH)
endif

rem 'Create date of event
myEventDate! = myWindow!.addInputD(103, 10, 45, 100, 25, $$, myDateMask$)
myEventDate!.setText(" ")

rem 'Create edit box for event name
myEditBox! = myWindow!.addEditBox(104, 120, 45, 120, 25, $$)

rem 'Create list box for the list of valid events
myList! = myWindow!.addListBox(105, 10, 80, 140, 100, $$)

rem 'Create buttons for date range
mySqueeze! = myWindow!.addButton(106, 250, 10, 90, 25, "Squeeze")
myExpand! = myWindow!.addButton(107, 250, 45, 90, 25, "Expand")

rem 'Set callbacks
myWindow!.setCallback(myWindow!.ON_CLOSE,"APP_CLOSE")
myLowDate!.setCallback(myLowDate!.ON_SPIN, "LOW_SPIN")
myHighDate!.setCallback(myHighDate!.ON_SPIN, "HIGH_SPIN")
myList!.setCallback(myList!.ON_LIST_DOUBLE_CLICK, "SELECT_EVENT")
mySqueeze!.setCallback(mySqueeze!.ON_BUTTON_PUSH, "SQUEEZE_RANGE")
myExpand!.setCallback(myExpand!.ON_BUTTON_PUSH, "EXPAND_RANGE")

rem 'Set callbacks for fast spin response
myAPI!.setCustomEventCallback("low_spin_started", "LOW_SPIN_STARTED")
myAPI!.setCustomEventCallback("high_spin_started", "HIGH_SPIN_STARTED")

rem 'Setup data structures for events
myEvents! = new TreeSet()
myEventDates! = new HashMap()

rem 'Populate data structures and myList!
GOSUB ADD_EVENTS
GOSUB DO_FILTER
lowSpin = 0
highSpin = 0
process_events

rem 'Callback for myLowDate! ON_SPIN
LOW_SPIN:
    rem 'Get BBjSpinEvent
    ev! = myAPI!.getLastEvent()

    rem 'Get text and convert to date
    date$ = ev!.getText()
    lowDate = NUM(date$)

    rem 'Set a new minimum for myHighDate! to be our current date.
    myHighDate!.setMinimumDate(lowDate)

    rem 'while receiving spin events, keep adding to the counter
    lowSpin = lowSpin + 1

    rem 'Post custom event, which will decrement the counter until 0
    rem 'then it will update myList!
    myAPI!.postCustomEvent("low_spin_started", NULL())
return

rem 'Callback for "low_spin_started"
LOW_SPIN_STARTED:
    rem 'Decrement counter
    lowSpin = lowSpin - 1

    rem 'When it reaches zero, filter the list and reset the displayed values
    if (lowSpin = 0)
        GOSUB DO_FILTER
    endif
return

rem 'Callback for myHighDate! ON_SPIN
HIGH_SPIN:
    rem 'Get BBjSpinEvent
    ev! = myAPI!.getLastEvent()

    rem 'Get text and convert to date
    date$ = ev!.getText()
    highDate = NUM(date$)

    rem 'Set a new maximum for myLowDate! to be our current date.
    myLowDate!.setMaximumDate(highDate)

    rem 'while receiving spin events, keep adding to the counter
    highSpin = highSpin + 1

    rem 'Post custom event, which will decrement the counter until 0
    rem 'then it will update myList!
    myAPI!.postCustomEvent("high_spin_started", NULL())
return

HIGH_SPIN_STARTED:
    rem 'Decrement counter
    highSpin = highSpin - 1

    rem 'When it reaches zero, filter the list and reset the displayed values
    if (highSpin = 0)
        GOSUB DO_FILTER
    endif
return

SELECT_EVENT:
    rem 'Get the currently selected index
    index = myList!.getSelectedIndex()

    rem 'Get the event
    eventName$ = myList!.getItemAt(index)

    rem 'Get the time
    myDate = myEventDates!.get(eventName$)

    rem 'Show them in the "detail" fields
    myEditBox!.setText(eventName$)
    myEventDate!.setValue(myDate)
return

rem 'Callback for Squeeze button
SQUEEZE_RANGE:
    rem 'Get the next and previous, and spin if there's room to spin.
    nextLow = myLowDate!.getNextDate()
    prevHigh = myHighDate!.getPreviousDate()
    if (nextLow <> -1 AND prevHigh <> -1)
        rem 'Prefer squeezing higher dates, if we can only move one.
        if (nextLow < prevHigh)
            myLowDate!.spin(1)
        endif
        myHighDate!.spin(0)
    endif

    rem 'spin doesn't cause event, so we have to manually filter
    GOSUB DO_FILTER
return

rem 'Callback for Expand button
EXPAND_RANGE:
    prevLow = myLowDate!.getPreviousDate()
    nextHigh = myHighDate!.getNextDate()
    if (prevLow <> -1)
        myLowDate!.spin(0)
    endif
    if (nextHigh <> -1)
        myHighDate!.spin(1)
    endif

    rem 'spin doesn't cause event, so we have to manually filter
    GOSUB DO_FILTER
return

rem 'Callback for window close box
APP_CLOSE:
release

rem 'Subroutine to filter the contents of myList!
DO_FILTER:
    rem 'Get the ends of the sequence.
    lowDate = myLowDate!.getValue()
    highDate = myHighDate!.getValue()

    rem 'Use the TreeSet to filter the sequence by date.
    eventsFiltered! = myEvents!.subSet(STR(lowDate:myNumMask$), STR(highDate + 1:myNumMask$))

    rem 'Make a vector to set as the data for myList!
    vec! = myAPI!.makeVector()

    rem 'Iterate through and only add the events in the filtered list
    iter! = eventsFiltered!.iterator()
    maskLen = LEN(myNumMask$)
    while (iter!.hasNext())
        key$ = iter!.next()

        rem 'Strip off the date part
        key$ = key$(maskLen + 1)
        vec!.add(key$)
    wend

    rem 'Remove all the existing events and set the new ones.
    myList!.removeAllItems()
    myList!.insertItems(0, vec!)

    rem 'Don't forget to let go of the references
    vec! = NULL()
return

rem 'Subroutine to set the initial events
ADD_EVENTS:
    rem 'This mask will allow the julian to sort lexigraphically
    myNumMask$ = "0000000000"

    rem 'Add all the dates
    dummy = fnAddEvent("Jim", JUL(2006, 1, 25))
    dummy = fnAddEvent("Laura", JUL(2006, 2, 5))
    dummy = fnAddEvent("Catherine", JUL(2006, 2, 28))
    dummy = fnAddEvent("John", JUL(2006, 3, 10))
    dummy = fnAddEvent("Ian", JUL(2006, 4, 13))
    dummy = fnAddEvent("Bob", JUL(2006, 5, 7))
    dummy = fnAddEvent("Stephen", JUL(2006, 6, 28))
    dummy = fnAddEvent("Jason", JUL(2006, 7, 6))
    dummy = fnAddEvent("Edna", JUL(2006, 8, 9))
    dummy = fnAddEvent("Stephanie", JUL(2006, 9, 17))
    dummy = fnAddEvent("Tara", JUL(2006, 10, 12))
    dummy = fnAddEvent("Joe", JUL(2006, 12, 12))
return

rem 'Add a single event
DEF fnAddEvent(event$, date)

rem 'Add the events so they'll sort by date in the TreeSet
myEvents!.add(STR(date:myNumMask$) + event$)

rem 'To provide lookup by name, put the events in the eventDates! map
myEventDates!.put(event$, date)
return 0
FNEND