BUS Screen Framework – Introduction

Since I develop ABAP in SAP I must deal with the old, dusty dynpros. Unfortunately, many customers are still not willing to more forward any use Web Dynpro, UI5 or any of the other modern technologies out there. In our current project, we were lucky enough and could start from scratch so I introduced the BUS Screen Framework. The first time I came in touch with this little framework was read the book Anwendungsentwicklung mit ABAP Objects from Thorsten Franz and Tobias Trapp.

The BUS Screen Framework is a way to develop dynpros using an object orientated approach. But don’t crow too soon: we still must use the dynpro painter and a handful modules and form routines. But it helps you to create an object orientated report and to handle the dynpro logic and events.
Let’s dive a little bit deeper into the framework. It provides you the abstract basic classes for main screens and sub screens. These classes provide some functions like the object orientated access to tab strips, to set the title and status, raising messages or to handle events triggered from the GUI.

The Dynpro Class

Since the BUS screen classes are defined as abstract you must create your own (local) class and inherit from the proper super class. In my example, I have one Dnypro 9000 which acts as my only main screen. This example should give you a first impression of the framework.
Due to the inheritance, we must redefine the abstract methods CALL_SCREEN and CALL_SCREEN_STARTING_AT.

Now we have our Dynpro class. It does not contain any logic but it is enough to create and show our Dynpro. But wait – we have a Dynpro class but no Dynpro yet.
The Dynpro is created like any other Dynpro you have created in your life before. I have created a normal screen that contains a label only.

The Dynpro does not yet communicate with the framework (and therefore with our screen class). First, we must program some code in the Dynpro flow logic. Due to the coding restrictions, we must create two modules (one for PBO and one for PAI).

The only thing these modules do is to handover the PBO and PAI handling for the actual Dynpro to the framework. The methods DYNPRO_PBO and DYNPRO_PAI retrieve an instance from your screen class from the internal buffer and invokes the corresponding methods on this screen object instance.

Both methods, DYNPRO_PBO and DYNPRO_PAI, are internally divided into two methods: PBO_BEGIN/PBO_END and PAI_BEGIN/PAI_END. In a later tutorial, you will see what is the reason for that.

Let’s review the current implementation status:

We have created a screen class for our main screen 9000. It inherits from the class CL_BUS_ABSTRACT_MAIN_SCREEN.

We have created the normal Dynpro 9000 and added some flow logic to handover the PBO/PAI handling to the framework.

The Handler Class

As we have learned the flow logic hands over the event handling to our screen class. Well to be accurate the method PAI_END in super class CL_BUS_ABSTRACT_MAIN_SCREEN raises the event PROCESS_AFTER_INPUT with the function code as parameter. For the ones who wonder where we have defined the function codes: this example does not have a custom status. If we don’t set a status the BUS framework uses the default status BUS_MAIN_SCREEN in function group BUS_LOCATOR. A later example will show how to use a customer own status.Let’s return to the handler class. The screen class raises an event and we must have a handler that listens to it. There is nothing wrong with adding the handler method into the screen class but I prefer a dedicated class. The local class LCL_HANDLER implements a method that listens to the mentioned event. The only action we perform is to leave the screen.

CLASS lcl_handler IMPLEMENTATION.
METHOD handle_pai.
CASE iv_function_code.
* when using the default status we can use the constants to
* check the PAI events
WHEN cl_bus_abstract_main_screen=>gc_function_code_back OR
cl_bus_abstract_main_screen=>gc_function_code_cancel.
* static variable contains a reference to the actual main screen
cl_bus_abstract_main_screen=>gv_current_main_screen->leave( ).
ENDCASE.
ENDMETHOD.
ENDCLASS.

When we invoke the method LEAVE on the actual main screen, the screen instance will be removed from the internal stack. If there was another main screen before the program would return to the previous screen, otherwise the program ends.

Let’s view the current implementation status:

We have created a screen class and Dynpro for our main screen 9000.

We have created the handler class LCL_HANDLER that listens to the event PROCESS_AFTER_INPUT which is raised by the framework.

Since we don’t set a custom status the BUS screen framework uses its default status.

Call the Screen and register the Handler

Next we must program some logic to call our screen, register the handler and display the screen. Personally, I like to put my Dynpros into function groups. Therefore, I have created a simple function module that calls our screen.

The method GET_SCREEN from class CL_BUS_ABSTRACT_MAIN_SCREEN creates an instance of our screen class LCL_SCR9000 and adds it to the internal call stack. But how does the framework know that it should create an instance of class LCL_SCR9000 for our Dynpro 9000? For this purpose, we need the only form routine. Method GET_SCREEN performs the form routine BUS_SCREEN_CREATE in the actual program. We must implement this form routine and return an instance of the screen class.