Grid Tutorial 2 - Standard Grid Using BBjGrid Methods


For Visual PRO/5 Grid Tutorials, see Data-Aware Grid Tutorial, Standard Grid Control Tutorial 1: Display-Only Grid and Standard Grid Tutorial 2: User-Modifiable Grid.

Suggested Procedures for Using the BBjGrid Control with BBjGrid methods:

  1. Create the basic grid control using BBjWindow::addGrid.

  2. Define various grid attributes using BBjGrid methods.

  3. Set cell text using BBjGrid::setCellText(row, column, text$) or setCellText(BBjVector) using a BBjVector object. If the data has a large amount of rows and/or columns, setting cell text in response to the table update event may still be faster since it will not have to initialize the data for all cells at once. Using setCellText(BBjVector) will be faster than setCellText(row, column, text$) because less method calls are needed.

  4. Use BBjGrid::setEditable to control grid editability. If all cells should be editable, no additional action is required.
  5. Set BBjGrid::setDragAccept to enable drag-and-drop functionality when needed.

  6. Show the grid.

  7. Register Callbacks for handling events or use read record to read events. This tutorial will use Callbacks. No handling of events is required to manage data, editing, or drag and drop when the grid is in use. Although, all of the regular and notify events are supported.

    The following tutorial will create a grid that displays weather information for a week.

    The grid will be editable if the editable check box is checked and editing will begin when a cell is double-clicked. If the editable check box it is checked off, the program will display a message box showing the cell contents if a cell is double-clicked. The results of this tutorial are the same as the results from BBjGrid Tutorial 1.

  8. Setup window:

    REM Open SYSGUI Channel and Window
    LET SYSGUI=UNT
    OPEN (SYSGUI)"X0"
    REM create window with event loop for check event
    PRINT (SYSGUI)'WINDOW'(100,100,600,300,"Grid Tutorial 2",$00090083$)
  9. Retrieve BBjSysGui and BBjWindow objects.

    REM Get Window and SysGui Objects
    LET BBJ! = BBjAPI()
    LET SYSGUI! = BBJ!.getSysGui()
    LET WINDOW! = SYSGUI!.getWindow(0)
  10. Set variables and create other controls.

    REM Set true/false constants
    LET TRUE=1
    LET FALSE=0
    
    REM Initialize variables
    LET GRID=100
    LET COLID=101
    LET ROWID=102
    LET NUMROW=7
    LET NUMCOL=9
    LET CONTEXT = 0
    LET EDITABLE=TRUE
    
    PRINT (SYSGUI)'TEXT'(97,10,5,150,25,"Weather Forecast",$$)
    PRINT (SYSGUI)'FONT'(97,"",12,DEC($01$))
    PRINT (SYSGUI)'TEXT'(98,160,10,200,25,"Temperature in Degrees Fahrenheit",$$)
    REM Display a checkbox to allow Grid editing to be toggled
    LET CHECK_FLAGS$=$$
    IF EDITABLE THEN
        LET CHECK_FLAGS$=$04$
    FI
    PRINT (SYSGUI)'CHECKBOX'(99,450,5,100,25,"Grid Editable",CHECK_FLAGS$)
  11. Create the basic grid control on the window using BBjWindow::addGrid:

    REM Create grid using Object Syntax
    LET GRID!=WINDOW!.addGrid(GRID,20,30,544,230,$8856$,NUMROW,NUMCOL)
  12. Set attributes in the grid:

    GRID!.setFitToGrid(TRUE)
    REM Set some properties on the grid
    GRID!.setRowHeaderWidth(100)
  13. Set header titles using BBj Object syntax. Create a BBjVector to add the headers.

    REM Set header titles using setColumnHeaderCellText()
    REM First create a BBjVector and add header strings to it
    
    LET VECTOR!=SYSGUI!.makeVector()
    VECTOR!.add("8 AM")
    VECTOR!.add("9 AM")
    VECTOR!.add("10 AM")
    VECTOR!.add("11 AM")
    VECTOR!.add("12 PM")
    VECTOR!.add("1 PM")
    VECTOR!.add("2 PM")
    VECTOR!.add("3 PM")
    VECTOR!.add("Rain")
    GRID!.setColumnHeaderText(VECTOR!)
    
    VECTOR!.clear()
    VECTOR!.add("Sunday")
    VECTOR!.add("Monday")
    VECTOR!.add("Tuesday")
    VECTOR!.add("Wednesday")
    VECTOR!.add("Thursday")
    VECTOR!.add("Friday")
    VECTOR!.add("Saturday")
    GRID!.setRowHeaderText(VECTOR!)
  14. Set the style of the last column:

    REM set style of last column to checkbox
    GRID!.setColumnStyle(NUMCOL-1,8)
  15. Set individual cells to checked:

    REM set the style of a couple checkboxes to checked
    GRID!.setCellStyle(1,NUMCOL-1,4)
    GRID!.setCellStyle(4,NUMCOL-1,4)
  16. Set the colors of the columns. Color objects are generated using BBjSysGui::makeColor.

    REM set column colors
    FOR COL=0 TO NUMCOL-1
        IF COL<3 THEN
            LET COLOR!=BBjColor.GREEN
         ELSE
            IF COL<6 THEN
                LET COLOR!=BBjColor.YELLOW
             ELSE
                IF COL<8 THEN
                    LET COLOR!=BBjColor.RED
                 ELSE
                    LET COLOR!=BBjColor.BLUE
                 FI
             FI
         FI
        GRID!.setColumnBackColor(COL,COLOR!)
    NEXT COL
  17. Set the text in the grid cells using BBjGrid::setCellText(BBjVector):

    REM Set text in cells using setCellText(BBjVector)
    REM First load the vector. Cells are loaded in rows starting from
    REM row 0, column 0 for as many strings are in the BBjVector
    VECTOR!.clear()
    FOR ROW=0 TO NUMROW-1
        FOR COL=0 TO NUMCOL-1
            IF COL = NUMCOL-1
                buff$=""; REM no text for last col
            ELSE
                buff$=STR(50+ROW+COL)
            FI
            VECTOR!.add(buff$)
        NEXT COL
    NEXT ROW
    GRID!.setCellText(VECTOR!)
  18. Set grid properties:

    GOSUB SET_EDITABLE
    REM Set drag and drop
    GRID!.setDragAccept(TRUE)
  19. Show the grid:

    GRID!.setVisible(TRUE)
  20. Register Callbacks and begin event loop. Event loop is necessary for optional grid handling.

    REM Register callbacks to handle some events
    REM Only need to register events that we want to handle
    CALLBACK(ON_CHECK_ON,ENABLE_EDITING,CONTEXT,99)
    CALLBACK(ON_CHECK_OFF,DISABLE_EDITING,CONTEXT,99)
    CALLBACK(ON_GRID_DOUBLE_CLICK,GRID_DOUBLE_CLICKED,CONTEXT,GRID)
    CALLBACK(ON_CLOSE,EXIT,CONTEXT)
    
    REM Set event template
    DIM EVENT$:TMPL(SYSGUI)
    DIM GENERIC$:NOTICETPL(0,0); REM ' Generic Notice Template
    
    REM Process Events loop.
    REM Subroutines will get called when the registered events occur
    REM And methods will return to continue event loop
    PROCESS_EVENTS
  21. When editable check box is toggled one of these subroutines will be called. Set editability in grid.

    ENABLE_EDITING:
        EDITABLE = TRUE
        GOSUB SET_EDITABLE
    RETURN
    
    DISABLE_EDITING:
        EDITABLE = FALSE
        GOSUB SET_EDITABLE
    RETURN
  22. Cell was double clicked so that if grid is not editable, use methods to retrieve state or text in cell then display a message box indicating cell contents. BBjSysGui::getLastEventString is used to retrieve the event string that would be retrieved using READ RECORD. This allows the method to retrieve more information from the event; in this case the row and column of the clicked cell.

    GRID_DOUBLE_CLICKED:
    REM If editable, do nothing, otherwise show a window containing contents of cell
        IF EDITABLE = FALSE THEN
    REM Get contents of cell. First get event string in order to get cell clicked on
            REM Could also use GRID!.getSelectedCell()
            GOSUB GET_GRID_NOTIFY
            ROW = GRID_NOTICE.ROW
            COL = GRID_NOTICE.COL
    
            REM First check if last column
            IF COL = NUMCOL-1 THEN
                REM Get cell state (TRUE= Checked)
                CHECKED = GRID!.getCellState(ROW,COL)
                IF CHECKED = FALSE THEN
                    DISPLAY$="No rain forcasted"
                ELSE
                    DISPLAY$="Rain forecasted"
                FI
            ELSE
                REM Get cell text
                CELL$= GRID!.getCellText(ROW,COL)
                DISPLAY$="The temperature at this time will be "+CELL$+" degrees Fahrenheit"
            FI
            REM Display a message box
            LET V=MSGBOX(DISPLAY$)
        FI
    RETURN
  23. Subroutine used to set grid editability to EDITABLE:

    SET_EDITABLE:
    REM Set editability of grid
        GRID!.setEditable(EDITABLE)
    RETURN
    END
  24. Subroutine used to retrieve grid notify event info:

    GET_GRID_NOTIFY:
    REM Get last event string
    EVENT$= SYSGUI!.getLastEventString()
    LET GENERIC$=NOTICE(SYSGUI,EVENT.X%)
    DIM GRID_NOTICE$:NOTICETPL(GENERIC.OBJTYPE%,EVENT.FLAGS%)
    LET GRID_NOTICE$=GENERIC$
    RETURN
  25. Subroutine called on exit and program end handling:

    EXIT:
        RELEASE

    Complete Sample

    REM Grid Tutorial 2 - Standard Grid Using BBjGrid Methods
    
    REM Open SYSGUI Channel and Window
    LET SYSGUI=UNT
    OPEN (SYSGUI)"X0"
    REM create window with event loop for check event
    PRINT (SYSGUI)'WINDOW'(100,100,600,300,"Grid Tutorial 2",$00090083$)
    
    REM Get Window and SysGui Objects
    LET BBJ! = BBjAPI()
    LET SYSGUI! = BBJ!.getSysGui()
    LET WINDOW! = SYSGUI!.getWindow(0)
    
    REM Set true/false constants
    LET TRUE=1
    LET FALSE=0
    
    REM Initialize variables
    LET GRID=100
    LET COLID=101
    LET ROWID=102
    LET NUMROW=7
    LET NUMCOL=9
    LET CONTEXT=0
    LET EDITABLE=TRUE
    
    PRINT (SYSGUI)'TEXT'(97,10,5,150,25,"Weather Forecast",$$)
    PRINT (SYSGUI)'FONT'(97,"",12,DEC($01$))
    PRINT (SYSGUI)'TEXT'(98,160,10,200,25,"Temperature in Degrees Fahrenheit",$$)
    REM Display a checkbox to allow Grid editing to be toggled
    LET CHECK_FLAGS$=$$
    IF EDITABLE THEN
        LET CHECK_FLAGS$=$04$
    FI
    PRINT (SYSGUI)'CHECKBOX'(99,450,5,100,25,"setEditable",CHECK_FLAGS$)
    
    REM Create grid using Object Syntax
    LET GRID!=WINDOW!.addGrid(GRID,20,30,544,225,$8856$,NUMROW,NUMCOL)
    
    GRID!.setFitToGrid(TRUE)
    REM Set some properties on the grid
    GRID!.setRowHeaderWidth(100)
    GRID!.setRowHeight(25)
    
    REM Set header titles using setColumnHeaderCellText()
    REM First create a BBjVector and add header strings to it
    
    LET VECTOR!=SYSGUI!.makeVector()
    VECTOR!.add("8 AM")
    VECTOR!.add("9 AM")
    VECTOR!.add("10 AM")
    VECTOR!.add("11 AM")
    VECTOR!.add("12 PM")
    VECTOR!.add("1 PM")
    VECTOR!.add("2 PM")
    VECTOR!.add("3 PM")
    VECTOR!.add("Rain")
    GRID!.setColumnHeaderText(VECTOR!)
    
    VECTOR!.clear()
    VECTOR!.add("Sunday")
    VECTOR!.add("Monday")
    VECTOR!.add("Tuesday")
    VECTOR!.add("Wednesday")
    VECTOR!.add("Thursday")
    VECTOR!.add("Friday")
    VECTOR!.add("Saturday")
    GRID!.setRowHeaderText(VECTOR!)
    
    REM set style of last column to checkbox
    GRID!.setColumnStyle(NUMCOL-1,8)
    
    REM set column colors
    FOR COL=0 TO NUMCOL-1
        IF COL<3 THEN
            LET COLOR!=BBjColor.GREEN
         ELSE
            IF COL<6 THEN
                LET COLOR!=BBjColor.YELLOW
             ELSE
                IF COL<8 THEN
                    LET COLOR!=BBjColor.RED
                 ELSE
                    LET COLOR!=BBjColor.BLUE
                 FI
             FI
         FI
        GRID!.setColumnBackColor(COL,COLOR!)
        print color!,col
    NEXT COL
    
    REM Set text in cells using setCellText(BBjVector)
    REM First load the vector. Cells are loaded in rows starting from
    REM row 0, column 0 for as many strings are in the BBjVector
    VECTOR!.clear()
    FOR ROW=0 TO NUMROW-1
        FOR COL=0 TO NUMCOL-1
            IF COL = NUMCOL-1
                buff$=""; REM no text for last col
            ELSE
                buff$=STR(50+ROW+COL)
            FI
            VECTOR!.add(buff$)
        NEXT COL
    NEXT ROW
    GRID!.setCellText(VECTOR!)
    
    GOSUB SET_EDITABLE
    REM Set drag and drop
    GRID!.setDragAccept(TRUE)
    
    GRID!.setVisible(TRUE)
    
    REM Register callbacks to handle some events
    REM Only need to register events that we want to handle
    CALLBACK(ON_CHECK_ON,ENABLE_EDITING,CONTEXT,99)
    CALLBACK(ON_CHECK_OFF,DISABLE_EDITING,CONTEXT,99)
    CALLBACK(ON_GRID_DOUBLE_CLICK,GRID_DOUBLE_CLICKED,CONTEXT,GRID)
    CALLBACK(ON_CLOSE,EXIT,CONTEXT,0)
    
    REM Set event template
    DIM EVENT$:TMPL(SYSGUI)
    DIM GENERIC$:NOTICETPL(0,0); REM ' Generic Notice Template
    
    REM Process Events loop.
    REM Subroutines will get called when the registered events occur
    REM And methods will return to continue event loop
    PROCESS_EVENTS
    
    ENABLE_EDITING:
        EDITABLE = TRUE
        GOSUB SET_EDITABLE
    RETURN
    
    DISABLE_EDITING:
        EDITABLE = FALSE
        GOSUB SET_EDITABLE
    RETURN
    
    GRID_DOUBLE_CLICKED:
    REM If editable, do nothing, otherwise show a window containing contents of cell
        IF EDITABLE = FALSE THEN
    REM Get contents of cell. First get event string in order to get cell clicked on
            REM Could also use GRID!.getSelectedCell()
            GOSUB GET_GRID_NOTIFY
            ROW = GRID_NOTICE.ROW
            COL = GRID_NOTICE.COL
    
            REM First check if last column
            IF COL = NUMCOL-1 THEN
                REM Get cell state (TRUE= Checked)
                CHECKED = GRID!.getCellState(ROW,COL)
                IF CHECKED = FALSE THEN
                    DISPLAY$="No rain forcasted"
                ELSE
                    DISPLAY$="Rain forecasted"
                FI
            ELSE
                REM Get cell text
                CELL$= GRID!.getCellText(ROW,COL)
                DISPLAY$="The temperature at this time will be "+CELL$+" degrees Fahrenheit"
            FI
            REM Display a message box
            LET V=MSGBOX(DISPLAY$)
        FI
    RETURN
    
    SET_EDITABLE:
    REM Set editability of grid
        GRID!.setEditable(EDITABLE)
    RETURN
    
    GET_GRID_NOTIFY:
        REM Get last event string
        EVENT$=SYSGUI!.getLastEventString()
        LET GENERIC$=NOTICE(SYSGUI,EVENT.X%)
        DIM GRID_NOTICE$:NOTICETPL(GENERIC.OBJTYPE%,EVENT.FLAGS%)
        LET GRID_NOTICE$=GENERIC$
    RETURN
    
    EXIT:
        RELEASE

    Grid appearance when shown:

  26. Appearance of grid when cell edited:

    Appearance of grid after double-clicking on non-editable grid: