Application Development


Chapter 17. Understanding Application Events

Almost everything that happens during the life span of a Panther application is identified by Panther as one type of event or another. At one level, events occur as the result of user interaction with the interface—for example, pressing a push button widget, or double-clicking on a dynamic label. These events and the control strings that determine the application's response are discussed in Chapter 18, "Programming Control Strings."

This chapter initially focuses on application events that are not always connected to user actions. For example, a Panther application always starts by opening a screen. Whenever a screen opens, the same sequence of events occurs, such as initialization of the transaction manager and execution of the screen's entry function. Functionality can be associated with an event, such as screen opening, by means of various properties or by installing C or Java functions.

Your ability to control application behavior largely depends on knowing the order in which events occur and what options, or hooks, are available that allow you to intervene. This chapter describes events that typically occur during a Panther application, and the hooks that are available for each one. For purposes of this discussion, events are broadly grouped according to the following application components:

The final section of the chapter discusses these event categories in relation to user-initiated actions.

This chapter assumes that you are already familiar with the basics of Panther application development, as covered by Chapter 1, "Building a Panther Application" and the tutorial in Getting Started 2-Tier or Getting Started JetNet/Oracle Tuxedo.


Screen and Widget Events

Screens and widgets provide the foundation of a Panther application. All user interaction takes place via a client screen and its widgets; and application code is typically accessible, either directly or indirectly, through client screens or, in three-tier applications, the service components that they invoke. Thus, much of the processing that takes place in a Panther application occurs at the screen and widget level, and can be decomposed into distinct screen and widget events.

The following drawing schematically depicts screen and widget events as they occur in an application that consists of two screens, Screen1 and Screen2:

Application workflow and accompanying events consist of these steps:

  1. Screen1 opens on application startup; this triggers screen entry and widget entry events, as focus is given to the first widget on the screen, Widget1.
  2. When the user tabs out of Widget1, Panther performs validation and exit processing for Widget1, then executes widget entry for Widget2.
  3. The user opens Screen2 while Widget2 has focus. Screen2 is opened as a stacked window, so Screen2 remains visible but is focus-protected. This action causes several events:
  4. When the user exits from Screen2 and returns to Screen1, these events occur:
  5. When the user exits the application from Screen1, Panther performs validation and exit processing for the widget that has focus, then screen exit for Screen1.

Most screen and widget events can be monitored and controlled programmatically and through Panther properties. Functions that execute on events are called event functions. An event function can be installed in the application as an automatic function, which executes on all events of a given object type (screen or widget); or it can be named in an event-specific property of a given screen or widget, so it executes only for that object on a specific event. For example, an automatic screen function executes on all entry and exit events for every screen in the application; however, a function that is named in a screen's Entry Function property executes only when that screen opens or regains focus.

Properties can also be used to control validation processing or check a widget's status. For example, you can set a widget's required property to force user input; and you can check whether a widget's data has changed through its runtime mdt property.

Getting your application to behave as you wish depends on knowing the sequence in which screen and widget events occur and what options are valid for each one. The following sections discuss these events in the order of occurrence. In addition, the Panther debugger can be used to determine the sequence of events for a particular screen.

Screen Entry

Screen entry occurs when a screen opens or regains focus. Because an application begins by opening a screen as its base form, the processing that is associated with screen open provides the first—and, often, the most important—set of opportunities to determine an application's behavior. Screen exposure occurs when a screen regains focus from a screen that previously overlay it. The set of events that occur on screen exposure is a subset of the set of events that occur on screen open.

Open Events

When a screen opens, events occur in the following order:

  1. The screen's unnamed JPL procedure executes. (A public or include statement in this procedure also executes that module's unnamed JPL procedure.)
  2. Transaction manager is initialized.
  3. Automatic screen function executes.
  4. Screen entry function executes.
  5. LDB write-through occurs (if there's an open LDB).
  6. valided and mdt properties are cleared (set to PV_NO) for all data input widgets.
  7. Automatic group, grid or tab control function executes, if the first field on the screen is in a container.
  8. Group, grid or tab control entry function executes, if the first field on the screen is in a container.
  9. Automatic field function executes for the first field on the screen.
  10. Field entry function executes for the first field on the screen.
  11. Pushed keys in input stack are processed.
  12. Keyboard opens, screen displays.

All processing that should occur before the user sees the screen must take place during these steps. The nature of the processing itself dictates the specific step at which it should occur. For example, transaction manager commands can be issued only after the transaction manager is initialized (step 2).

Always allow all steps on this list to complete. Specifically, avoid opening a screen while opening another screen; doing so can prevent the original screen from completing its open processing and yield unpredictable results.

Exposure Events

At different times during an application, the active window can open another screen as a sibling or stacked window; the newly opened window overlays its caller. When the original window regains focus, screen exposure processing takes place. Screen exposure processing also occurs when a report returns to the invoking screen (refer to the runreport command).

Screen exposure processing is a subset of open processing, and consists of these steps:

  1. Automatic screen function executes.
  2. Screen entry function executes.
  3. LDB write-through occurs.
  4. Automatic field function executes (for the field that gains focus).
  5. Field entry function executes (for the field that gains focus).
  6. Pushed keys in input stack processed.
  7. Keyboard opens, screen is redrawn.

When a screen is exposed, focus returns to the last field on the screen to have had focus. If this field is in a group, grid or tab control, there will be entry events associated with the container prior to the automatic field function.

A screen's unnamed procedure executes and the transaction manager is initialized only once for a given screen, when it opens. Also, the valided and mdt properties for the screen's data input widgets are cleared (set to PV_NO) only when a screen opens. Subsequent exposures of the screen leave these properties unaffected.

Unnamed Procedure

A screen's JPL (accessed through its JPL Procedures property) is accessible to the entire screen. When the screen initially opens, its unnamed procedure—the code that precedes the first proc statement—executes first.

A screen executes its unnamed procedure only when it opens; subsequent exposures of the screen ignore this code. Thus, the unnamed procedure of an application's opening screen is the appropriate place to make public those JPL library modules that are required by the entire application or make other JPL modules available for this screen.

The public command makes these modules' procedures accessible to this and other application screens and their widgets. A public module's procedure can be named in screen or widget properties—for example, in a widget's Entry Function property—or called from other JPL procedures with the call command.

When Panther loads a public module, it loads the module's procedures into memory and executes its unnamed procedure, if any. During its life span, an application can call any named procedure in a public module, unless the module is explicitly removed from memory with the unload command.

A public module's unnamed procedure executes only once; and a module can be made public only once. (Panther ignores any public command that is issued on a module that is already public.) Thus, any code in a public module's unnamed procedure is virtually guaranteed to execute only once during the life span of an application.

The include command makes a modules' procedures accessible to the current application screen.

In general, it is good programming practice to public only the procedures that you need to be global to the entire application. Procedures specific to individual screens should be in modules that are included by the screens to which they refer.

It is suggested that you maintain JPL code in libraries for the following reasons:

Transaction Manager Initialization

The transaction manager is initialized only once for a given screen. You can issue transaction manager commands such as SELECT (via sm_tm_command) only after this step is complete. Thus, it is an error to issue this or any other transaction manager command in a screen's unnamed procedure. Use a later stage of screen open processing to issue these commands—for example, the screen's entry function.

To disable transaction manager initialization, set the screen's Root property to None.

Screen Automatic and Entry Functions

A screen's automatic function and entry function are called successively on screen entry:

Panther always executes the automatic and named entry functions on screen open. It also executes these functions on screen exposure if the setup variable EXPHIDE_OPTION is set to ON_EXPHIDE (the default). If so, the screen's automatic and entry functions are the first events to occur on screen exposure.

Panther automatically supplies two arguments to screen functions: the screen's name; and an integer bitmask that indicates the screen's current state and why the function was called. (For information on using these arguments in a JPL procedure, refer to "Passing Standard Arguments to JPL Procedures.") Screen functions can use these arguments to control execution that is specific to a given screen; or (more typically) to distinguish between screen event types.Panther provides three mnemonics that can be bit-wise AND'ed with the context argument to determine which screen event caused the screen function to be called:

For example, the following screen function code tests whether the function is called on screen open or screen exposure:

int scr_entry_func( char *scr_name, int context )
{
if( context & K_ENTRY )
{
if( context & K_EXPOSE )
{
// expose processing
}
else
{
// open processing
} } }

The following example tests if the screen is being opened for the first time, instead of just being exposed:

int scr_entry_func( char *scr_name, int context )
{
if !( context & K_EXPOSE )
{
// only the first screen open processing
} }
LDB Write-through

Panther screens can be used as vehicles for initializing and saving values on other screens. A screen that performs this background role is called a local data block, or LDB. When a screen serves as an LDB, Panther uses its data input widgets, or LDB entries, to transfer data to and from corresponding widgets on the current screen. Panther matches LDB entries and screen widgets by name. By using LDBs, applications can transfer data between screens automatically.

LDB write-through occurs on both screen open and expose events. No hook is provided to intervene in this process; however, it is important to know that any attempt before this step to set a screen widget's value is actually written to the corresponding LDB entry and so might overwrite any previous value in it. Note also that on screen open, the LDB respects initial widget data that is specified through the screen editor—for example, the value set in a push button's Label property. Initial widget data also is written to the corresponding LDB entry.

For more information about LDB processing, refer to "Using Local Data Blocks."

Clearing of Valided and Mdt Properties

Panther provides two widget-level runtime properties, valided and mdt, which are automatically cleared (set to PV_NO) on screen open for all data input widgets. In other words, when the screen first opens, all data input widgets are regarded as requiring validation and as unmodified.

A widget's valided property remains clear until it passes validation. This sets the valided property to PV_YES until the widget's data changes again.

A widget's mdt property remains clear until its data changes. Thereafter, the widget's mdt property is set to PV_YES unless it is explicitly cleared, either individually or with all data input widgets on the screen by a call to sm_cl_all_mdts.

No hook is provided to intervene in this processing; however, it is important to know that Panther sets these properties after the screen's automatic and entry functions execute and LDB write-through occurs—in other words, after the stages in which widget data is typically initialized, either from a database or LDBs. So, Panther marks as potentially invalid widgets whose initial data is probably valid. By testing both the valided and mdt properties, you can determine whether a widget actually requires validation.

For more on using the valided and mdt properties, refer to "Field Validation" and "How to Validate All Screen Widgets".

Field Automatic and Entry Functions

The automatic field function and a field's own entry function are called successively on field entry. The automatic field function is called on all field events; a field's entry function is named in the field's Entry Function property and is there fore specific to that field and event. Field entry functions are typically used for processing that should occur every time a given field gains focus.

For more information about automatic field functions, refer to "Field Functions"; for more about field event functions, refer to "Event-specific Functions and Arguments" .

Input Stack Processing

Just after Panther opens the keyboard and before it displays the screen to the user, it checks the input stack for unprocessed keys; if any are found, it pops them off the stack and processes them. You can push keys onto the input stack earlier during screen entry by calling jm_keys. Because application keys can be associated with control strings through a screen's Control Strings property, the input stack can be used to defer any processing that cannot safely be called earlier during screen entry, such as calls to open a screen.

For example, on application startup you might want to display a login screen that appears simultaneously with the application's base screen and overlays it. As noted earlier, a screen should never try to open another screen until its own open processing is complete. You can implement this behavior in two steps:

  1. In the base screen's Control Strings property, attach the appropriate control string to an unused application key. For example:
    APP1 = &login.scr
  2. At an appropriate stage of the base screen's entry processing, enter this statement:
    call jm_keys APP1

    Because a login screen appears only at application startup, this call should be made at a stage of the base screen's entry processing that is not repeated on later exposures of the same screen. The unnamed procedure of a module that the base screen makes public (in its own unnamed procedure) executes only once, so it should issue the call to open the login screen.

Now, when the application starts and opens its base screen, the call to jm_keys pushes APP1 onto the keystack, where it remains until the keyboard opens; Panther pops APP1 off the keystack and in doing so executes APP1's control string and opens the login screen as a stacked window. This done, Panther draws the display and shows both screens as if they opened simultaneously, with login.scr as the topmost, active window.

Frameset Events

Frameset event processing is described in "Cursor Movement and Window Management using Framesets" in Using the Editors.

Widget Events

Fields, or data entry widgets, can undergo three events: entry, validation, and exit. Dynamic labels are the exception to field event processing; since dynamic labels cannot be entered, they only have validation events.

The following widget types are not fields, so other exceptions in event processing apply:

Panther provides various properties that let you control entry, validation and exit processing; properties that are specific to each event are described in later sections. All three events share these features:

Automatic Field Function

All fields initially call the automatic field function if one is installed. The automatic field function must be written in C, and it must be installed via the source file funclist.c. For more information about installing an automatic field function, refer to "Field Functions."

Event-specific Functions and Arguments

Almost all widgets provide properties that let you name functions to execute on specific events—Entry Function, Validation Func, and Exit Function. Some widget types have a Control String property, which can name a function to execute on validation events.

The functions that you name in these properties can be written in JPL, in C, or in Java. If written in C, the function must be installed either as a demand field function (applicable only to data input widgets or as a prototyped function. Because they are specified using individual properties of a given widget, you can write functions that are tailored to specific widgets or events. For example, a function that should execute every time a widget gains focus should be attached to that widget's Entry Function property. For more information, refer to "Installation of Demand Widget Functions" and "Installing Prototyped Functions".

If written in Java, the Java Tag property must specify the Java event handler. If a widget has both the Java Tag and Entry Function properties specified, both types of processing will occur; first the Java event handler, then the named function. For more information, refer to Chapter 21, "Java Event Handlers and Objects."

Panther automatically supplies four arguments to any event function that is specified for a data input widget:

Panther supplies these arguments if the event function property contains only the function's name. The function can use these arguments to control execution that is specific to a given widget, or to identify widget event types—for example, to differentiate between close and hide events.

Panther also supplies arguments for grid widgets, selection groups, and tab cards. For more information, refer to "Calls from Screens and Widgets."

Field Entry

When a screen opens or is exposed, the first field that can gain focus undergoes entry processing. Thereafter, a field gains focus either because of user action such as tabbing or mouse-clicking into it, or through programmatic manipulation—for example, a call to sm_tab or sm_gofield.

Entry processing for a field can comprise two stages: first, the automatic field function (if one is installed) executes; then the field's own entry function executes. A field's entry function is a named function that you set in the field's Entry Function property. This property is available for all data input widgets such as single line text; it is also available for grid widgets and selection groups.

Field Validation

When a field loses focus or it is selected or deselected, it undergoes validation processing unless its no_validation property is set to PV_YES; the default is PV_NO. Field validation can occur as a result of various events or actions, including the following:

Avoid Unnecessary Validation

Field validation always occurs on the aforementioned events regardless of the widget's valided property setting. You can avoid unnecessary processing by checking the widget's validation state in any function that executes during validation. This JPL function tests the current field's valided property:

proc wdg_valid_func()

if ( @widget("@current")->valided )
{
return
}
else
{
//do validation processing
}

As mentioned earlier, Panther sets all widgets' valided property to PV_NO on screen open; inasmuch as a screen's entry function might initialize these widgets from database values, the valided setting might not reliably tell whether a widget's data is valid. In this case, you can also test a widget against its mdt property setting:

proc wdg_valid_func()
vars valid = @widget("@current")->valided
vars modified = @widget("@current")->mdt

if ( valid || !modified ) //data either valid or unchanged
{
return //no further processing required
}
else
{
//do validation processing
}

Note: You can also test a widget's validation and modified states by bit-wise AND'ing the VALIDED and MDT mnemonics with the fourth standard argument received by widget functions, as in this code:

proc wdg_valid_func( fldno, data, occ, context )
if( context & VALIDED || !context & MDT )...
Properties Tested During Validation

During field validation, Panther tests a field's data against a number of formatting and input property settings, in the order shown in the following table. Some fields are skipped if the field is empty or its valided property is set to PV_YES—that is, there is no data to verify or the data already passed verification.

Table 17-1 Properties tested during field validation

Property setting Skip if valid Skip if empty

required = PV_YES

y

n

must_fill = PV_YES

y

y

regular_exp = expr

y

y

minimum_value = value

y

y

maximum_value = value

y

y

Check Digit = value*

y

y

data_formatting = PV_DATE_TIME

y

y

table_lookup = expr*

y

y

data_formatting = PV_NUMERIC

y

y**

Validation Function*

n

n

Auto Field Function*

n

n

JPL Validation*

n

n

calculation

n

n

*Properties that are not accessible at runtime.

**If the field has a numeric format, the empty_format property also is tested; refer to "Defining a Numeric Format" in Using the Editors.

The JPL in a field's Validation Func and JPL Validation property must return 0 to indicate success. Other values indicate failure: a return value of 1 leaves the cursor at its last position; any other non-zero value repositions the cursor at the widget's first position.

Non-validation Events

Field validation does not typically occur when the user uses a cursor key to move out of the widget, or mouse clicks into another widget. To force validation also to occur on these events, set the application setup variable IN_VALID to OK_NOVALID. Because users expect to move freely within a GUI application screen, validation is typically suppressed until they explicitly submit the screen data—for example, by pressing a Save push button. Therefore, IN_VALID is by default set to OK_NOVALID.

Field Exit

Exit processing occurs for a field that has focus when the user moves the cursor out of the field, or the screen closes or is hidden. All methods of moving the cursor out of the field, including mouse clicking, trigger exit processing. If the exit event is also one that requires validation processing, exit processing begins only when the widget's valided property is set to PV_YES.

Exit processing for a field can comprise two stages: first, the field's own exit function executes; then the automatic field function (if one is installed) executes. A field's exit function is a named function that you set in the field's Exit Function property. This property is available for all data input fields such as single line text; it is also available for grid widgets and selection groups.

Grid Column Label Click

When a widget is a grid member, what happens when its column label is clicked depends on its Click Column Action property, which can be None, Sort or Custom.

When Click Column Action is Sort, the Sort Order should be set. The order can be Lexicographic for an alphabetic sort; Numeric for a numeric value sort; Date/Time for sort by date and time; and Custom to allow you to use your own sort function. The Sort Order Func property names this function. It can be written in JPL or can be installed as a prototyped function. The function is passed two strings to compare. The return value should be COMPARE_LESS if the first string is less than the second, COMPARE_EQUAL if the two strings are equal, COMPARE_GREATER if the first string is greater than the second or COMPARE_ERROR if an error has occurred.

When Click Column Action is Custom, a Column Click Func can be specified that will be called when the widget's column label is been clicked. This function can be written in JPL or can be installed as a prototyped function. The function is passed the object ID of the widget. Its return is ignored.

Tab Control Events

Events occur for the index tab on a tab card and for the tab card itself; the tab deck has no events. Cards in a tab deck have expose and hide events along with entry and exit events.

A tab card expose event occurs when a card becomes the topmost card in the deck and during screen entry for the topmost card in the deck, even if the tab deck is hidden. A hide event occurs when another card on the deck becomes the topmost card, when the card is deleted, or when the screen is closed.

When moving to a new topmost card, a card exit event will not precede a card hide event if a widget outside the tab deck has focus. The following drawing schematically depicts the events that would occur in this context:

Panther provides three mnemonics that can be bit-wise AND'ed with the context argument to determine which event caused the tab card's function to be called:

If all three bits are clear, the tab card hide event was called. For more information, refer to "Tab Control Functions."

Screen Exit

Screen exit occurs when a screen closes or is hidden by another screen. Because an application typically ends by closing the screen that is its base form, exit processing for this screen can perform any cleanup that the application requires, such as closing database or middleware connections. Screen hide events occur when a screen loses focus to another screen, or invokes a report by calling the runreport command. Screen hide events are a subset of close events.

When a screen closes or is hidden, the following events occur:

  1. Exit processing for the current widget, as described under "Field Exit."
  2. LDB write-through. All widget data is written to corresponding entries in active LDBs.
  3. Screen exit function executes. The screen exit function, like the screen entry function, is a named function; specify the function in the screen's Exit Function property. Screen exit functions are typically used for processing that should occur every time a screen is hidden or closed.

    The functions that you name in these properties can be written in JPL, in C, or in Java. If written in C, a screen entry function must be installed either as a demand screen function or as a prototyped function. Because they are explicitly named, you can write exit functions that are individually tailored to specific screens.

    To write screen functions in Java, you must specify an event handler class for the screen in the Java Tag property. If a screen has both the Java Tag and Entry Function properties specified, both types of processing will occur; first the Java event handler, then the named function. Panther automatically supplies the same two arguments to screen exit functions that it supplies to screen entry functions.

  4. Automatic screen function executes as described earlier. This function must be written in C.
  5. Transaction manager closes (only on screen close).

    Note: Panther always executes the screen's automatic screen function and the screen's named exit function on screen close. It also executes these functions on screen expose if setup variable EXPHIDE_OPTION is set to ON_EXPHIDE (the default).

Screen Exit Processing

Screen exit processing often tests widget data, either by forcing validation processing or by testing whether widget data has changed. However, you should not open another screen during screen exit.

How to Validate All Screen Widgets

Call sm_s_val or sm_validate which traverses the screen, testing each widget occurrence and setting its valided property to PV_YES. If it encounters an occurrence with invalid data, the function returns, posts an error message, and positions the cursor there. The valided property remains unchanged for all untested widgets.

How to Test Screen Data Changes

Call sm_tst_all_mdts which checks the mdt property for each data input widget and its occurrences. When the function encounters an occurrence that contains modified data, it returns with information that identifies the widget and occurrence number. For example, the following function alerts users to changed data on the current screen:

int dataChanged()
{
int fldno, occ, wdg;
char *nm;

fldno = sm_tst_all_mdts( &occ );
if( fldno >= 0 )
{
// get the widget's name
wdg = sm_prop_id( "@field_num(fldno)" );
nm = sm_prop_get_str( wdg, PR_NAME );
if ( sm_message_box
( "New data in "##nm##" field--Continue?",
"", SM_MB_YESNO ) == SM_IDNO )
return sm_o_gofield( fldno, occ );
}
return 1;
}

Because sm_tst_all_mdts is not callable from JPL, you must either use it in a C function, or write a wrapper function that you install as a prototyped function and call from JPL. Alternatively, you can write JPL code that traverses all screen widgets and test each one's mdt property, as in this example:

proc tst_mdts()

vars nextObj, answer, wdg, ctObjs, occ, wdgOccs, nm
vars objList = sm_list_objects_start( @screen("@current")->id )

if( objList > 0 )
{
// get the number of widgets on screen
ctObjs = sm_list_objects_count( objList )

// start traversal
for wdg = 1 while wdg <= ctObjs
{
nextObj = sm_list_objects_next( objList )
nm = @id( nextObj )-> name

// get all the occurrences of this widget
wdgOccs = @id( nextObj )-> num_occurrences

// test mdt property of each widget occurrence
for occ = 1 while occ <= wdgOccs
{
if( @id( nextObj)[occ]-> mdt )
{
if ( sm_message_box \
("New data in "##nm##" field--Continue?",\
"", SM_MB_YESNO) == SM_IDNO )
{
call sm_o_gofield \
(@id( nextObj )->fldnum, occ)
return 0
} } } } }
return 1

Closing Screens

The following actions close a screen:

Exiting an Application

You can exit an application by:

CLAPP is the Panther logical key that closes an application. For example, the following control string attached to the final screen calls jm_keys to issue the CLAPP key and a Y response to the termination message:

^jm_keys CLAPP 'Y'

Programming User-initiated Events

Table 17-2 lists common user-initiated events and the associated event hooks where application processing can be specified. This table references many widget events described under "Widget Events."

Table 17-2 Typical user events and their associated event hooks

Key/mouse events Best event hook Alternate event hooks

User enters grid

Grid FocusEntry Function property

Widget FocusEntry Function property of a grid member
Widget ValidationControl String property of a listbox in the grid
Widget ValidationValidation Function property of a listbox in the grid

User enters text widget

Widget FocusEntry Function property

Default field function

User enters text

keyfilter routine

logical keys that are mapped to physical keys

User clicks on push button

Widget ValidationControl String property

Widget ValidationValidation Function property
Widget FocusEntry Function property

User enters list box (Select Any)

Widget FocusEntry Function property

Group ValidationValidation Function property of listbox' group
Group FocusEntry Function property of listbox' group

User enters list box (Action)

Widget ValidationControl String property

Widget ValidationValidation Function property
Widget FocusEntry Function property

User double clicks

Widget ValidationDouble Click property

Screen FocusControl String property—MOUS/MDBL

User leaves field

Widget FocusExit Function property

Widget ValidationValidation Function property
Widget FocusEntry Function property of next/previous field

User leaves grid

Grid FocusExit Function property

Widget FocusExit Function property of a grid member

User clicks grid column

Widget Format/Display->Sort Order Func

Widget Format/Display->Column Click Func

User does nothing

timeout function

timer function


Transaction Manager Events

The transaction manager generates a series of events in order to fetch database data, track any modifications to that data, and update the database with any modifications. The events are divided into two levels: requests and slices.

When you call a transaction manager command, such as VIEW or SAVE, the transaction manager generates that command's requests. For the VIEW command, the request events would be PRE_VIEW, VIEW, and POST_VIEW. The transaction manager then accesses the transaction model to determine what processing to perform for each request. Since a single request could have several steps, each request can be sub-divided into slices. The transaction model also determines the processing necessary for each slice.

For more information on transaction manager operations, refer to Chapter 31, "Building a Transaction Manager Screen." For descriptions of transaction manager commands and their requests and slices, refer to Chapter 8, "Transaction Manager Commands," in Programming Guide.


Database Interface Events

Database requests can generate errors that are reported by Panther's database drivers and the database engine itself. Panther provides global variables and hook functions that can help identify and manage these errors. Default error handlers are installed to report errors from Panther's database drivers and from the database engine. You can also write and install your own error handlers. With the JetNet/ Oracle Tuxedo middleware adapter, these errors can be logged to your application server.

For full information about database error handlers, refer to Chapter 37, "Processing Application Errors."


Web Application Events

The online Web Development Guide describes the events that occur at runtime for a Panther web application. For more information, refer to Chapter 5, "Web Events," in Web Development Guide.

You can also include JavaScript or VBScript programming in your client screens for events occurring in the web browser. For more information, refer to Chapter 9, "Using JavaScript and VBScript," in Web Development Guide.


Middleware Events

In three-tier applications, the type of middleware determines the specification and type of events.

JetNet and Oracle Tuxedo Events

In JetNet and Oracle Tuxedo applications, events have been defined for service requests and as those events occur, they are forwarded to handlers for processing.

Panther provides built-in event handlers for all middleware event types. You can also write and install your own handlers in JPL or C. These handlers can perform all required processing on their own, or they can call the built-in handlers and overlay these with desired enhancements.

The following table lists event types for JetNet and Oracle Tuxedo applications:

Event type Description

advertise

A service has been advertised

exception

An error or unusual change in the normal flow of program execution

JIF_changed

The JIF has been changed

message

A client receives an unsolicited message

post_request

A service request is completed

post_service

A service completes execution

pre_request

A service request is initiated

pre_service

A service is about to begin execution

request_received

A service request is received by the server

server_exit

A server is brought down in an orderly fashion

unadvertise

A service has been unadvertised

unload

Data is received from an external source that can be written (unloaded) to Panther variables

Middleware events in JetNet and Oracle Tuxedo applications occur independently of screen and field events and transaction management events; however, their handlers can initiate actions that themselves precipitate events of these types. For example, an exception handler might respond to an error by aborting a service request, which in turn causes the transaction manager to report an error.

For more information about JetNet/Oracle Tuxedo event types and their handlers, refer to Chapter 6, "JetNet/Oracle Tuxedo Event Processing," in JetNet Guide/Oracle Tuxedo Guide.