Sunteți pe pagina 1din 19

Article

ABAP Objects in Action: Screen Programming


with the Control Framework
by Horst Keller and Gisbert Loff | SAPinsider
June 1, 2000

Share on facebookShare on twitterShare on emailShare on printMore Sharing


Services
by Horst Keller and Gisbert Loff, SAP SAPinsider - 2000 (Volume 1), June (Issue 1)

This article demonstrates how to use controls with ABAP Objects to program single-screen user interfaces. It
also takes you step-by-step through the development process and provides sample code that serves as a
starting point for creating more inviting user interfaces.
If you have attended a recent training class or SAP demonstration where SAP's "flight
model" was used as a database, you should recognize the abbreviations AA, AZ, and so
on, shown on the flight information screen in Figure 1. But compared to classical training
examples, the screen in Figure 1 is much fancier. The upper left portion shows an
airplane graphic that has no functionality - it is for visual purposes only. On the lower left
is a tree structure, from which users can select carriers or flight connections from SAP's
flight model. The third pane displays the Web site of the selected carrier or the detail lists
for flight connections.
This is just one example of the kinds of easy-to-use, easy-to-navigate interfaces that
you can provide users when you combine the strengths of GUI control technology with
ABAP Objects.
In this article, we show you how to use controls with ABAP Objects to program singlescreen user interfaces. After providing an overview of the control framework, we will take
you step by step through the development process and provide some sample code which will run in R/3 Release 4.6 - that you can use as a starting point for creating more
inviting user interfaces in your own applications.

Figure User Interface of the Flight Model Program


1

Control Technology Overview


The R/3 system communicates with the user via screens on the frontend. In classical
ABAP programming, screens may contain input/output fields, checkboxes, radio buttons,
and push buttons to interact with the user.
All user actions that raise the runtime event PAI (Process After Input) and the
respective processing on the application server are connected to a function code that is
transported to the application server.

Controls in General
Controls are independent software components that are shipped with the SAP GUI,
beginning with Release 4.5. You can place controls on screens to either replace or work
alongside classical components - both are supported in parallel. SAP currently supports
ActiveX controls for Microsoft Windows platforms and JavaBeans for the SAP GUI in the
Java environment.
Note that controls provide a great deal of functionality and can keep a lot of data at
the presentation server without putting weight on the application server (for example,
during scrolling and editing of texts). On the other hand, frequent data exchange between
the frontend and backend may increase the network load. Therefore, controls are
appropriate when most of the work can be done at the frontend and when exchange with
the backend does not occur too often.

Control Framework
In order to facilitate programming with controls, starting with Release 4.6, the SAP Basis
system provides a control framework (CFW). The CFW encapsulates all available
controls in global classes of ABAP Objects. To work with controls on your screen, simply
create objects of these global classes, call their methods, and react on their events.
Since the CFW classes are part of an inheritance hierarchy, these classes provide a

standardized interface for most of the common functionality you will find in the controls.
The CFW distinguishes between container controls and application controls. Application
controls are the components you want to use on the screen. Container controls provide a
software layer that standardizes all layout-related issues and the implementation of
application controls. All application controls must be linked to a container control while
the container control is linked to an area of the screen (see Figure 2).

Figure Container Controls and Application Controls on Screens


2
Container Controls
Container controls provide areas on the screen that can be used for application controls.
The most important container controls are encapsulated in the following global classes:

CL_GUI_CUSTOM_CONTAINER:

When you create an object of this


class, you must link it to a custom control on a screen via the IMPORTING parameter
container_name of its constructor. You can use the Screen Painter to create one or
several custom controls within the area of one screen, and you can use custom
controls together with classical screen elements. Any application control that you link
to a custom container will appear within its screen area.

CL_GUI_DOCKING_CONTAINER: When you create an object of


this class, you must link it to one of the four edges of a screen. By doing so, you
create a new area docked to a screen without using the Screen Painter. Any
application control that you link to a docking container will appear within that screen
area.

CL_GUI_SPLITTER_CONTAINER: When you create an object of


this class, you must link it to an already existing container control. By doing so, you
split the area of the existing control either vertically or horizontally into two new areas,
as was done to create the screen in Figure 1. You can then link application controls to
the new areas. You can also nest splitter controls to create more areas.

Application Controls

After creating objects of container controls, you can create objects of application controls
- the components you want to use onscreen. You must link each application control to an
object of a container control. You can do this by simply passing the respective reference
to the parameter parent of the application control's constructor. Important application
controls and their respective global classes are:

CL_GUI_ALV_GRID: This control allows you to display interactive lists.


(ALV stands for ABAP List Viewer, which replaces classical list processing.)

CL_GUI_HTML_VIEWER: This control allows you to display HTML


documents. For example, the new help viewer of the ABAP keyword documentation
uses an HTML control.

CL_GUI_PICTURE: This control allows you to display any given picture


on an R/3 screen. For example, the airplane in Figure 1 is displayed in a picture
control. SAP Easy Access is another example of a picture control as background.

CL_GUI_SIMPLE_TREE: This control allows you to display and work


with a tree structure. In addition to the simple tree, there are also other kinds of trees
available. For example, the Object Navigator of the ABAP Workbench uses a tree
control.

CL_GUI_TEXTEDIT: This control implements a full-fledged editor for


viewing and maintaining texts. For example, the ABAP Editor uses a textedit control.

Control Methods
You use the methods defined in the control's classes to work with the controls displayed
on the screen. In general, you work with the methods of the application controls. You
would use these, for example, to fill text from an internal table into the text editor of the
textedit control. But sometimes you will also call methods of the CFW. In order to
minimize the network load between backend and frontend, method calls are buffered in
an automation queue before being sent to the frontend at defined synchronization points,
such as at the end of PBO (Process Before Output) processing. To force a
synchronization point in your program, you can call the static method cl_gui_cfw=> flush.

Control Events and Event Handling


User actions on controls can trigger events. However, the events of controls are not
classical screen events, which trigger the PAI processing at the application server and
send a function code. Instead, they are declared as ABAP Objects events in their global
wrapper classes. For performance reasons, a user action on controls is not automatically
passed back to the application server. If you want an event to be passed back to the
application server, you must register it in your program using the special method
set_registered_events, which is available in all application controls. You can specify two
kinds of event handling:

System Events (default): The event is passed to the application


server, but does not trigger the PAI event (see Figure 3). In order to react on the

event, you must register an event handler method in your ABAP program with the
SET HANDLER statement. This method is then executed on the application server.
Pros and cons: The benefits of using this default technique is that the event handler
method is executed automatically. There also are no conflicts with the classical
automatic input checks associated with the screen. The disadvantage is that the
contents of the classical screen fields that might exist alongside controls are not
automatically transported to the program.

TIP: If you work


with classical
screen fields and
you really need to
transport their
contents during
control event
handling, you can
call the static
method
cl_gui_cfw=>set_
new_ok_code to
set a function
code and trigger
the PAI event,
including a field
transport. After
PAI has been
processed, the
PBO event of the
next screen is
triggered (see
Figure 3).

Figure Handling of System Events


3
Application Events: With this second type of event handling, the event is
passed to the application server and triggers the PAI (see Figure 4). If you want to
handle the event, you must include a method call for cl_gui_cfw=>dispatch in an
appropriate PAI dialog module. The dispatch method calls all event handler methods
that are defined and registered with the SET HANDLER statement for that event.
After the event handler has been processed, control returns to the PAI module and
PAI processing continues.
Pros and cons: The advantage of using this method is that you can specify the point
at which the event is handled. The contents of the screen fields are also transported

to the application server beforehand. The disadvantage is that this kind of event
handling can lead to conflicts with the automatic input checks on the screen, which
can cause events to be lost.
Why two types of event handling? You have these options because controls may be
displayed on classical ABAP screens, and there may be classical screen elements
alongside controls. The flexibility of the two types of event registration and the
methods of the CFW, mentioned above, allow you to steer the sequence of data
transports between frontend and backend. If you do not use any classical screen
components at all, you can simply work with system events (the default mode).

Figure Handling of Application Events


4

Introduction to the Demonstration Program


Our demonstration program is designed to be as simple as possible. It is meant to
demonstrate the basic concepts of programming with GUI controls. Because of this, we
omitted all superfluous code, and we did not exploit all the possibilities that control
technology provides. With the information we provide in this article, you can go on to
modify the program to learn more. You can find the code in our example at
DEMO_ABAP_ OBJECTS_SPLIT_SCREEN in R/3 Release 4.6C or higher.
Program Structure
Figure 5 shows the processing blocks of the demonstration program. The program
contains two local classes, screen_init and screen_handler, which are used to create and
fill the controls and to react on the user's input. Since controls are displayed on classical
ABAP screens, we need a small classical framework to call a carrier screen for our
controls. We use the event block LOAD-OF-PROGRAM and two dialog modules for that
purpose.
Listing 1 shows the coding structure of the program. For our demonstration program,

we have chosen the program type 1 (executable). Note that we could have taken one of
the other program types that support screens, namely a module pool or a function pool.
Choosing an executable just simplifies the program execution, because you can start the
program directly from the ABAP Editor.
The program does not contain any global data declarations, and it does not make use of
the classical reporting events such as START-OF-SELECTION. It is simply a container
for the three processing blocks of the classical screen framework, shown in Figure 5, and
our two local classes.

Figure Structure of the Demonstration Program


5
PROGRAM demo_abap_objects_split_screen.
* Classes
***************************************************
CLASS screen_init DEFINITION CREATE PRIVATE.
...
ENDCLASS.
CLASS screen_handler DEFINITION.
...
ENDCLASS.
CLASS screen_init IMPLEMENTATION.
...
ENDCLASS.
CLASS screen_handler IMPLEMENTATION.
...
ENDCLASS.
* Classical processing blocks ********************************
LOAD-OF-PROGRAM.
...
MODULE status_0100 OUTPUT.
...
ENDMODULE.
MODULE cancel INPUT.
...
ENDMODULE.

Listing Layout of the Demonstration Program


1

The Program at Runtime

Figure 6 shows which objects the program uses to create the screen display of the
demonstration program, along with the references between these objects.
During screen display, there is no instance of the local class screen_init because
there is no global reference variable in the program that can point to such an instance.
An object of screen_init will be created temporarily during each PBO processing of the
screen, where it is used as a factory object to create the control objects from the global
classes cl_gui_splitter_container, cl_gui_picture, and cl_gui_ simple_tree. After each
PBO processing, the object of screen_init will be deleted by the garbage collector. The
objects of the global classes are kept alive by pointers from the CFW because they are
bound to screen areas. An instance of screen_handler is registered as an event handler
for events of object cl_gui_simple_tree. This instance itself holds references to objects of
the global classes cl_gui_ html_viewer and cl_gui_alv_grid. The instances of the global
classes are linked to controls on the screen via the CFW layer. The two objects of cl_gui_
splitter_container split the screen in the three areas shown in Figure 1. The objects of the
application controls are linked to these areas. The objects of cl_gui_html_viewer and
cl_gui_alv_grid are both linked to the same area.

Figure Runtime Objects of the Demonstration Program


6

Demonstration Program in Detail


The following sections explain the definitions and the processing blocks of the
demonstration program in detail. (Again, the code shown here is available at
DEMO_ABAP_OBJECTS_SPLIT_ SCREEN in Release 4.6C or higher.)
Classical Screen Framework
Listing 2 shows the complete coding of the three classical processing blocks listed in
Figure 5. The ABAP runtime environment raises the event LOAD-OF-PROGRAM at the
moment when the program is started. The respective processing block does nothing but
call Screen 100. Screen 100 is created with the Screen Painter. In its screen flow logic,
the two dialog modules status_0100 and cancel are called during PBO and PAI

respectively, the latter with the addition AT EXIT-COMMAND. We did not use the
graphical Screen Painter for our example because we have no classical elements on our
screen, and we will use an implicit method to create a custom control. The PBO module
sets a GUI status. Within that status, the three function codes BACK, EXIT, and CANCEL
are defined with function type E (Exit Command) and are activated in the symbol bar.
Therefore, the PAI module is called only when the user wants to leave the program. The
most important action during PBO is calling the static method init_screen of class
screen_handler. All actual screen handling is encapsulated in the two local classes.

LOAD-OF-PROGRAM.
CALL SCREEN 100.
MODULE status_0100 OUTPUT.
SET PF-STATUS 'SCREEN_100'.
SET TITLEBAR 'TIT_100'.
CALL METHOD screen_init=>init_screen.
ENDMODULE.
MODULE cancel INPUT.
LEAVE PROGRAM.
ENDMODULE.

Listing Classical Processing Blocks of the Demonstration Program


2

Local Class Definitions


Listing 3 shows the declaration parts of the two local classes of the program: screen_init
and screen_handler. In each of the declaration parts, two visibility sections are defined by
using the statements PUBLIC SECTION and PRIVATE SECTION. Only those class
components that must be used from the outside client are declared in the public sections.
All other components are encapsulated in the private sections. All attributes are
reference variables that refer to global classes of the CFW. Each local class has an
instance constructor and private methods that are used to fill the controls with data.
In addition to these general features, our two local classes also have their own
particular features:

Class screen_init has a public static method, init_screen, that can be called
without creating an object of that class.

Class screen_handler has an event handler method handle_node_ double_click


that can handle events of the global class cl_gui_ simple_tree.

Note the addition CREATE PRIVATE in the definition of screen_init in Listing 3.


Objects of class screen_ init can be created only within class screen_init itself.

CLASS screen_init DEFINITION CREATE PRIVATE.


PUBLIC SECTION.
CLASS-METHODS init_screen.
METHODS constructor.
PRIVATE SECTION.

DATA: splitter_h TYPE REF TO cl_gui_splitter_container,


splitter_v TYPE REF TO cl_gui_splitter_container,
picture TYPE REF TO cl_gui_picture,
tree TYPE REF TO cl_gui_simple_tree.
METHODS: fill_tree, fill_picture.
ENDCLASS.
CLASS screen_handler DEFINITION. PUBLIC SECTION.
METHODS: constructor IMPORTING container
TYPE REF TO cl_gui_container,
handle_node_double_click
FOR EVENT node_double_click
OF cl_gui_simple_tree
IMPORTING node_key.
PRIVATE SECTION.
DATA: html_viewer TYPE REF TO cl_gui_html_viewer,
list_viewer TYPE REF TO cl_gui_alv_grid.
METHODS: fill_html IMPORTING carrid TYPE spfli-carrid,
fill_list IMPORTING carrid TYPE spfli-carrid
connid TYPE spfli-connid.
ENDCLASS.

Listing Declaration Parts of the Two Local Classes


3

Static Method init_screen


Listing 4 shows the static method init_screen of class screen_init. The single purpose of
method init_screen is to create a temporary object of class screen_init. This is done by
using a local reference variable, screen. During the CREATE OBJECT statement, the
instance constructor of screen_init is executed. Note that after leaving method
init_screen, the reference variable screen is deleted. The object is not referenced
anymore and will be deleted by the next turn of the garbage collector.

METHOD init_screen.
DATA screen TYPE REF TO screen_init.
CREATE OBJECT screen.
ENDMETHOD.

Listing The Static Method init_screen of Class screen_init


4

Instance Constructor of screen_init


Listing 5 shows the instance constructor of class screen_init. The instance constructor is
used to create all the container controls on Screen 100 and two of the application
controls (picture and tree). Furthermore, it creates an event handler for events of the tree
control. Most of the data objects that are needed for this purpose are declared locally
within the constructor. The reference variables of type cl_gui_ container can contain
references that point to any container control at the screen.

METHOD constructor.
DATA: events TYPE cntl_simple_events,
event LIKE LINE OF events,
event_handler TYPE REF TO screen_handler,

container_left TYPE REF TO cl_gui_container,


container_right TYPE REF TO cl_gui_container,
container_top TYPE REF TO cl_gui_container,
container_bottom TYPE REF TO cl_gui_container.
CREATE OBJECT splitter_h
EXPORTING
parent = cl_gui_container=>screen0
rows = 1
columns = 2.
CALL METHOD splitter_h->set_border
EXPORTING border = cl_gui_cfw=>false.
CALL METHOD splitter_h->set_column_mode
EXPORTING mode = splitter_h->mode_absolute.
CALL METHOD splitter_h->set_column_width
EXPORTING id = 1
width = 110.
container_left = splitter_h->get_container( row = 1 column = 1 ).
container_right = splitter_h->get_container( row = 1 column = 2 ).
CREATE OBJECT splitter_v
EXPORTING
parent = container_left
rows = 2
columns = 1.
CALL METHOD splitter_v->set_border
EXPORTING border = cl_gui_cfw=>false.
CALL METHOD splitter_v->set_row_mode
EXPORTING mode = splitter_v->mode_absolute.
CALL METHOD splitter_v->set_row_height
EXPORTING id = 1
height = 160.
container_top = splitter_v->get_container( row = 1 column = 1 ).
container_bottom = splitter_v->get_container( row = 2 column = 1 ).
CREATE OBJECT picture
EXPORTING parent = container_top.
CREATE OBJECT tree
EXPORTING parent = container_bottom
node_selection_mode =
cl_gui_simple_tree=>node_sel_mode_single.
CREATE OBJECT event_handler
EXPORTING container = container_right.
event-eventid = cl_gui_simple_tree=>eventid_node_double_click.
event-appl_event = ' '.
APPEND event TO events.
CALL METHOD tree->set_registered_events
EXPORTING events = events.
SET HANDLER event_handler->handle_node_double_click FOR tree.
CALL METHOD: me->fill_picture,
me->fill_tree.
ENDMETHOD.

Listing The Instance Constructor of Class screen_init


5

Creating the Container Controls


The code in Listing 5 demonstrates the process involved in creating the container
controls in the demonstration program:
1.
Create the first splitter container (CREATE OBJECT splitter_h). The
constructor creates an object of the global class cl_gui_splitter_ container using
the reference variable splitter_h. In the CREATE statement, actual parameters are
passed to the IMPORTING parameters of the global class's constructor.
2.

Create a Custom Control at Screen 100 (parent = cl_gui_container


=>screen0). By passing the static attribute screen0 of class cl_gui_ container to
the parameter parent, we use the entire area of Screen 100 as a custom control
implicitly. (This is why we didn't have to use the graphical Screen Painter for
Screen 100 to create a custom control.)

Alternatively, we could create a custom control on Screen 100 with the graphical
Screen Painter and pass its name instead of screen0. Then, only this area would
be used for displaying the controls.
TIP: When you write more complex programs that work with
more than one screen, you must create custom controls with
the graphical Screen Painter in order to distinguish between
3.

the screens.
Split the screen into two columns (columns = 2). We fill the remaining
IMPORTING parameters with appropriate values to split Screen 100 into two
columns. For each column, a new container control is created. References to
each new container are stored in a system table of the CFW. You cannot access
this table from the ABAP program. Nevertheless, the table lines point to container
control objects of the program that are currently linked to a screen and prevent
these objects from being deleted by the garbage collector, even if the container
control objects are not referenced in the program itself (see Figure 6).
TIP: To remove a control object from the program, you must
use its method free before initializing all respective reference
variables. This method deletes the respective entry from the

4.

5.

CFW system table.


Get references of the two columns into container_left and container_right.
After we set some attributes of the columns by calling methods of splitter_h, we
read the references to our containers from the CFW into the local reference
variables container_left and container_right by functional calls of method
get_container.
Create two rows in the left column (CREATE OBJECT splitter_v). We
follow the basic principles of steps 1-4 in a similar procedure to split the left
column into two rows. Here, we pass the reference in container_left to the
constructor of cl_gui_splitter_ container and get references of the two new
container objects into the local reference variables container_ top and
container_bottom.

Creating the Application Controls By going through the steps listed above, we have
created all the container controls that we need. Now we can go on to create our
application controls. The process is shown in the code in Listing 5, and involves these
steps:
1.
Create application controls for the left column (CREATE OBJECT picture
and CREATE OBJECT tree). With the instance constructor of class screen_init,
we create the two application controls for the containers in the left column. In the
upper container, we create an object of cl_gui_picture. In the lower container, we
create an object of cl_gui_simple_tree. We link the objects to the respective
container controls by passing the references in container_top and container_
bottom to their constructor's IMPORTING parameter parent.
2.

Create an event handler (CREATE OBJECT event_handler). Since we want


our program to react on user actions in the tree control, we must provide and
register an event handler:

2.

First, we create an object of our local class screen_handler.

The constructor of this class demands an IMPORTING parameter of


type cl_gui_container. We pass the reference to the right column's container
control.

In order to register our object of class screen_handler as an event


handler for the tree control, we must call the special method
set_registered_events as well as the simple SET HANDLER statement (see
"Control Events and Event Handling" above).

The parameters are passed via an internal table of type cntl_


simple_events, which is defined in the ABAP Dictionary.

By moving a blank character ' ' (default value) and not an 'X' to the
component appl_event, we define that the event is handled as a system event
(default) and not as an application event.

Send initial data to the application controls (call method: me->fill picture, me->fill
tree). Finally, the constructor calls the methods fill_picture and fill_tree to initialize
the contents of our application controls on the screen.

Method fill_picture
Listing 6 shows the instance method fill_picture of class screen_init. The method
fill_picture imports a picture in GIF format from an indx type database table abtree into a
local internal table pict_tab. The function module dp_create_url creates a URL for that
internal table and passes it to the local variable url. By passing that URL to method
load_picture_from_url of our picture control object, we send the picture to the picture
control at the screen. The method set_display_mode allows us to set the attributes of the
picture displayed in the control.
Instead of working with an internal table, you can also use a local picture file from
your presentation server and pass its name directly to the parameter url of method
load_picture_from_url. Our program has the advantage of working for all users.

METHOD fill_picture.
TYPES pict_line(256) TYPE c.
DATA pict_tab TYPE TABLE OF pict_line.
DATA url(255) TYPE c.
IMPORT pict_tab = pict_tab FROM DATABASE abtree(pi) ID 'FLIGHTS'.
CALL FUNCTION 'DP_CREATE_URL'
EXPORTING
type = 'IMAGE'
subtype = 'GIF'
TABLES
data = pict_tab
CHANGING
url = url.
CALL METHOD picture->load_picture_from_url EXPORTING url = url.
CALL METHOD picture->set_display_mode
EXPORTING display_mode = picture->display_mode_fit_center.
ENDMETHOD.

Listing The Instance Method fill_picture of Class screen_init


6

TIP:How can you save pictures in an indx type database table? Listing 7 shows a little
helper routine that fulfills that purpose. Provide your favorite picture in a folder (for
example, C:\TEMP\ of your presentation server) and simply run this program. The
program loads the picture in binary format into an internal table and exports it to an indx
type database table. (We strongly recommend that you create your own indx type table
instead of using abtree or indx itself!)

REPORT picture_save.
PARAMETERS file TYPE rlgrap-filename DEFAULT 'C:\TEMP\.GIF'.
PARAMETERS id(20) TYPE c.
DATA pict_line(256) TYPE c.
DATA pict_tab LIKE TABLE OF pict_line.
CALL FUNCTION 'WS_UPLOAD'
EXPORTING
filename = file
filetype = 'BIN'
TABLES
data_tab = pict_tab.
EXPORT pict_tab = pict_tab TO DATABASE abtree(pi) ID id.

Listing Helper Routine to Save GIFs in a Database Table


7

Method fill_tree
Listing 8 shows the instance method fill_tree of class screen_init. To create a tree-like
structure within the tree control, you must call method add_nodes and pass an internal
table of special structure and contents to that method. The addition TYPE TABLE OF in
the declaration of node_table in Listing 8 shows that the line type of that internal table is
abdemonode, defined in the ABAP Dictionary. You can create such types by copying the
global template structure mtreesnode.
The internal table contains one line for each node of the tree. Each node must have a
unique key node_key. The columns relatkey and relatship describe the relations between
the nodes. You can also add description texts, change the standard icons, and so on. In
our example, we create a node table from the contents of database table spfli. The
database table spfli is the well-known table of flight connections from SAP's training and
demonstration flight model.
We select all data from spfli into the sorted internal table spfli_tab and process this
table in a loop. There, we fill the internal table node_table with lines that represent a tree
structure of two hierarchy levels. The attributes of the nodes are set by assigning flags to
some columns of node_table. Note that we replace the standard folder icon with an
airplane icon for the subnodes by assigning the internal code "@AV@" to the image
columns.

METHOD fill_tree.
DATA: node_table TYPE TABLE OF abdemonode,
node TYPE abdemonode,
spfli_wa TYPE spfli,
spfli_tab TYPE SORTED TABLE OF spfli
WITH UNIQUE KEY carrid connid.
SELECT carrid connid
FROM spfli
INTO CORRESPONDING FIELDS OF TABLE spfli_tab.
node-hidden = ' '.
node-disabled = ' '.
node-isfolder = 'X'.
node-expander = ' '.
LOOP AT spfli_tab INTO spfli_wa.
AT NEW carrid.
node-node_key = spfli_wa-carrid.
CLEAR node-relatkey.
CLEAR node-relatship.
node-text = spfli_wa-carrid.
node-n_image = ' '.
node-exp_image = ' '.
APPEND node TO node_table.
ENDAT.
AT NEW connid.
CONCATENATE spfli_wa-carrid spfli_wa-connid
INTO node-node_key.
node-relatkey = spfli_wa-carrid.
node-relatship =
cl_gui_simple_tree=>relat_last_child.
node-text = spfli_wa-connid.
node-n_image = '@AV@'.
node-exp_image = '@AV@'.
ENDAT.
APPEND node TO node_table.
ENDLOOP.
CALL METHOD tree->add_nodes
EXPORTING table_structure_name = 'ABDEMONODE'
node_table = node_table.
ENDMETHOD.

Listing The Instance Method fill_tree of Class screen_init


8
TIP: To find the internal codes of all SAP icons, execute the report SHOWICON.
Instance Constructor of screen_handler
Listing 9 shows the instance constructor of class screen_handler. The instance
constructor of class screen_init creates an object of class screen_ handler. This means
that the execution of the instance constructor of class screen_handler is embedded in the
execution of the instance constructor of class screen_init. It creates two application
control objects, both of which are linked to the right column of our vertical splitter control.
Remember that the instance constructor of class screen_init passes the reference to the
right column's container control and to the constructor's parameter container in the
CREATE OBJECT statement. The application controls can display either HTML pages or
lists, but they are not filled during the constructor's execution yet. Filling these controls
depends on the user's action in the tree control.

METHOD constructor.
CREATE OBJECT: html_viewer EXPORTING parent = container,
list_viewer EXPORTING i_parent = container.

ENDMETHOD.

Listing The Instance Constructor of Class screen_handler


9

Method handle_node_double_click
Listing 10 shows the instance method handle_node_double_click of class
screen_handler. This method is declared and registered as an event handler for the
event node_double_click of our tree control object. Therefore, each time a user doubleclicks on a node of the tree, it triggers that method. The method imports the event's
EXPORTING parameter node_key, which contains the key of the selected node.
Depending on the key's contents, the event handler either calls method fill_html or
fill_list. It also sets the visibility of the two application controls referenced by html_viewer
and list_viewer. Remember that both controls are linked to the right column of our vertical
splitter control. The event handler steers their alternative display in that container.
As stated above, method calls to the frontend are buffered in an automation queue.
But since there is no automatic synchronization point after handling a system event on
the backend, we must force the system to process the preceding method calls. To do
this, we must call the static method cl_gui_cfw=>flush. Note that we do not have any
regular PAI processing in our program except when the user leaves the screen. The
communication between frontend and backend is handled by the CFW. The frontend-tobackend communication is triggered by events, and the backend-to-frontend
communication is triggered by flushes.

METHOD handle_node_double_click.
DATA: carrid TYPE spfli-carrid,
connid TYPE spfli-connid.
carrid = node_key(2).
connid = node_key+2(4).
IF connid IS INITIAL.
CALL METHOD: fill_html EXPORTING
html_viewer->set_visible EXPORTING visible = 'X',
list_viewer->set_visible EXPORTING visible = ' '.
ELSE.
CALL METHOD: fill_list EXPORTING
connid = connid,
list_viewer->set_visible EXPORTING visible
html_viewer->set_visible EXPORTING visible
ENDIF.
CALL METHOD cl_gui_cfw=>flush.
ENDMETHOD.

Listing
10

carrid = carrid,

carrid = carrid
= 'X',
= ' '.

The Instance Method handle_node_double_click of Class


screen_handler

Method fill_html
Listing 11 shows the instance method fill_html of class screen_handler. When a user

selects a node, this method reads the value of column URL from the database table
SCARR according to the node selected. The selected URL is simply passed to the
method show_url of our HTML control, which displays it in its area on the screen.
Beginning with Release 4.6C, the new column URL of the carrier database table
SCARR will contain the addresses of the carrier's Web sites. To add, change, or update
the addresses, you can provide your own data and change the program accordingly.

METHOD fill_html.
DATA url TYPE scarr-url.
SELECT SINGLE url
FROM
scarr
INTO
url
WHERE carrid = carrid.
CALL METHOD html_viewer->show_url EXPORTING url = url.
ENDMETHOD.

Listing 11The Instance Method fill_html of Class screen_handler

Method fill_list
Listing 12 shows the instance method fill_list of class screen_handler. This method
gives you an impression of how to work with the new SAP List Viewer, which will replace
classical ABAP list processing. As with the tree control, you have to prepare data in an
internal table and pass this table to a method of the List Viewer object. In our case, we
read detail information from database table sflight into an internal table flight_tab when
the user has double-clicked a flight connection in the tree. In addition to the actual data,
we prepare and pass additional information - such as the list's title and some of its
attributes - to the method. Figure 7 shows the screen after selecting a flight connection
in the tree.

METHOD fill_list.
DATA: flight_tab TYPE TABLE OF demofli,
BEGIN OF flight_title,
carrname TYPE scarr-carrname,
cityfrom TYPE spfli-cityfrom,
cityto TYPE spfli-cityto,
END OF flight_title,
list_layout TYPE lvc_s_layo.
SELECT SINGLE c~carrname p~cityfrom p~cityto
INTO
CORRESPONDING FIELDS OF flight_title
FROM
( scarr AS c
INNER JOIN spfli AS p ON
c~carrid = p~carrid )
WHERE
p~carrid = carrid AND
p~connid = connid.
SELECT fldate seatsmax seatsocc
INTO
CORRESPONDING FIELDS OF TABLE
flight_tab

FROM
sflight
WHERE
carrid = carrid AND connid = connid
ORDER BY fldate.
CONCATENATE flight_title-carrname
connid
flight_title-cityfrom
flight_title-cityto
INTO list_layout-grid_title
SEPARATED BY space.
list_layout-smalltitle = 'X'.
list_layout-cwidth_opt = 'X'.
list_layout-no_toolbar = 'X'.
CALL METHOD list_viewer->set_table_for_first_display
EXPORTING i_structure_name = 'DEMOFLI'
is_layout = list_layout
CHANGING
it_outtab = flight_tab.
ENDMETHOD.

Listing
12

The Instance Method fill_list of Class screen_handler

Figure 7List Display with an ALV Control

Conclusion
In this article, we showed you the principal concepts of programming screens with the
control framework using a detailed demonstration program. This procedure can be
condensed into the following steps:
1.
Create container control objects and link them to areas at the screen.
2.

Create application control objects and link them to the container controls.

3.

Provide data for the controls in data objects, which, in most cases, are

internal tables of special global types.


4.
5.

Send the data to the controls by calling control methods.


React on user actions on the controls by defining and registering event
handler methods.
In this article, we did not explain the single control classes - or their methods and

events - in great detail. We simply wanted to provide an overview for the ABAP Objects
programmer who wants to use global classes of the CFW and who defines his or her own
local classes to handle the control objects on the screen.
Using this article as a starting point, you can learn more about the features of the
control framework by referring to the documentation of the control classes or to their
definition in the class builder of the ABAP Workbench. With that information, you can
then continue to explore the CFW on your own. For example, you might create classes
that react when a user clicks on a picture. Or you could look further into tree controls, so
that when a user selects a node in a tree control, you could introduce context menus for
those nodes. Users would then find these when they right-click on a particular node.
Finally, there is much to discover about the ALV, which we covered only briefly. ALV is the
best choice for presenting tabular data on the screen. It replaces classical table controls
as well as classical lists, and it provides a complete environment for interactive reporting.
If you wish to design and improve GUI features that benefit your users, the
opportunities are there, and the development process for these interfaces is more
streamlined than ever before. Whichever features you choose to take advantage of, this
article can be your springboard to creating an interface that is an effective tool for your
end users.

Horst Keller is information developer in the SAP ABAP & GUI Group. He documents the
ABAP language with an emphasis on ABAP Objects. He also develops and teaches
classes on ABAP programming and gives workshops at technical education conferences.
You can reach him at horst.keller@sap.com.
Gisbert Loff is product manager in the SAP ABAP & GUI Group, where he handles all
GUI-related issues. He has given various lecture presentations and workshops at
technical education conferences and SAPPHIREs. You can reach him
atgisbert.loff@sap.com.

S-ar putea să vă placă și