Object Oriented Programming
Object Oriented Programming
Public attributes are defined in the PUBLIC section and can be viewed and
changed from outside the class. There is direct access to public attributes. As a
general rule, as few public attributes should be defined as possible.
PUBLIC SECTION.
DATA: Counter type i.
Private attributes
Private attributes are defined in the PRIVATE section. The can only be viewes
and changed from within the class. There is no direct access from outside the
class.
PRIVATE SECTION.
DATA: name(25) TYPE c,
planetype LIKE saplane-planetyp,
Instance attributes
There exist one instance attribute for each instance of the class, thus they exist
seperately for each object. Instance attributes are declared with the DATA
keyword.
Static attributes
Static attributes exist only once for each class. The data are the same for all
instances of the class, and can be used e.g. for instance counters. Static
attributes are defined with the keyword CLASS-DATA.
PRIVATE SECTION.
CLASS-DATA: counter type i,
Public methods
PUBLIC SECTION.
METHODS: set_attributes IMPORTING p_name(25) TYPE c,
p_planetype LIKE saplane-planetyp,
Private methods
Can only be called from inside the class. They are placed in the PRIVATE
section of the class.
Constructor method
Implicitly, each class has an instance constructor method with the reserved name
constructor and a static constructor method with the reserved name
class_constructor.
The instance constructor is executed each time you create an object (instance)
with the CREATE OBJECT statement, while the class constructor is executed
exactly once before you first access a class.
Static constructor
Protected components
When we are talking subclassing and enheritance there is one more component
than Public and Private, the Protected component. Protected components can be
used by the superclass and all of the subclasses. Note that Subclasses cannot
access Private components.
Polymorphism
******************************************
* Definition part
******************************************
CLASS xxx DEFINITION.
*------------------------------
* Public section
*------------------------------
PUBLIC SECTION.
TYPES:
DATA:
* Static data
CLASS-DATA:
* Methods
METHODS:
* Using the constructor to initialize parameters
constructor IMPORTING xxx type yyy,
*---------------------------------------------------*
* Protected section. Also accessable by subclasses
*---------------------------------------------------
PROTECTED SECTION.
*---------------------------------------------------
* Private section. Not accessable by subclasses
*---------------------------------------------------
PRIVATE SECTION.
ENDCLASS.
******************************************
* Implementation part
******************************************
CLASS lcl_airplane IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD mm1.
ENDMETHOD.
METHOD mm2.
ENDMETHOD.
ENDCLASS.
Template for calling a class
START-OF-SELECTION.
* Create instance using parameters in the cosntructor method
CREATE OBJECT airplane1 exporting im_name = 'Hansemand'
im_planetype = 'Boing 747'.
* Calling a method with parameters
CALL METHOD: airplane1->display_n_o_airplanes,
airplane1->display_attributes.
Subclass
METHODS:
add_a_new_airplane importing im_airplane TYPE REF to lcl_airplane.
Interfaces
In ABAP interfaces are implemented in addition to, and independently of classes. An interface
only has a declaration part, and do not have visibillity sections. Components (Attributes, methods,
constants, types) can be defined the same way as in classes.
• Interfaces are listed in the definition part lof the class, and must always
be in the PUBLIC SECTION.
• Operations defined in the interface atre impemented as methods of the
class. All methods of the interface must be present in the
• implementation part of the class.
• Attributes, events, constants and types defined in the interface are
automatically available to the class carying out the implementation.
• Interface components are adresse in the class by <interface
name>~<component name>
Events
***INCLUDE ZBC404_HF_LCL_AIRPLANE .
******************************************
* Definition part
******************************************
CLASS lcl_airplane DEFINITION.
*------------------------------
* Public section
*------------------------------
PUBLIC SECTION.
TYPES: t_name(25) TYPE c.
METHODS:
constructor,
set_attributes IMPORTING p_name TYPE t_name
p_planetype TYPE saplane-planetype,
display_attributes,
display_n_o_airplanes.
*------------------------------
* Private section
*------------------------------
PRIVATE SECTION.
* Private attributes
DATA: name(25) TYPE c,
planetype TYPE saplane-planetype.
* Private static attribute
CLASS-DATA n_o_airplanes TYPE i.
ENDCLASS.
******************************************
* Implementation part
******************************************
CLASS lcl_airplane IMPLEMENTATION.
METHOD constructor.
* Counts number of instances
n_o_airplanes = n_o_airplanes + 1.
ENDMETHOD.
METHOD set_attributes.
name = p_name.
planetype = p_planetype.
ENDMETHOD.
METHOD display_attributes.
WRITE:/ 'Name:', name, 'Planetype:', planetype.
ENDMETHOD.
METHOD display_n_o_airplanes.
WRITE: / 'No. planes:', n_o_airplanes.
ENDMETHOD.
ENDCLASS.
REPORT zbc404_hf_maintain_airplanes .
INCLUDE zbc404_hf_lcl_airplane.
START-OF-SELECTION.
* Create instance
CREATE OBJECT airplane1.
CALL METHOD: airplane1->display_n_o_airplanes.
END-OF-SELECTION.
* Using methods
CALL METHOD: airplane1->display_n_o_airplanes,
airplane1->display_attributes.
No. planes: 1
No. planes: 2
Name: Kurt Planetype: MD80
METHODS:
constructor importing p2_name type t_name
p2_planetype TYPE saplane-planetype,
..... more code .......
CLASS lcl_airplane IMPLEMENTATION.
METHOD constructor.
name = p2_name.
planetype = p2_planetype.
..... more code .......
START-OF-SELECTION.
CREATE OBJECT airplane1 exporting p2_name = 'Hansemand'
p2_planetype = 'Boing 747'.
Subclassing
Superclass LCL_AIRPLANE
***INCLUDE ZBC404_HF_LCL_AIRPLANE .
******************************************
* Definition part
******************************************
CLASS lcl_airplane DEFINITION.
*------------------------------
* Public section
*------------------------------
PUBLIC SECTION.
TYPES: t_name(25) TYPE c.
METHODS:
constructor IMPORTING im_name TYPE t_name
im_planetype TYPE saplane-planetype,
display_attributes.
* Static methods
CLASS-METHODS:
display_n_o_airplanes.
*------------------------------
* Protected section
*------------------------------
PROTECTED SECTION.
* Private attributes
DATA: name(25) TYPE c,
planetype TYPE saplane-planetype.
* Private static attribute
CLASS-DATA n_o_airplanes TYPE i.
ENDCLASS.
******************************************
* Implementation part
******************************************
CLASS lcl_airplane IMPLEMENTATION.
METHOD constructor.
name = im_name.
planetype = im_planetype.
METHOD display_attributes.
WRITE:/ 'Name:', name, 'Planetype:', planetype.
ENDMETHOD.
METHOD display_n_o_airplanes.
WRITE: / 'No. planes:', n_o_airplanes.
ENDMETHOD.
ENDCLASS.
***INCLUDE ZBC404_HF_LCL_PASSENGER_PLANE .
*******************************************************************
* This is a subclass of class lcl_airplane
*******************************************************************
CLASS lcl_passenger_airplane DEFINITION INHERITING FROM lcl_airplane.
PUBLIC SECTION.
PRIVATE SECTION.
DATA: n_o_seats TYPE sflight-seatsmax.
ENDCLASS.
ENDMETHOD.
* The redefined display_attributes method
METHOD display_attributes.
CALL METHOD super->display_attributes.
WRITE: / 'No. seats:', n_o_seats.
ENDMETHOD.
ENDCLASS.
Sub class LCL_CARGO_PLANE
***INCLUDE ZBC404_HF_LCL_CARGO_PLANE .
*******************************************************************
* This is a subclass of class lcl_airplane
*******************************************************************
CLASS lcl_cargo_plane DEFINITION INHERITING FROM lcl_airplane.
PUBLIC SECTION.
METHODS:
* The constructor contains the parameters from the superclass
* plus the parameters from the subclass
constructor IMPORTING im_name TYPE t_name
im_planetype TYPE saplane-planetype
im_cargomax type scplane-cargomax,
* Redefinition of superclass method display_attributes
display_attributes REDEFINITION.
PRIVATE SECTION.
DATA:cargomax TYPE scplane-cargomax.
ENDCLASS.
CLASS lcl_cargo_plane IMPLEMENTATION.
METHOD constructor.
* The constructor method of the superclass MUST be called withing the
* constructor
CALL METHOD super->constructor
EXPORTING im_name = im_name
im_planetype = im_planetype.
cargomax = im_cargomax.
ENDMETHOD.
METHOD display_attributes.
* The redefined display_attributes method
CALL METHOD super->display_attributes.
WRITE: / 'Cargo max:', cargomax.
ENDMETHOD.
ENDCLASS.
The Main program that uses the classes
REPORT zbc404_hf_main .
* Super class
INCLUDE zbc404_hf_lcl_airplane.
* Sub classes
INCLUDE zbc404_hf_lcl_passenger_plane.
INCLUDE zbc404_hf_lcl_cargo_plane.
DATA:
* Type ref to sub classes. Note: It is not necesssary to make typeref
to the superclass
o_passenger_airplane TYPE REF TO lcl_passenger_airplane,
o_cargo_plane TYPE REF TO lcl_cargo_plane.
START-OF-SELECTION.
* Display initial number of instances = 0
CALL METHOD lcl_airplane=>display_n_o_airplanes.
* Create objects
CREATE OBJECT o_passenger_airplane
EXPORTING
im_name = 'LH505'
im_planetype = 'Boing 747'
im_n_o_seats = 350.
CREATE OBJECT o_cargo_plane
EXPORTING
im_name = 'AR13'
im_planetype = 'DC 3'
im_cargomax = 35.
* Display attributes
CALL METHOD o_passenger_airplane->display_attributes.
CALL METHOD o_cargo_plane->display_attributes.
* Call static method display_n_o_airplanes
* Note: The syntax for calling a superclass method, differs from the
syntax when calling a subclass method.
* When calling a superclass => must be used instead of ->
CALL METHOD lcl_airplane=>display_n_o_airplanes.
Result:
No. planes: 0
Name: LH505 Planetype: Boing 747
No. seats: 350
Name: AR13 Planetype: DC 3
Cargo max: 35,0000
No. planes: 2
Polymorphism
Polymorphism: When the same method is implemented differently in different
classes. This can be done using enheritance, by redefining a method from the
superclass in subclasses and implement it differently.
Classes:
• lcl_airplane Superclass
• lcl_cargo_airplane Subclass
• lcl_passenger_airplane Subclass
REPORT zbc404_hf_main .
*******************************************************************
* This reprort uses class LCL_AIRPLNAE and subclasses
* LCL_CARGO_PLANE and LCL_PASSENGER_AIRPLANE and class LCL_CARRIER
*******************************************************************
* Super class for airplanes
INCLUDE zbc404_hf_lcl_airplane.
* Sub classes for airplanes
INCLUDE zbc404_hf_lcl_passenger_plane.
INCLUDE zbc404_hf_lcl_cargo_plane.
* Carrier class
INCLUDE zbc404_hf_lcl_carrier.
DATA:
* Type ref to classes
o_passenger_airplane TYPE REF TO lcl_passenger_airplane,
o_passenger_airplane2 TYPE REF TO lcl_passenger_airplane,
o_cargo_plane TYPE REF TO lcl_cargo_plane,
o_cargo_plane2 TYPE REF TO lcl_cargo_plane,
o_carrier TYPE REF TO lcl_carrier.
START-OF-SELECTION.
* Create objects
CREATE OBJECT o_passenger_airplane
EXPORTING
im_name = 'LH505'
im_planetype = 'Boing 747'
im_n_o_seats = 350.
CREATE OBJECT o_passenger_airplane2
EXPORTING
im_name = 'SK333'
im_planetype = 'MD80'
im_n_o_seats = 110.
CREATE OBJECT o_cargo_plane
EXPORTING
im_name = 'AR13'
im_planetype = 'DC 3'
im_cargomax = 35.
CREATE OBJECT o_cargo_plane2
EXPORTING
im_name = 'AFL124'
im_planetype = 'Iljutsin 2'
im_cargomax = 35000.
CREATE OBJECT o_carrier
EXPORTING im_name = 'Spritisch Airways'.
* Add passenger and cargo planes to the list of airplanes
CALL METHOD o_carrier->add_a_new_airplane
EXPORTING im_airplane = o_passenger_airplane.
CALL METHOD o_carrier->add_a_new_airplane
EXPORTING im_airplane = o_passenger_airplane2.
CALL METHOD o_carrier->add_a_new_airplane
EXPORTING im_airplane = o_cargo_plane.
CALL METHOD o_carrier->add_a_new_airplane
EXPORTING im_airplane = o_cargo_plane2.
* Display list of airplanes
call method o_carrier->display_airplanes.
Result:
Name: LH505 Planetype: Boing 747
No. seats: 350
Name: SK333 Planetype: MD80
No. seats: 110
Name: AR13 Planetype: DC 3
Cargo max: 35,0000
Name: AFL124 Planetype: Iljutsin 2
Cargo max: 35.000,0000
Events
REPORT zbc404_hf_events_5.
*---------------------------------------------------------------------*
* CLASS lcl_dog DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_dog DEFINITION.
PUBLIC SECTION.
* Declare events
EVENTS:
dog_is_hungry
EXPORTING value(ex_time_since_last_meal) TYPE i.
METHODS:
constructor
IMPORTING im_name TYPE string,
set_time_since_last_meal
IMPORTING im_time TYPE i,
on_dog_is_hungry FOR EVENT dog_is_hungry OF lcl_dog
IMPORTING ex_time_since_last_meal.
ENDCLASS.
*---------------------------------------------------------------------*
* CLASS lcl_dog IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS lcl_dog IMPLEMENTATION.
METHOD constructor.
WRITE: / 'I am a dog and my name is', im_name.
ENDMETHOD.
METHOD set_time_since_last_meal.
IF im_time < 4.
SKIP 1.
WRITE: / 'You fool, I am not hungry yet'.
ELSE.
* Subsrcribe for event:
* set handler <Event handler method>
* FOR <ref_sender>!FOR ALL INSTANCES [ACTIVATION <var>]
SET HANDLER on_dog_is_hungry FOR ALL INSTANCES ACTIVATION 'X'.
* Raise event
RAISE EVENT dog_is_hungry
EXPORTING ex_time_since_last_meal = im_time.
ENDIF.
ENDMETHOD.
METHOD on_dog_is_hungry.
* Event method, called when the event dog_is_hungry is raised
SKIP 1.
WRITE: / 'You son of a bitch. I have not eaten for more than',
ex_time_since_last_meal, ' hours'.
WRITE: / 'Give me something to eat NOW!'.
ENDMETHOD.
ENDCLASS.
*---------------------------------------------------------------------*
* R E P O R T
*---------------------------------------------------------------------*
DATA: o_dog1 TYPE REF TO lcl_dog.
START-OF-SELECTION.
CREATE OBJECT o_dog1 EXPORTING im_name = 'Beefeater'.
CALL METHOD o_dog1->set_time_since_last_meal
EXPORTING im_time = 2.
* This method call will raise the event dog_is_hungy
* because time > 3
CALL METHOD o_dog1->set_time_since_last_meal
EXPORTING im_time = 5.
Result:
You son of a bitch. I have not eaten for more than 5 hours
Give me something to eat NOW!
1. Simple class
This example shows how to create a simple employee class. The constructor
method is used to initialize number and name of thje employee when the object
is created. A display_employee method can be called to show the attributes of
the employee, and CLASS-METHOD dosplay_no_of_employees can be called to
show the total number of employees (Number of instances of the employee
class).
REPORT zbc404_hf_events_1.
*********************************************************************
* L C L _ E M P L O Y E E
*********************************************************************
*---- LCL Employee - Definition
CLASS lcl_employee DEFINITION.
PUBLIC SECTION.
*--------------------------------------------------------------------
* The public section is accesible from outside
*--------------------------------------------------------------------
TYPES:
BEGIN OF t_employee,
no TYPE i,
name TYPE string,
END OF t_employee.
METHODS:
constructor
IMPORTING im_employee_no TYPE i
im_employee_name TYPE string,
display_employee.
* Class methods are global for all instances
CLASS-METHODS: display_no_of_employees.
PROTECTED SECTION.
*--------------------------------------------------------------------
* The protecetd section is accesible from the class and its subclasses
*--------------------------------------------------------------------
* Class data are global for all instances
CLASS-DATA: g_no_of_employees TYPE i.
PRIVATE SECTION.
*--------------------------------------------------------------------
* The private section is only accesible from within the classs
*--------------------------------------------------------------------
DATA: g_employee TYPE t_employee.
ENDCLASS.
*--- LCL Employee - Implementation
CLASS lcl_employee IMPLEMENTATION.
METHOD constructor.
g_employee-no = im_employee_no.
g_employee-name = im_employee_name.
g_no_of_employees = g_no_of_employees + 1.
ENDMETHOD.
METHOD display_employee.
WRITE:/ 'Employee', g_employee-no, g_employee-name.
ENDMETHOD.
METHOD display_no_of_employees.
WRITE: / 'Number of employees is:', g_no_of_employees.
ENDMETHOD.
ENDCLASS.
***********************************************************************
*
* R E P O R T
*********************************************************************
DATA: g_employee1 TYPE REF TO lcl_employee,
g_employee2 TYPE REF TO lcl_employee.
START-OF-SELECTION.
CREATE OBJECT g_employee1
EXPORTING im_employee_no = 1
im_employee_name = 'John Jones'.
CREATE OBJECT g_employee2
EXPORTING im_employee_no = 2
im_employee_name = 'Sally Summer'.
CALL METHOD g_employee1->display_employee.
CALL METHOD g_employee2->display_employee.
CALL METHOD g_employee2->display_no_of_employees.
Principles:
• Constructor
• Add_Employee - Adds a new employee to the list of employees
• Display_Employee_List - Displays all employees and there wage
• Display_no_of_employees - Displays total number of employees
Note the use of CLASS-DATA to keep the list of employees and number of
employees the same from instance to instance.
Methodes:
The program
REPORT zbc404_hf_events_2 .
*******************************************************
* Super class LCL_CompanyEmployees
*******************************************************
CLASS lcl_company_employees DEFINITION.
PUBLIC SECTION.
TYPES:
BEGIN OF t_employee,
no TYPE i,
name TYPE string,
wage TYPE i,
END OF t_employee.
METHODS:
constructor,
add_employee
IMPORTING im_no TYPE i
im_name TYPE string
im_wage TYPE i,
display_employee_list,
display_no_of_employees.
PRIVATE SECTION.
CLASS-DATA: i_employee_list TYPE TABLE OF t_employee,
no_of_employees TYPE i.
ENDCLASS.
*-- CLASS LCL_CompanyEmployees IMPLEMENTATION
CLASS lcl_company_employees IMPLEMENTATION.
METHOD constructor.
no_of_employees = no_of_employees + 1.
ENDMETHOD.
METHOD add_employee.
* Adds a new employee to the list of employees
DATA: l_employee TYPE t_employee.
l_employee-no = im_no.
l_employee-name = im_name.
l_employee-wage = im_wage.
APPEND l_employee TO i_employee_list.
ENDMETHOD.
METHOD display_employee_list.
* Displays all employees and there wage
DATA: l_employee TYPE t_employee.
WRITE: / 'List of Employees'.
LOOP AT i_employee_list INTO l_employee.
WRITE: / l_employee-no, l_employee-name, l_employee-wage.
ENDLOOP.
ENDMETHOD.
METHOD display_no_of_employees.
* Displays total number of employees
SKIP 3.
WRITE: / 'Total number of employees:', no_of_employees.
ENDMETHOD.
ENDCLASS.
*******************************************************
* Sub class LCL_BlueCollar_Employee
*******************************************************
CLASS lcl_bluecollar_employee DEFINITION
INHERITING FROM lcl_company_employees.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING im_no TYPE i
im_name TYPE string
im_hours TYPE i
im_hourly_payment TYPE i,
add_employee REDEFINITION.
PRIVATE SECTION.
DATA:no TYPE i,
name TYPE string,
hours TYPE i,
hourly_payment TYPE i.
ENDCLASS.
*---- CLASS LCL_BlueCollar_Employee IMPLEMENTATION
CLASS lcl_bluecollar_employee IMPLEMENTATION.
METHOD constructor.
* The superclass constructor method must be called from the subclass
* constructor method
CALL METHOD super->constructor.
no = im_no.
name = im_name.
hours = im_hours.
hourly_payment = im_hourly_payment.
ENDMETHOD.
METHOD add_employee.
* Calculate wage an call the superclass method add_employee to add
* the employee to the employee list
DATA: l_wage TYPE i.
l_wage = hours * hourly_payment.
CALL METHOD super->add_employee
EXPORTING im_no = no
im_name = name
im_wage = l_wage.
ENDMETHOD.
ENDCLASS.
*******************************************************
* Sub class LCL_WhiteCollar_Employee
*******************************************************
CLASS lcl_whitecollar_employee DEFINITION
INHERITING FROM lcl_company_employees.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING im_no TYPE i
im_name TYPE string
im_monthly_salary TYPE i
im_monthly_deductions TYPE i,
add_employee REDEFINITION.
PRIVATE SECTION.
DATA:
no TYPE i,
name TYPE string,
monthly_salary TYPE i,
monthly_deductions TYPE i.
ENDCLASS.
*---- CLASS LCL_WhiteCollar_Employee IMPLEMENTATION
CLASS lcl_whitecollar_employee IMPLEMENTATION.
METHOD constructor.
* The superclass constructor method must be called from the subclass
* constructor method
CALL METHOD super->constructor.
no = im_no.
name = im_name.
monthly_salary = im_monthly_salary.
monthly_deductions = im_monthly_deductions.
ENDMETHOD.
METHOD add_employee.
* Calculate wage an call the superclass method add_employee to add
* the employee to the employee list
DATA: l_wage TYPE i.
l_wage = monthly_salary - monthly_deductions.
CALL METHOD super->add_employee
EXPORTING im_no = no
im_name = name
im_wage = l_wage.
ENDMETHOD.
ENDCLASS.
*******************************************************
* R E P O R T
*******************************************************
DATA:
* Object references
o_bluecollar_employee1 TYPE REF TO lcl_bluecollar_employee,
o_whitecollar_employee1 TYPE REF TO lcl_whitecollar_employee.
START-OF-SELECTION.
* Create bluecollar employee obeject
CREATE OBJECT o_bluecollar_employee1
EXPORTING im_no = 1
im_name = 'Gylle Karen'
im_hours = 38
im_hourly_payment = 75.
* Add bluecollar employee to employee list
CALL METHOD o_bluecollar_employee1->add_employee
EXPORTING im_no = 1
im_name = 'Gylle Karen'
im_wage = 0.
* Create whitecollar employee obeject
CREATE OBJECT o_whitecollar_employee1
EXPORTING im_no = 2
im_name = 'John Dickens'
im_monthly_salary = 10000
im_monthly_deductions = 2500.
* Add bluecollar employee to employee list
CALL METHOD o_whitecollar_employee1->add_employee
EXPORTING im_no = 1
im_name = 'Karen Johnson'
im_wage = 0.
* Display employee list and number of employees. Note that the result
* will be the same when called from o_whitecollar_employee1 or
* o_bluecolarcollar_employee1, because the methods are defined
* as static (CLASS-METHODS)
CALL METHOD o_whitecollar_employee1->display_employee_list.
CALL METHOD o_whitecollar_employee1->display_no_of_employees.
List of Employees
1 Karen Johnson 2.850
2 John Dickens 7.500
3. Interfaces
The interface in the example only contains a method, but an iterface can also
contain attrbutes, constants, types and alias names.
All changes in the program compared to example 2 are marked with red.
REPORT zbc404_hf_events_3 .
*---------------------------------------------------------------------*
* INTERFACE lif_employee
*---------------------------------------------------------------------*
INTERFACE lif_employee.
METHODS:
add_employee
IMPORTING im_no TYPE i
im_name TYPE string
im_wage TYPE i.
ENDINTERFACE.
*******************************************************
* Super class LCL_CompanyEmployees
*******************************************************
CLASS lcl_company_employees DEFINITION.
PUBLIC SECTION.
INTERFACES lif_employee.
TYPES:
BEGIN OF t_employee,
no TYPE i,
name TYPE string,
wage TYPE i,
END OF t_employee.
METHODS:
constructor,
* add_employee "Removed
IMPORTING im_no TYPE i
im_name TYPE string
im_wage TYPE i,
display_employee_list,
display_no_of_employees.
PRIVATE SECTION.
CLASS-DATA: i_employee_list TYPE TABLE OF t_employee,
no_of_employees TYPE i.
ENDCLASS.
*-- CLASS LCL_CompanyEmployees IMPLEMENTATION
CLASS lcl_company_employees IMPLEMENTATION.
METHOD constructor.
no_of_employees = no_of_employees + 1.
ENDMETHOD.
METHOD lif_employee~add_employee.
* Adds a new employee to the list of employees
DATA: l_employee TYPE t_employee.
l_employee-no = im_no.
l_employee-name = im_name.
l_employee-wage = im_wage.
APPEND l_employee TO i_employee_list.
ENDMETHOD.
METHOD display_employee_list.
* Displays all employees and there wage
DATA: l_employee TYPE t_employee.
WRITE: / 'List of Employees'.
LOOP AT i_employee_list INTO l_employee.
WRITE: / l_employee-no, l_employee-name, l_employee-wage.
ENDLOOP.
ENDMETHOD.
METHOD display_no_of_employees.
* Displays total number of employees
SKIP 3.
WRITE: / 'Total number of employees:', no_of_employees.
ENDMETHOD.
ENDCLASS.
*******************************************************
* Sub class LCL_BlueCollar_Employee
*******************************************************
CLASS lcl_bluecollar_employee DEFINITION
INHERITING FROM lcl_company_employees.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING im_no TYPE i
im_name TYPE string
im_hours TYPE i
im_hourly_payment TYPE i,
lif_employee~add_employee REDEFINITION..
PRIVATE SECTION.
DATA:no TYPE i,
name TYPE string,
hours TYPE i,
hourly_payment TYPE i.
ENDCLASS.
*---- CLASS LCL_BlueCollar_Employee IMPLEMENTATION
CLASS lcl_bluecollar_employee IMPLEMENTATION.
METHOD constructor.
* The superclass constructor method must be called from the subclass
* constructor method
CALL METHOD super->constructor.
no = im_no.
name = im_name.
hours = im_hours.
hourly_payment = im_hourly_payment.
ENDMETHOD.
METHOD lif_employee~add_employee.
* Calculate wage an call the superclass method add_employee to add
* the employee to the employee list
DATA: l_wage TYPE i.
l_wage = hours * hourly_payment.
CALL METHOD super->lif_employee~add_employee
EXPORTING im_no = no
im_name = name
im_wage = l_wage.
ENDMETHOD.
ENDCLASS.
*******************************************************
* Sub class LCL_WhiteCollar_Employee
*******************************************************
CLASS lcl_whitecollar_employee DEFINITION
INHERITING FROM lcl_company_employees.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING im_no TYPE i
im_name TYPE string
im_monthly_salary TYPE i
im_monthly_deductions TYPE i,
lif_employee~add_employee REDEFINITION.
PRIVATE SECTION.
DATA:
no TYPE i,
name TYPE string,
monthly_salary TYPE i,
monthly_deductions TYPE i.
ENDCLASS.
*---- CLASS LCL_WhiteCollar_Employee IMPLEMENTATION
CLASS lcl_whitecollar_employee IMPLEMENTATION.
METHOD constructor.
* The superclass constructor method must be called from the subclass
* constructor method
CALL METHOD super->constructor.
no = im_no.
name = im_name.
monthly_salary = im_monthly_salary.
monthly_deductions = im_monthly_deductions.
ENDMETHOD.
METHOD lif_employee~add_employee.
* Calculate wage an call the superclass method add_employee to add
* the employee to the employee list
DATA: l_wage TYPE i.
l_wage = monthly_salary - monthly_deductions.
CALL METHOD super->lif_employee~add_employee
EXPORTING im_no = no
im_name = name
im_wage = l_wage.
ENDMETHOD.
ENDCLASS.
*******************************************************
* R E P O R T
*******************************************************
DATA:
* Object references
o_bluecollar_employee1 TYPE REF TO lcl_bluecollar_employee,
o_whitecollar_employee1 TYPE REF TO lcl_whitecollar_employee.
START-OF-SELECTION.
* Create bluecollar employee obeject
CREATE OBJECT o_bluecollar_employee1
EXPORTING im_no = 1
im_name = 'Gylle Karen'
im_hours = 38
im_hourly_payment = 75.
* Add bluecollar employee to employee list
CALL METHOD o_bluecollar_employee1->lif_employee~add_employee
EXPORTING im_no = 1
im_name = 'Karen Johnson'
im_wage = 0.
* Create whitecollar employee obeject
CREATE OBJECT o_whitecollar_employee1
EXPORTING im_no = 2
im_name = 'John Dickens'
im_monthly_salary = 10000
im_monthly_deductions = 2500.
* Add bluecollar employee to employee list
CALL METHOD o_whitecollar_employee1->lif_employee~add_employee
EXPORTING im_no = 1
im_name = 'Gylle Karen'
im_wage = 0.
* Display employee list and number of employees. Note that the result
* will be the same when called from o_whitecollar_employee1 or
* o_bluecolarcollar_employee1, because the methods are defined
* as static (CLASS-METHODS)
CALL METHOD o_whitecollar_employee1->display_employee_list.
CALL METHOD o_whitecollar_employee1->display_no_of_employees.
4. Events
This is the same example as example 4. All changes are marked with red. There
have been no canges to the subclasses, only to the superclass and the report, sp
the code for th esubclasses is not shown.
REPORT zbc404_hf_events_4 .
*---------------------------------------------------------------------*
* INTERFACE lif_employee
*---------------------------------------------------------------------*
INTERFACE lif_employee.
METHODS:
add_employee
IMPORTING im_no TYPE i
im_name TYPE string
im_wage TYPE i.
ENDINTERFACE.
*******************************************************
* Super class LCL_CompanyEmployees
*******************************************************
CLASS lcl_company_employees DEFINITION.
PUBLIC SECTION.
TYPES:
BEGIN OF t_employee,
no TYPE i,
name TYPE string,
wage TYPE i,
END OF t_employee.
* Declare event. Note that declaration could also be placed in the
* interface
EVENTS: employee_added_to_list
EXPORTING value(ex_employee_name) TYPE string.
* CLASS-EVENTS: Events can also be defined as class-events
INTERFACES lif_employee.
METHODS:
constructor,
display_employee_list,
display_no_of_employees,
* Declare event method
on_employee_added_to_list FOR EVENT employee_added_to_list OF
lcl_company_employees
IMPORTING ex_employee_name sender.
PRIVATE SECTION.
CLASS-DATA:
i_employee_list TYPE TABLE OF t_employee,
no_of_employees TYPE i.
ENDCLASS.
*-- CLASS LCL_CompanyEmployees IMPLEMENTATION
CLASS lcl_company_employees IMPLEMENTATION.
METHOD constructor.
no_of_employees = no_of_employees + 1.
ENDMETHOD.
METHOD lif_employee~add_employee.
* Adds a new employee to the list of employees
DATA: l_employee TYPE t_employee.
l_employee-no = im_no.
l_employee-name = im_name.
l_employee-wage = im_wage.
APPEND l_employee TO i_employee_list.
* Raise event employee_added_to_list
RAISE EVENT employee_added_to_list
EXPORTING ex_employee_name = l_employee-name.
ENDMETHOD.
METHOD display_employee_list.
* Displays all employees and there wage
DATA: l_employee TYPE t_employee.
WRITE: / 'List of Employees'.
LOOP AT i_employee_list INTO l_employee.
WRITE: / l_employee-no, l_employee-name, l_employee-wage.
ENDLOOP.
ENDMETHOD.
METHOD display_no_of_employees.
* Displays total number of employees
SKIP 3.
WRITE: / 'Total number of employees:', no_of_employees.
ENDMETHOD.
METHOD on_employee_added_to_list.
* Event method
WRITE: / 'Employee added to list', ex_employee_name.
ENDMETHOD.
ENDCLASS.
*******************************************************
* Sub class LCL_BlueCollar_Employee
*******************************************************
CLASS lcl_bluecollar_employee DEFINITION
INHERITING FROM lcl_company_employees.
See code in example 3...
ENDCLASS.
CLASS lcl_bluecollar_employee IMPLEMENTATION.
See code in example 3...
ENDCLASS.
*******************************************************
* Sub class LCL_WhiteCollar_Employee
*******************************************************
CLASS lcl_whitecollar_employee DEFINITION
See code in example 3...
ENDCLASS.
CLASS lcl_whitecollar_employee IMPLEMENTATION.
See code in example 3...
ENDCLASS.
*******************************************************
* R E P O R T
*******************************************************
DATA:
* Object references
o_bluecollar_employee1 TYPE REF TO lcl_bluecollar_employee,
o_whitecollar_employee1 TYPE REF TO lcl_whitecollar_employee.
START-OF-SELECTION.
* Create bluecollar employee obeject
CREATE OBJECT o_bluecollar_employee1
EXPORTING im_no = 1
im_name = 'Karen Johnson'
im_hours = 38
im_hourly_payment = 75.
* Register event for o_bluecollar_employee1
SET HANDLER o_bluecollar_employee1->on_employee_added_to_list
FOR o_bluecollar_employee1.
* Add bluecollar employee to employee list
CALL METHOD o_bluecollar_employee1->lif_employee~add_employee
EXPORTING im_no = 1
im_name = 'Gylle Karen'
im_wage = 0.
* Create whitecollar employee obeject
CREATE OBJECT o_whitecollar_employee1
EXPORTING im_no = 2
im_name = 'John Dickens'
im_monthly_salary = 10000
im_monthly_deductions = 2500.
* Register event for o_whitecollar_employee1
SET HANDLER o_whitecollar_employee1->on_employee_added_to_list
FOR o_whitecollar_employee1.´
Result:
These classes contains methods that are enherited by subsequent classes in the
enheritance tree.
Synchronization/Flush
RFC calls is used to synchronize the front and backend. This synchronization
takes palce at some predifined points in the program flow. However you should
not rely entirely on automatic synchronization, but force synchronization with the
Flush method when necessary.
Syntax:
Application events. T
The flow logic of the screen is processed after the event (The PAI module is
processed).
In the events table the event must be registred as an application event by setting
then field appl_event to 'X':
wa_events-eventid = cl_gui_textedit=>event_double_click.
wa_events-appl_event = 'X'.
append wa_events to i_events.
Important: The dispatch method of cl_gui_cfw must be called in the PAI module:
System events.
For system events the flow-logic of the screen is not executed. That means that
the PAI and PBO modules are not processed.
In the events table the the field appl_event must be set to SAPCE:
wa_events-eventid = cl_gui_textedit=>event_double_click.
wa_events-appl_event = space.
append wa_events to i_events.
Example
Data:
* 1. Define and instance of the eventhandler class.
* If the event handler class is defined after the data decalaration
* the class must be declared as DEFERRED in the top of the program:
CLASS cls_event_handler DEFINITION DEFERRED.
go_event_handler TYPE REF TO cls_event_handler,
* 2. Define table for registration of events.
* Note that a TYPE REF to cls_event_handler must be created before you
can
* reference types cntl_simple_events and cntl_simple_event
gi_events TYPE cntl_simple_events,
* Workspace for table gi_events
g_event TYPE cntl_simple_event.
* 3. Define and implement eventhandler class
CLASS cls_event_handler DEFINITION.
PUBLIC SECTION.
METHODS:
* Syntax:
* <method name> FOR EVENT <event of control - see the control
documentation>
* OF <class of object> <importing parameters l - see the control
documentation>
on_function_selected
FOR EVENT function_selected OF cl_gui_toolbar
IMPORTING fcode,
ENDCLASS.
CLASS cls_event_handler IMPLEMENTATION.
METHOD on_function_selected.
* Do something when the event is raised
ENDMETHOD.
ENDCLASS.
* 4. Append events to the events table
* The Event Id can be found in the control documentation. Note that The event
below is registred as an application event
g_event-eventid = go_toolbar->m_id_function_selected.
g_event-appl_event = 'X'. "This is an application event
APPEND g_event TO gi_events.
.... append more events i necessary...
* 5. Use the events table to register events for the control
CALL METHOD go_toolbar->set_registered_events
EXPORTING
events = gi_events.
* 6. Create event handler
CREATE OBJECT go_event_handler.
* Syntax:
* SET HANDLER <event handler class> -> <Event handler method>
* FOR <control>
SET HANDLER go_event_handler->on_function_selected
FOR go_toolbar.
Scenario:
CLASS lcl_myclass.....
ENDCLASS.
This will cause an error because the definition of class lcl_myclass is after the
declaration.
Solution:
Define the class in the beginning of the program with DEFINITION DEFERRED:
CLASS lcl_myclass.....
ENDCLASS.
Report Z_CTRY.
Interface IShape.
Methods: getArea Returning Value(area) Type F,
getCircumference Returning Value(circumference) Type F.
Endinterface.
Public Section.
Interfaces IShape.
Private Section.
Data radius Type F.
Constants PI Type F Value '3.141592365359'.
EndClass.
Method Constructor.
radius = pRadius.
EndMethod.
Method setRadius.
radius = pRadius.
EndMethod.
Method getRadius.
pRadius = radius.
EndMethod.
Method IShape~getArea.
Compute area = 2 * PI * radius.
EndMethod.
Method IShape~getCircumference.
Compute circumference = PI * radius * radius.
EndMethod.
EndClass.
* A Square Class
Class CSquare Definition.
Public Section.
Interfaces IShape.
Private Section.
Data side Type F.
EndClass.
Method Constructor.
side = pSide.
EndMethod.
Method IShape~getArea.
Compute area = side * side.
EndMethod.
Method IShape~getCircumference.
Compute circumference = 4 * side.
EndMethod.
EndClass.
* A Rectangle Class
Class CRectangle Definition.
Public Section.
Interfaces IShape.
Private Section.
Data: height Type F,
length Type F.
EndClass.
Method Constructor.
height = pHeight.
length = pLength.
EndMethod.
Method IShape~getArea.
Compute area = height * length.
EndMethod.
Method IShape~getCircumference.
Compute circumference = 2 * ( height + length ).
EndMethod.
EndClass.
* START of PROGRAM
* Array of Shapes
Data: OneShape Type Ref To IShape, " One Object with
Shape Behaviour
ShapeTable Type Table Of Ref To IShape. " Array of Objects
with Shape Behaviour
START-OF-SELECTION.
Create Object C1 Exporting pRadius = '2.5'.
Create Object C2 Exporting pRadius = '5.0'.
Serial = 0.
Add 1 to Serial.
EndLoop.
** Results
* 1 CSQUARE
* Area 12.2500
* Circumference 14.0000
*
* 2 CRECTANGLE
* Area 10.7100
* Circumference 16.0000
*
* 3 CRECTANGLE
* Area 9.5200
* Circumference 12.4000
*
* 4 CCIRCLE
* Area 31.4159
* Circumference 78.5398
*
* 5 CCIRCLE
* Area 15.7080
* Circumference 19.6350
*
* 6 CSQUARE
* Area 36.0000
* Circumference 24.0000
Steps
1. Create a report
2. In the start of selection event add: SET SCREEN '100'.
3. Create screen 100
4. Place a custom control on the screen by choosing the custom control icon
which can be recognized by the letter 'C', and give it the name
MYCONTAINER1.
5. To be able to exit the program, add a pushbutton with the function code
EXIT.
6. In the elements list enter the name OK_CODE for the element of type OK.
The code
REPORT sapmz_hf_controls1 .
CONSTANTS:
line_length TYPE i VALUE 254.
DATA: ok_code LIKE sy-ucomm.
DATA:
* Create reference to the custom container
custom_container TYPE REF TO cl_gui_custom_container,
* Create reference to the TextEdit control
editor TYPE REF TO cl_gui_textedit,
repid LIKE sy-repid.
START-OF-SELECTION.
SET SCREEN '100'.
*---------------------------------------------------------------------*
* MODULE USER_COMMAND_0100 INPUT *
*---------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'EXIT'.
LEAVE TO SCREEN 0.
ENDCASE.
ENDMODULE. " USER_COMMAND_0100 INPUT
*&---------------------------------------------------------------------
*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------
*
MODULE status_0100 OUTPUT.
* The TextEdit control shoul only be initialized the first time the
* PBO module executes
IF editor IS INITIAL.
repid = sy-repid.
* Create obejct for custom container
CREATE OBJECT custom_container
EXPORTING
container_name = 'MYCONTAINER1'
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
others = 6
.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* Create obejct for the TextEditor control
CREATE OBJECT editor
EXPORTING
wordwrap_mode =
cl_gui_textedit=>wordwrap_at_fixed_position
wordwrap_position = line_length
wordwrap_to_linebreak_mode = cl_gui_textedit=>true
parent = custom_container
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
gui_type_not_supported = 5
others = 6
.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.
ENDMODULE. " STATUS_0100 OUTPUT
The result
1. Create an input/output field on screen 100, where the event type can be
output. Name it EVENT_TYPE
The code:
REPORT sapmz_hf_controls1 .
CONSTANTS:
line_length TYPE i VALUE 254.
DATA: ok_code LIKE sy-ucomm.
DATA:
* Create reference to the custom container
custom_container TYPE REF TO cl_gui_custom_container,
* Create reference to the TextEdit control
editor TYPE REF TO cl_gui_textedit,
repid LIKE sy-repid.
**********************************************************************
* Impmenting events
**********************************************************************
DATA:
event_type(20) TYPE c,
* Internal table for events that should be registred
i_events TYPE cntl_simple_events,
* Structure for oneline of the table
wa_events TYPE cntl_simple_event.
*---------------------------------------------------------------------*
* CLASS lcl_event_handler DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
catch_dblclick FOR EVENT dblclick
OF cl_gui_textedit IMPORTING sender.
ENDCLASS.
CLASS lcl_event_handler IMPLEMENTATION.
METHOD catch_dblclick.
event_type = 'Event DBLCLICK raised'.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
CLEAR wa_events. refresh i_events.
SET SCREEN '100'.
*---------------------------------------------------------------------*
* MODULE USER_COMMAND_0100 INPUT *
*---------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'EXIT'.
LEAVE TO SCREEN 0.
WHEN OTHERS.
* Call the Dispacth method to initiate application event handling
call method cl_gui_cfw=>Dispatch.
ENDCASE.
ENDMODULE. " USER_COMMAND_0100 INPUT
*&---------------------------------------------------------------------
*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------
*
MODULE status_0100 OUTPUT.
* The TextEdit control shoul only be initialized the first time the
* PBO module executes
IF editor IS INITIAL.
repid = sy-repid.
* Create obejct for custom container
CREATE OBJECT custom_container
EXPORTING
container_name = 'MYCONTAINER1'
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
others = 6
.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* Create obejct for the TextEditor control
CREATE OBJECT editor
EXPORTING
wordwrap_mode =
cl_gui_textedit=>wordwrap_at_fixed_position
wordwrap_position = line_length
wordwrap_to_linebreak_mode = cl_gui_textedit=>true
parent = custom_container
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
gui_type_not_supported = 5
others = 6
.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* Link the event handler method to the event and the
* TextEdit control
SET HANDLER lcl_event_handler=>catch_dblclick FOR editor.
* Register the event in the internal table i_events
wa_events-eventid = cl_gui_textedit=>event_double_click.
wa_events-appl_event = 'X'. "This is an application event
append wa_events to i_events.
* Pass the table to the TextEdit control using method
* set_registred_events
call method editor->set_registered_events
exporting events = i_events.
ENDIF.
ENDMODULE. " STATUS_0100 OUTPUT
Result:
When you double click on the TextEdit control, the input/ouput field should show
the text: Event DBLCLICK
Code:
CLASS lcl_event_handler IMPLEMENTATION.
METHOD catch_dblclick.
*--- event_type = 'Event DBLCLICK raised'.
* Reacting to the system event
call method cl_gui_cfw=>set_new_ok_code
exporting new_code = 'SHOW'.
Result:
When you double clicks on the TextEdit control nothing happens, since the flow-
logic of the screen an dthe fielde transport is ignore.
Example 4: Calling methods of the control
In this exercise a function that loads the texts of an internal table into the text
window, is implemented.
Steps:
Define anoterh pushbutton on the screen, that activates the method that fills the
TextEdit control. Give itname PUSHBUTTON_IMPORT and function code IMP.
Code:
When you double click on a text line in the TextEdit control, you want it to be
prefixed with a '*'.
The line number of the TextEdit control that is double clicked, is retreived using
method GET_SELECTION_POS. The internal text table is reloaded froim the
TextEdit control with method GET_TEXT_AS_R3TABLE. The position of the
double click in the TextEdit control is used to find the entry in the table, and the
entry is prefixed with '*' and loaded into the TextEdit control again.
The program should be changed so that the internal table i_texttable is global,
and a global flag g_loaded added. The load of the table should be moved to the
PBO module. The changes in thje code are marked with red. The whole program
now looks like this:
Code
REPORT sapmz_hf_controls1 .
CONSTANTS:
line_length TYPE i VALUE 254.
DATA: ok_code LIKE sy-ucomm.
DATA:
* Create reference to the custom container
custom_container TYPE REF TO cl_gui_custom_container,
* Create reference to the TextEdit control
editor TYPE REF TO cl_gui_textedit,
repid LIKE sy-repid.
**********************************************************************
* Utillity table to load texts
**********************************************************************
TYPES:
BEGIN OF t_texttable,
line(line_length) TYPE c,
END OF t_texttable.
DATA:
i_texttable TYPE TABLE OF t_texttable,
g_loaded(1) TYPE c.
**********************************************************************
* Impmenting events
**********************************************************************
DATA:
event_type(20) TYPE c,
* Internal table for events that should be registred
i_events TYPE cntl_simple_events,
* Structure for oneline of the table
wa_events TYPE cntl_simple_event.
*---------------------------------------------------------------------*
* CLASS lcl_event_handler DEFINITION
*---------------------------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
catch_dblclick FOR EVENT dblclick
OF cl_gui_textedit IMPORTING sender.
ENDCLASS.
CLASS lcl_event_handler IMPLEMENTATION.
METHOD catch_dblclick.
DATA:
from_line TYPE i,
from_pos TYPE i,
to_line TYPE i,
to_pos TYPE i,
wa_texttable TYPE t_texttable.
* Used for the sytem event
call method cl_gui_cfw=>set_new_ok_code
exporting new_code = 'SHOW'.
* Read the position of the double click
CALL METHOD sender->get_selection_pos
IMPORTING
from_line = from_line
from_pos = from_pos
to_line = to_line
to_pos = to_pos.
* Texts in the TextEdit control can have been changed, so
* first reload text from the control into the internal
* table that contains text
IF NOT g_loaded IS INITIAL.
CALL METHOD sender->get_text_as_r3table
IMPORTING table = i_texttable.
* Read the line of the internal table that was clicked
READ TABLE i_texttable INDEX from_line INTO wa_texttable.
IF sy-subrc <> 0.
EXIT.
ENDIF.
IF wa_texttable+0(1) CS '*'.
SHIFT wa_texttable.
ELSEIF wa_texttable+0(1) NS '*'.
SHIFT wa_texttable RIGHT.
wa_texttable+0(1) = '*'.
ENDIF.
modify i_texttable from wa_texttable index from_line.
* Reload texts from h einternal table
perform load_texts.
ENDIF.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
CLEAR wa_events.
REFRESH: i_events.
SET SCREEN '100'.
*---------------------------------------------------------------------*
* MODULE USER_COMMAND_0100 INPUT *
*---------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
CASE ok_code.
WHEN 'EXIT'.
LEAVE TO SCREEN 0.
WHEN 'SHOW'.
event_type = 'System dblclick'.
WHEN 'IMP'.
PERFORM Load_texts.
WHEN OTHERS.
* CALL METHOD cl_gui_cfw=>dispatch. "Not used for system events
ENDCASE.
ENDMODULE. " USER_COMMAND_0100 INPUT
*&---------------------------------------------------------------------
*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------
*
MODULE status_0100 OUTPUT.
* The TextEdit control shoul only be initialized the first time the
* PBO module executes
IF editor IS INITIAL.
repid = sy-repid.
* Create object for custom container
CREATE OBJECT custom_container
EXPORTING
container_name = 'MYCONTAINER1'
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
others = 6
.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* Create obejct for the TextEditor control
CREATE OBJECT editor
EXPORTING
wordwrap_mode =
cl_gui_textedit=>wordwrap_at_fixed_position
wordwrap_position = line_length
wordwrap_to_linebreak_mode = cl_gui_textedit=>true
parent = custom_container
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
gui_type_not_supported = 5
others = 6
.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* Link the event handler method to the event and the
* TextEdit control
SET HANDLER lcl_event_handler=>catch_dblclick FOR editor.
* Register the event in the internal table i_events
wa_events-eventid = cl_gui_textedit=>event_double_click.
* wa_events-appl_event = 'X'. "This is an application event
wa_events-appl_event = space. "This is a system event
APPEND wa_events TO i_events.
* Pass the table to the TextEdit control uding method
* set_registred_events
CALL METHOD editor->set_registered_events
EXPORTING events = i_events.
* Create internal table with texts taht can be uploaded to
* the TextEdit control
APPEND 'This a method that fills the TextEdit control' TO
i_texttable.
APPEND 'with a text.' TO i_texttable.
DO 10 TIMES.
APPEND 'hallo world !' TO i_texttable.
ENDDO.
ENDIF.
ENDMODULE. " STATUS_0100 OUTPUT
*&---------------------------------------------------------------------
*
*& Form Load_texts
*&---------------------------------------------------------------------
*
* This form loads the lines of the internal table i_texttable into
* the TextEdit control
*----------------------------------------------------------------------
*
FORM Load_texts.
* Load TextEdit control with texts
CALL METHOD editor->set_text_as_r3table
EXPORTING table = i_texttable.
IF sy-subrc > 0.
* Display an error message
EXIT.
ENDIF.
* All methods that operates on controls are transferred to the frontend
* by a RFC calls. the method FLUSH is used to determine when this is
* done.
CALL METHOD cl_gui_cfw=>flush.
IF sy-subrc > 0.
* Display an error message
ENDIF.
g_loaded = 'X'.
ENDFORM. " create_texts
All methods that operates on controls are transfered to the fronend by RFC calls.
The FLUSH method is used to synchronize control execution and the frontend.
This is very important when working e.g. with export parameters from a method,
as the parmeters will not be correct before the FLUSH method has been called.
The example below portects selected lines in the TextEdit and uses FLUSH to
ensure that the correct parameters are returned from method
GET_SELECTION_POS.
Steps
• Add a new pushbutton to the screen with the function code PROTECT.
Code
* Global variables
DATA:
from_idx TYPE i,
to_idx TYPE i,
index TYPE i.
MODULE user_command_0100 INPUT.
CASE ok_code.
code.......................
WHEN 'PROTECT'.
PERFORM protect.
. .......................
ENDCASE.
*&---------------------------------------------------------------------
*
*& Form protect
*&---------------------------------------------------------------------
*
* Protects marked lines in a TextEdit control
*----------------------------------------------------------------------
*
FORM protect.
* Determine the area selected by the user
CALL METHOD editor->get_selection_pos
IMPORTING
from_line = from_idx
to_line = to_idx
EXCEPTIONS
error_cntl_call_method = 1.
* Synchronize execution in the control with the ABAP program.
* Without this synchronization the variables from_idx and
* to_idx will have obsolutete values (The initial value for
* both, are 0)
CALL METHOD cl_gui_cfw=>flush.
IF sy-subrc > 0.
* Errormessage: Error in flush
ENDIF.
* Protect the selected lines
IF to_idx > from_idx.
to_idx = to_idx - 1.
ENDIF.
CALL METHOD editor->protect_lines
EXPORTING
from_line = from_idx
to_line = to_idx.
* The PROTECT_SELECTION method could be used instead, eliminating the
* need of line numbers and the last FLUSH
In this example a second TextEdit control will be added to the screen. The new
TextEdit control will be designed to act as a clipboard for short texts.
Steps:
Code:
Insert global datadeclaration:
**********************************************************************
* Implementing a second Scratch TextEdit control
**********************************************************************
DATA:
scratch TYPE REF TO cl_gui_textedit,
custom_container2 TYPE REF TO cl_gui_custom_container.
*------------------------------------------------------
* The SCRATCH TextEdit control
*------------------------------------------------------
IF scratch IS INITIAL.
* Create obejct for custom container2
CREATE OBJECT custom_container2
EXPORTING
container_name = 'MYCONTAINER2'
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
others = 6
.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* Create obejct for the SCRATCH TextEditor control
CREATE OBJECT scratch
EXPORTING
parent = custom_container2
wordwrap_mode =
cl_gui_textedit=>wordwrap_at_windowborder
wordwrap_to_linebreak_mode = cl_gui_textedit=>true.
* Remove the staus bar
CALL METHOD scratch->set_statusbar_mode
EXPORTING statusbar_mode = cl_gui_textedit=>false.
ENDIF.
Result:
1 REPORT sapmz_hf_controls1 .
2
3 CONSTANTS:
4 line_length TYPE i VALUE 254.
5
6 DATA: ok_code LIKE sy-ucomm.
7
8 DATA:
9 * Create reference to the custom container
10 custom_container TYPE REF TO cl_gui_custom_container,
11 * Create reference to the TextEdit control
12 editor TYPE REF TO cl_gui_textedit,
13 repid LIKE sy-repid.
14
15
**********************************************************************
16 * Utillity table to load texts
17
**********************************************************************
18 TYPES:
19 BEGIN OF t_texttable,
20 line(line_length) TYPE c,
21 END OF t_texttable.
22
23 DATA:
24 i_texttable TYPE TABLE OF t_texttable,
25 wa_texttable TYPE t_texttable,
26 g_loaded(1) TYPE c.
27
28
**********************************************************************
29 * Data for the protection example
30
**********************************************************************
31 DATA:
32 from_idx TYPE i,
33 to_idx TYPE i,
34 index TYPE i.
35
36
**********************************************************************
37 * Implementing a second Scratch TextEdit control
38
**********************************************************************
39 DATA:
40 scratch TYPE REF TO cl_gui_textedit,
41 custom_container2 TYPE REF TO cl_gui_custom_container.
42
43
44
**********************************************************************
45 * Implementing events
46
**********************************************************************
47 DATA:
48 event_type(20) TYPE c,
49 * Internal table for events that should be registred
50 i_events TYPE cntl_simple_events,
51 * Structure for oneline of the table
52 wa_events TYPE cntl_simple_event.
53
54 *-------------------------------------------------------------
--------*
55 * CLASS lcl_event_handler DEFINITION
56 *-------------------------------------------------------------
--------*
57 * ........
*
58 *-------------------------------------------------------------
--------*
59 CLASS lcl_event_handler DEFINITION.
60 PUBLIC SECTION.
61 CLASS-METHODS:
62 catch_dblclick FOR EVENT dblclick
63 OF cl_gui_textedit IMPORTING sender.
64
65 ENDCLASS.
66
67 *-------------------------------------------------------------
--------*
68 * CLASS lcl_event_handler IMPLEMENTATION
69 *-------------------------------------------------------------
--------*
70 * ........
*
71 *-------------------------------------------------------------
--------*
72 CLASS lcl_event_handler IMPLEMENTATION.
73 METHOD catch_dblclick.
74 DATA:
75 from_line TYPE i,
76 from_pos TYPE i,
77 to_line TYPE i,
78 to_pos TYPE i.
79
80
81 * Used for the sytem event
82 CALL METHOD cl_gui_cfw=>set_new_ok_code
83 EXPORTING new_code = 'SHOW'.
84
85
86 * Read the position of the double click
87 CALL METHOD sender->get_selection_pos
88 IMPORTING
89 from_line = from_line
90 from_pos = from_pos
91 to_line = to_line
92 to_pos = to_pos.
93
94 * Texts in the TextEdit control can have been changed, so
95 * first reload text from the control into the internal
96 * table that contains text
97 IF NOT g_loaded IS INITIAL.
98 CALL METHOD sender->get_text_as_r3table
99 IMPORTING table = i_texttable.
100 * Read the line of the internal table that was clicked
101 READ TABLE i_texttable INDEX from_line INTO
wa_texttable.
102 IF sy-subrc <> 0.
103 EXIT.
104 ENDIF.
105
106 IF wa_texttable+0(1) CS '*'.
107 SHIFT wa_texttable.
108 ELSEIF wa_texttable+0(1) NS '*'.
109 SHIFT wa_texttable RIGHT.
110 wa_texttable+0(1) = '*'.
111 ENDIF.
112 MODIFY i_texttable FROM wa_texttable INDEX from_line.
113 * Reload texts from h einternal table
114 PERFORM load_texts.
115
116
117 ENDIF.
118
119
120 ENDMETHOD.
121 ENDCLASS.
122
123
124
125 START-OF-SELECTION.
126 CLEAR wa_events.
127 REFRESH: i_events.
128
129 SET SCREEN '100'.
130
131
132
133 *-------------------------------------------------------------
--------*
134 * MODULE USER_COMMAND_0100 INPUT
*
135 *-------------------------------------------------------------
--------*
136 MODULE user_command_0100 INPUT.
137
138 CASE ok_code.
139 WHEN 'EXIT'.
140 LEAVE TO SCREEN 0.
141 WHEN 'SHOW'.
142 event_type = 'System dblclick'.
143 WHEN 'IMP'.
144 PERFORM load_texts.
145 WHEN 'PROTECT'.
146 PERFORM protect.
147
148 WHEN OTHERS.
149 * CALL METHOD cl_gui_cfw=>dispatch. "Not used for system
events
150 ENDCASE.
151
152
153 ENDMODULE. " USER_COMMAND_0100 INPUT
154 *&------------------------------------------------------------
---------*
155 *& Module STATUS_0100 OUTPUT
156 *&------------------------------------------------------------
---------*
157 MODULE status_0100 OUTPUT.
158 * The TextEdit control shoul only be initialized the first
time the
159 * PBO module executes
160 IF editor IS INITIAL.
161 repid = sy-repid.
162 * Create obejct for custom container
163 CREATE OBJECT custom_container
164 EXPORTING
165 container_name = 'MYCONTAINER1'
166 EXCEPTIONS
167 cntl_error = 1
168 cntl_system_error = 2
169 create_error = 3
170 lifetime_error = 4
171 lifetime_dynpro_dynpro_link = 5
172 others = 6
173 .
174 IF sy-subrc <> 0.
175 MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
176 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
177 ENDIF.
178
179 * Create obejct for the TextEditor control
180 CREATE OBJECT editor
181 EXPORTING
182
183 wordwrap_mode =
184 cl_gui_textedit=>wordwrap_at_fixed_position
185 wordwrap_position = line_length
186 wordwrap_to_linebreak_mode = cl_gui_textedit=>true
187 parent = custom_container
188 EXCEPTIONS
189 error_cntl_create = 1
190 error_cntl_init = 2
191 error_cntl_link = 3
192 error_dp_create = 4
193 gui_type_not_supported = 5
194 others = 6
195 .
196 IF sy-subrc <> 0.
197 MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
198 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
199 ENDIF.
200
201 * Link the event handler method to the event and the
202 * TextEdit control
203 SET HANDLER lcl_event_handler=>catch_dblclick FOR editor.
204
205 * Register the event in the internal table i_events
206 wa_events-eventid = cl_gui_textedit=>event_double_click.
207
208 * wa_events-appl_event = 'X'. "This is an application event
209 wa_events-appl_event = space. "This is a system event
210
211
212 APPEND wa_events TO i_events.
213 * Pass the table to the TextEdit control uding method
214 * set_registred_events
215 CALL METHOD editor->set_registered_events
216 EXPORTING events = i_events.
217
218 * Create internal table with texts taht can be uploaded to
219 * the TextEdit control
220 APPEND 'This a method that fills the TextEdit control' TO
i_texttable.
221 APPEND 'with a text.' TO i_texttable.
222 DO 10 TIMES.
223 APPEND 'hallo world !' TO i_texttable.
224 ENDDO.
225 ENDIF.
226
227 *------------------------------------------------------
228 * The SCRATCH TextEdit control
229 *------------------------------------------------------
230 IF scratch IS INITIAL.
231 * Create obejct for custom container2
232 CREATE OBJECT custom_container2
233 EXPORTING
234 container_name = 'MYCONTAINER2'
235 EXCEPTIONS
236 cntl_error = 1
237 cntl_system_error = 2
238 create_error = 3
239 lifetime_error = 4
240 lifetime_dynpro_dynpro_link = 5
241 others = 6
242 .
243 IF sy-subrc <> 0.
244 MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
245 WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
246 ENDIF.
247
248 * Create obejct for the SCRATCH TextEditor control
249 CREATE OBJECT scratch
250 EXPORTING
251 parent = custom_container2
252 wordwrap_mode =
253 cl_gui_textedit=>wordwrap_at_windowborder
254 wordwrap_to_linebreak_mode = cl_gui_textedit=>true.
255
256 * Remove the staus bar
257 CALL METHOD scratch->set_statusbar_mode
258 EXPORTING statusbar_mode = cl_gui_textedit=>false.
259
260 ENDIF.
261
262
263 ENDMODULE. " STATUS_0100 OUTPUT
264
265 *&------------------------------------------------------------
---------*
266 *& Form Load_texts
267 *&------------------------------------------------------------
---------*
268 * This form loads the lines of the internal table i_texttable
into
269 * the TextEdit control
270 *-------------------------------------------------------------
---------*
271 FORM load_texts.
272
273 * Load TextEdit control with texts
274 CALL METHOD editor->set_text_as_r3table
275 EXPORTING table = i_texttable.
276 IF sy-subrc > 0.
277 * Display an error message
278 EXIT.
279 ENDIF.
280
281 * All methods that operates on controls are transferred to the
frontend
282 * by a RFC calls. the method FLUSH is used to determine when
this is
283 * done.
284 CALL METHOD cl_gui_cfw=>flush.
285 IF sy-subrc > 0.
286 * Display an error message
287 ENDIF.
288 g_loaded = 'X'.
289 ENDFORM. " create_texts
290 *&------------------------------------------------------------
---------*
291 *& Form protect
292 *&------------------------------------------------------------
---------*
293 * Protects marked lines in a TextEdit control
294 *-------------------------------------------------------------
---------*
295 FORM protect.
296 * Determine the area selected by the user
297 CALL METHOD editor->get_selection_pos
298 IMPORTING
299 from_line = from_idx
300 to_line = to_idx
301 EXCEPTIONS
302 error_cntl_call_method = 1.
303
304 * Synchronize execution in the control with the ABAP program.
305 * Without this synchronization the variables from_idx and
306 * to_idx will have obsolutete values (The initial value for
307 * both, are 0)
308 CALL METHOD cl_gui_cfw=>flush.
309 IF sy-subrc > 0.
310 * Errormessage: Error in flush
311 ENDIF.
312
313 * Protect the lines selected
314 IF to_idx > from_idx.
315 to_idx = to_idx - 1.
316 ENDIF.
317 CALL METHOD editor->protect_lines
318 EXPORTING
319 from_line = from_idx
320 to_line = to_idx.
321
322
323 * The PROTECT_SELECTION method could be used instead,
eliminating the
324 * need of line numbers and the last FLUSH
325
326 * call method editor->protect_selection.
327
328
329 * Flush again to protect immidately
330 CALL METHOD cl_gui_cfw=>flush.
331 IF sy-subrc > 0.
332 * Errormessage: Error in flush
333 ENDIF.
334
335
336
337 ENDFORM. " protect