[ABAP] Beispiel für die Verwendung von CL_COLUMN_TREE_MODEL

* Demoprogramm: SAPCOLUMN_TREE_CONTROL_DEMO
* http://saphelp.ucc.ovgu.de/NW750/EN/4d/88f020981740abe10000000a15822b/frameset.htm
* Eventhandler-Klasse
CLASS lcl_events DEFINITION.
  PUBLIC SECTION.

    TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

    CLASS-METHODS: on_button_click FOR EVENT button_click OF cl_column_tree_model
      IMPORTING
          node_key
          item_name
          sender.

    CLASS-METHODS: on_link_click FOR EVENT link_click OF cl_column_tree_model
      IMPORTING
          node_key
          item_name
          sender.

    CLASS-METHODS: on_checkbox_change FOR EVENT checkbox_change OF cl_column_tree_model
      IMPORTING
          node_key
          item_name
          checked
          sender.

    CLASS-METHODS: on_header_click FOR EVENT header_click OF cl_column_tree_model
      IMPORTING
          header_name
          sender.

ENDCLASS.

CLASS lcl_events IMPLEMENTATION.

  METHOD on_button_click.
    MESSAGE node_key && '_' && item_name TYPE 'S'.
  ENDMETHOD.

  METHOD on_link_click.
    MESSAGE node_key && '_' && item_name TYPE 'S'.
  ENDMETHOD.

  METHOD on_checkbox_change.
    MESSAGE node_key && '_' && item_name && '_' && checked TYPE 'S'.
  ENDMETHOD.

  METHOD on_header_click.
    MESSAGE header_name TYPE 'S'.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
* Tree-Control erzeugen
* item_selection = abap_true wegen der CheckBoxen
  DATA(o_tree) = NEW cl_column_tree_model( node_selection_mode   = cl_column_tree_model=>node_sel_mode_single
                                           hierarchy_column_name = 'FOLDER'
                                           hierarchy_header      = VALUE #( t_image = icon_folder
                                                                            heading = 'Beispiel'
                                                                            tooltip = 'Tooltip'
                                                                            width   = 30
                                                                          )
                                           item_selection        = abap_true
                                         ).
* Spalten hinzufügen
  o_tree->add_column( EXPORTING
                        name                = 'COL1'
                        width               = 30
                        header_text         = 'Column1' ).

  o_tree->add_column( EXPORTING
                        name                = 'COL2'
                        width               = 30
                        header_text         = 'Column2' ).

* in default_screen einbetten
  o_tree->create_tree_control( parent = cl_gui_container=>default_screen ).

* Beispielhaft Nodes und Subnodes erzeugen
  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE1'
                      relative_node_key = ''
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_folder )
                      image             = CONV tv_image( icon_folder )
                      item_table        = VALUE #( ( class     = cl_column_tree_model=>item_class_checkbox
                                                     item_name = 'FOLDER'
                                                     text      = 'Obj1'
                                                     editable  = abap_true
                                                   )
                                                 )
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE1_1'
                      relative_node_key = 'NODE1'
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_oo_object )
                      image             = CONV tv_image( icon_oo_object )
                      item_table        = VALUE #( ( class     = cl_column_tree_model=>item_class_link
                                                     item_name = 'FOLDER'
                                                     text      = 'Obj4'
                                                   )
                                                   ( class     = cl_column_tree_model=>item_class_text
                                                     item_name = 'COL1'
                                                     text      = 'Wert1'
                                                     style     = cl_column_tree_model=>style_intensified
                                                     font      = cl_column_tree_model=>item_font_prop
                                                   )
                                                   ( class     = cl_column_tree_model=>item_class_text
                                                     item_name = 'COL2'
                                                     text      = 'Wert2'
                                                   )
                                                 )
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE2'
                      relative_node_key = ''
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_folder )
                      image             = CONV tv_image( icon_folder )
                      item_table        = VALUE #( ( class     = cl_column_tree_model=>item_class_checkbox
                                                     item_name = 'FOLDER'
                                                     text      = 'Obj2'
                                                     editable  = abap_true
                                                   )
                                                 )
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE2_1'
                      relative_node_key = 'NODE2'
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_oo_object )
                      image             = CONV tv_image( icon_oo_object )
                      item_table        = VALUE #( ( class     = cl_column_tree_model=>item_class_button
                                                     item_name = 'FOLDER'
                                                     text      = 'Obj3'
                                                   )
                                                   ( class     = cl_column_tree_model=>item_class_text
                                                     item_name = 'COL1'
                                                     text      = 'Wert1'
                                                     style     = cl_column_tree_model=>style_inactive
                                                     font      = cl_column_tree_model=>item_font_prop
                                                   )
                                                   ( class     = cl_column_tree_model=>item_class_text
                                                     item_name = 'COL2'
                                                     text      = 'Wert2'
                                                   )
                                                 )
                  ).

* Nodes expandieren
  o_tree->expand_root_nodes( expand_subtree = abap_true
                             level_count = 10 ).

* Events registrieren
* ITEM_DOUBLE_CLICK	           Doppelklick auf Item
* BUTTON_CLICK                 Drucktaste wurde gedrückt
* LINK_CLICK                   Link geklickt
* CHECKBOX_CHANGE              Zustandsänderung einer Checkbox
* ITEM_KEYPRESS                Taste wurde gedrückt, Item war selektiert
* HEADER_CLICK                 Header geklickt
* ITEM_CONTEXT_MENU_REQUEST    Anforderung eines Kontext-Menüs für ein Item
* ITEM_CONTEXT_MENU_SELECT     Kontext-Menü Eintrag wurde ausgewählt
* HEADER_CONTEXT_MENU_REQUEST  Anforderung eines Kontext-Menüs für einen Header
* HEADER_CONTEXT_MENU_SELECT   Kontext-Menü Eintrag wurde ausgewählt
* DRAG                         Ereignis zum Füllen des Drag Drop Daten - Objekts
* DRAG_MULTIPLE                Ereignis zum Füllen des Drag Drop Daten - Objekts
* DROP_COMPLETE                Ereignis nach erfolgreichem Drop
* DROP_COMPLETE_MULTIPLE       Ereignis nach erfolgreichem Drop
  SET HANDLER lcl_events=>on_button_click FOR o_tree.
  SET HANDLER lcl_events=>on_checkbox_change FOR o_tree.
  SET HANDLER lcl_events=>on_header_click FOR o_tree.
  SET HANDLER lcl_events=>on_link_click FOR o_tree.

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE lcl_events=>ty_it_events(
                                                    ( eventid = cl_column_tree_model=>eventid_button_click
                                                      appl_event = abap_true )
                                                    ( eventid = cl_column_tree_model=>eventid_checkbox_change
                                                      appl_event = abap_true )
                                                    ( eventid = cl_column_tree_model=>eventid_header_click
                                                      appl_event = abap_true )
                                                    ( eventid = cl_column_tree_model=>eventid_link_click
                                                      appl_event = abap_true )
                                                  ).

  o_tree->set_registered_events( events = it_events ).

* Erzeugung von cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] Beispiel für die Verwendung von CL_LIST_TREE_MODEL

* Demoprogramm: SAP_LIST_TREE_MODEL_DEMO
* http://saphelp.ucc.ovgu.de/NW750/EN/4d/88f020981740abe10000000a15822b/frameset.htm
* Eventhandler-Klasse
CLASS lcl_events DEFINITION.
  PUBLIC SECTION.

    TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

    CLASS-METHODS: on_button_click FOR EVENT button_click OF cl_list_tree_model
      IMPORTING
          node_key
          item_name
          sender.

    CLASS-METHODS: on_link_click FOR EVENT link_click OF cl_list_tree_model
      IMPORTING
          node_key
          item_name
          sender.

    CLASS-METHODS: on_checkbox_change FOR EVENT checkbox_change OF cl_list_tree_model
      IMPORTING
          node_key
          item_name
          checked
          sender.

    CLASS-METHODS: on_header_click FOR EVENT header_click OF cl_list_tree_model
      IMPORTING
          header_name
          sender.

ENDCLASS.

CLASS lcl_events IMPLEMENTATION.

  METHOD on_button_click.
    MESSAGE node_key && '_' && item_name TYPE 'S'.
  ENDMETHOD.

  METHOD on_link_click.
    MESSAGE node_key && '_' && item_name TYPE 'S'.
  ENDMETHOD.

  METHOD on_checkbox_change.
    MESSAGE node_key && '_' && item_name && '_' && checked TYPE 'S'.
  ENDMETHOD.

  METHOD on_header_click.
    MESSAGE header_name TYPE 'S'.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
* Tree-Control erzeugen
* item_selection = abap_true wegen der CheckBoxen
  DATA(o_tree) = NEW cl_list_tree_model( node_selection_mode = cl_list_tree_model=>node_sel_mode_single
                                         item_selection      = abap_true
                                         with_headers        = abap_true
                                         hierarchy_header      = VALUE #( t_image = icon_folder
                                                                          heading = 'Beispiel'
                                                                          tooltip = 'Tooltip'
                                                                          width   = 80
                                                                        )
                                       ).

* in default_screen einbetten
  o_tree->create_tree_control( parent = cl_gui_container=>default_screen ).

* Beispielhaft Nodes und Subnodes erzeugen
  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE1'
                      relative_node_key = ''
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_folder )
                      image             = CONV tv_image( icon_folder )
                      item_table        = VALUE #( ( class     = cl_list_tree_model=>item_class_checkbox
                                                     item_name = '1'
                                                     text      = 'Obj1'
                                                     editable  = abap_true
                                                     length    = 10
                                                   )
                                                 )
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_false
                      node_key          = 'NODE1_1'
                      relative_node_key = 'NODE1'
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_oo_object )
                      image             = CONV tv_image( icon_oo_object )
                      item_table        = VALUE #( ( class     = cl_list_tree_model=>item_class_link
                                                     item_name = '1'
                                                     text      = 'Obj4'
                                                     length    = 10
                                                   )
                                                   ( class     =  cl_list_tree_model=>item_class_text
                                                     item_name = '2'
                                                     text      = 'Wert1'
                                                     length    = 10
                                                   )
                                                   ( class     =  cl_list_tree_model=>item_class_text
                                                     item_name = '3'
                                                     text      = 'Wert2'
                                                     length    = 10
                                                     alignment = cl_list_tree_model=>align_auto
                                                     font      = cl_list_tree_model=>item_font_prop
                                                   )
                                                 )
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_true
                      node_key          = 'NODE2'
                      relative_node_key = ''
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_folder )
                      image             = CONV tv_image( icon_folder )
                      item_table        = VALUE #( ( class     = cl_list_tree_model=>item_class_checkbox
                                                     item_name = '1'
                                                     text      = 'Obj2'
                                                     editable  = abap_true
                                                     length    = 10
                                                   )
                                                 )
                  ).

  o_tree->add_node( EXPORTING
                      isfolder          = abap_false
                      node_key          = 'NODE2_1'
                      relative_node_key = 'NODE2'
                      relationship      = cl_tree_model=>relat_last_child
                      expanded_image    = CONV tv_image( icon_oo_object )
                      image             = CONV tv_image( icon_oo_object )
                      item_table        = VALUE #( ( class     = cl_list_tree_model=>item_class_button
                                                     item_name = '1'
                                                     text      = 'Obj3'
                                                     length    = 10
                                                   )
                                                   ( class     =  cl_list_tree_model=>item_class_text
                                                     item_name = '2'
                                                     text      = 'Wert1'
                                                     length    = 10
                                                   )
                                                   ( class     =  cl_list_tree_model=>item_class_text
                                                     item_name = '3'
                                                     text      = 'Wert2'
                                                     length    = 10
                                                     alignment = cl_list_tree_model=>align_auto
                                                     font      = cl_list_tree_model=>item_font_prop
                                                   )
                                                 )
                  ).

* Nodes expandieren
  o_tree->expand_root_nodes( expand_subtree = abap_true
                             level_count = 10 ).

* Events registrieren
* ITEM_DOUBLE_CLICK	           Doppelklick auf Item
* BUTTON_CLICK                 Drucktaste wurde gedrückt
* LINK_CLICK                   Link geklickt
* CHECKBOX_CHANGE              Zustandsänderung einer Checkbox
* ITEM_KEYPRESS                Taste wurde gedrückt, Item war selektiert
* HEADER_CLICK                 Header geklickt
* ITEM_CONTEXT_MENU_REQUEST    Anforderung eines Kontext-Menüs für ein Item
* ITEM_CONTEXT_MENU_SELECT     Kontext-Menü Eintrag wurde ausgewählt
* HEADER_CONTEXT_MENU_REQUEST  Anforderung eines Kontext-Menüs für einen Header
* HEADER_CONTEXT_MENU_SELECT   Kontext-Menü Eintrag wurde ausgewählt
* DRAG                         Ereignis zum Füllen des Drag Drop Daten - Objekts
* DRAG_MULTIPLE                Ereignis zum Füllen des Drag Drop Daten - Objekts
* DROP_COMPLETE                Ereignis nach erfolgreichem Drop
* DROP_COMPLETE_MULTIPLE       Ereignis nach erfolgreichem Drop
  SET HANDLER lcl_events=>on_button_click FOR o_tree.
  SET HANDLER lcl_events=>on_checkbox_change FOR o_tree.
  SET HANDLER lcl_events=>on_header_click FOR o_tree.
  SET HANDLER lcl_events=>on_link_click FOR o_tree.

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE lcl_events=>ty_it_events(
                                                    ( eventid = cl_list_tree_model=>eventid_button_click
                                                      appl_event = abap_true )
                                                    ( eventid = cl_list_tree_model=>eventid_checkbox_change
                                                      appl_event = abap_true )
                                                    ( eventid = cl_list_tree_model=>eventid_header_click
                                                      appl_event = abap_true )
                                                    ( eventid = cl_list_tree_model=>eventid_link_click
                                                      appl_event = abap_true )
                                                  ).

  o_tree->set_registered_events( events = it_events ).

* Erzeugung von cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] Erweiterte Baumansicht mit einem cl_gui_column_tree, Eventhandling

* Demoprogramm: SAPCOLUMN_TREE_CONTROL_DEMO

CONSTANTS: co_root TYPE tv_nodekey VALUE 'Root'.
CONSTANTS: co_auart TYPE tv_itmname VALUE 'Auftragsart'.
CONSTANTS: co_matnr TYPE tv_itmname VALUE 'Mat.-Nr.'.
CONSTANTS: co_arktx TYPE tv_itmname VALUE 'Kurztext'.
CONSTANTS: co_netwr TYPE tv_itmname VALUE 'Wert'.
CONSTANTS: co_flag TYPE tv_itmname VALUE 'Flag'.

DATA: it_nodes TYPE treev_ntab.
DATA: it_items TYPE STANDARD TABLE OF mtreeitm WITH DEFAULT KEY.

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

TYPES: BEGIN OF ty_vbak_vbap,
         auart TYPE vbak-auart,
         vbeln TYPE vbak-vbeln,
         posnr TYPE vbap-posnr,
         matnr TYPE vbap-matnr,
         arktx TYPE vbap-arktx,
         netwr TYPE vbap-netwr,
         flag  TYPE boolean,
       END OF ty_vbak_vbap.

TYPES: ty_it_vbak_vbap TYPE STANDARD TABLE OF ty_vbak_vbap WITH DEFAULT KEY.

* Eventhandlerklasse
CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_node_double_click FOR EVENT node_double_click OF cl_gui_column_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_item_double_click FOR EVENT item_double_click OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_column_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_header_click FOR EVENT header_click OF cl_gui_column_tree
      IMPORTING
          header_name
          sender.
    CLASS-METHODS: on_button_click FOR EVENT button_click OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          sender.
    CLASS-METHODS: on_link_click FOR EVENT link_click OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          sender.
    CLASS-METHODS: on_checkbox_change FOR EVENT checkbox_change OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          checked
          sender.
    CLASS-METHODS: on_dft_context_menu_req FOR EVENT default_context_menu_request OF cl_gui_column_tree
      IMPORTING
          menu
          sender.
    CLASS-METHODS: on_dft_context_menu_sel FOR EVENT default_context_menu_select OF cl_gui_column_tree
      IMPORTING
          fcode
          sender.
    CLASS-METHODS: on_node_context_menu_req FOR EVENT node_context_menu_request OF cl_gui_column_tree
      IMPORTING
          node_key
          menu
          sender.
    CLASS-METHODS: on_node_context_menu_sel FOR EVENT node_context_menu_select OF cl_gui_column_tree
      IMPORTING
          node_key
          fcode
          sender.
    CLASS-METHODS: on_item_context_menu_req FOR EVENT item_context_menu_request OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          menu
          sender.
    CLASS-METHODS: on_item_context_menu_sel FOR EVENT item_context_menu_select OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          fcode
          sender.
    CLASS-METHODS: on_header_context_menu_req FOR EVENT header_context_menu_request OF cl_gui_column_tree
      IMPORTING
          header_name
          menu
          sender.
    CLASS-METHODS: on_header_context_menu_sel FOR EVENT header_context_menu_select OF cl_gui_column_tree
      IMPORTING
          header_name
          fcode
          sender.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
* Doppelklick auf Icon
  METHOD on_node_double_click.
    MESSAGE node_key TYPE 'S'.
  ENDMETHOD.
* Doppelklick auf Item
  METHOD on_item_double_click.

    CASE item_name.
* wenn Item für Wert NETWR editiert werden soll
      WHEN co_netwr.
* Text aus der Nodes-Tabelle lesen
        ASSIGN it_items[ node_key = node_key item_name = item_name ] TO FIELD-SYMBOL(<i>).

        DATA: lv_changed TYPE as4flag.
        DATA: lv_value TYPE string.

        lv_value = condense( <i>-text ).

* Popup für Werte-Eingabe
        CALL FUNCTION 'CC_POPUP_STRING_INPUT'
          EXPORTING
            property_name = 'NETWR:'
          IMPORTING
            value_changed = lv_changed
          CHANGING
            string_value  = lv_value.

        IF lv_changed = abap_true.
* Text in der Item Table anpassen
          <i>-text = lv_value.

* Text in der Node anpassen
          sender->item_set_text( node_key  = node_key
                                 item_name = item_name
                                 text      = |{ <i>-text }| ).
        ENDIF.
    ENDCASE.

    MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
* hier können evtl. Daten nachgeladen werden
  METHOD on_expand_no_children.
    MESSAGE node_key TYPE 'S'.
  ENDMETHOD.
* Header-Klick
  METHOD on_header_click.
    MESSAGE |{ header_name }| TYPE 'S'.
  ENDMETHOD.
* Button-Klick
  METHOD on_button_click.
    MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
  ENDMETHOD.
* Link-Klick
  METHOD on_link_click.
    MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
  ENDMETHOD.
* Checkbox Change
  METHOD on_checkbox_change.
    MESSAGE |{ item_name }_{ node_key }: { checked }| TYPE 'S'.
  ENDMETHOD.
* Freier Klickbereich: Kontextmenu füllen
  METHOD on_dft_context_menu_req.

    menu->add_function( text = 'Message'
                        fcode = 'MSG' ).

    menu->add_function( text = 'Exit'
                        fcode = 'EXIT' ).

  ENDMETHOD.
* Freier Klickbereich: Klick im Kontextmenu auswerten
  METHOD on_dft_context_menu_sel.

    CASE fcode.

      WHEN 'MSG'.
        MESSAGE 'Message' TYPE 'S'.
      WHEN 'EXIT'.
        LEAVE PROGRAM.

    ENDCASE.

  ENDMETHOD.
* Node: Kontextmenu füllen
  METHOD on_node_context_menu_req.

    menu->add_function( text = |{ node_key }|
                        fcode = 'NODE' ).

  ENDMETHOD.
* Node: Klick im Kontextmenu auswerten
  METHOD on_node_context_menu_sel.

    CASE fcode.

      WHEN 'NODE'.
        MESSAGE node_key TYPE 'S'.

    ENDCASE.

  ENDMETHOD.
* Item: Kontextmenu füllen
  METHOD on_item_context_menu_req.

    menu->add_function( text = |{ node_key }_{ item_name }|
                        fcode = 'NODE_ITEM' ).

  ENDMETHOD.
* Item: Klick im Kontextmenu auswerten
  METHOD on_item_context_menu_sel.

    CASE fcode.

      WHEN 'NODE_ITEM'.
        MESSAGE |{ node_key }_{ item_name }| TYPE 'S'.

    ENDCASE.

  ENDMETHOD.
* Header: Kontextmenu füllen
  METHOD on_header_context_menu_req.

    menu->add_function( text = |{ header_name }|
                        fcode = 'HEADER' ).

  ENDMETHOD.
* Header: Klick im Kontextmenu auswerten
  METHOD on_header_context_menu_sel.

    CASE fcode.

      WHEN 'HEADER'.
        MESSAGE |{ header_name }| TYPE 'S'.

    ENDCASE.

  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA: it_vbak_vbap TYPE ty_it_vbak_vbap.

* Daten holen -> bei zu vielen Elementen (-> 450?) kommt es zum Absturz der Trees
  SELECT vbak~auart, vbak~vbeln, vbap~posnr, vbap~matnr, vbap~arktx, vbap~netwr FROM vbak
    INNER JOIN vbap ON vbak~vbeln = vbap~vbeln
    INTO CORRESPONDING FIELDS OF TABLE @it_vbak_vbap
    UP TO 100 ROWS.

  SORT: it_vbak_vbap BY auart vbeln posnr.

* 1. Spalte des Trees
  DATA(lv_thhdr) = VALUE treev_hhdr( heading = co_auart
                                     width   = 50 ).

* Tree-Objekt im default_screen einbetten
  DATA(o_tree) = NEW cl_gui_column_tree( parent                = cl_gui_container=>default_screen
                                         node_selection_mode   = cl_gui_column_tree=>node_sel_mode_single
                                         item_selection        = abap_true
                                         hierarchy_column_name = co_auart
                                         hierarchy_header      = lv_thhdr ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_column_tree=>eventid_node_double_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_item_double_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_expand_no_children
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_link_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_button_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_checkbox_change
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_header_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_def_context_menu_req
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_node_context_menu_req
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_item_context_menu_req
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_header_context_men_req
                                          appl_event = abap_true ) ).

* Events registrieren
  o_tree->set_registered_events( events = it_events ).

* Eventhandler für Klicks und Kontextmenüs
  SET HANDLER lcl_event=>on_node_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_item_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_expand_no_children FOR o_tree.
  SET HANDLER lcl_event=>on_header_click FOR o_tree.
  SET HANDLER lcl_event=>on_button_click FOR o_tree.
  SET HANDLER lcl_event=>on_link_click FOR o_tree.
  SET HANDLER lcl_event=>on_checkbox_change FOR o_tree.
  SET HANDLER lcl_event=>on_dft_context_menu_req FOR o_tree.
  SET HANDLER lcl_event=>on_dft_context_menu_sel FOR o_tree.
  SET HANDLER lcl_event=>on_node_context_menu_req FOR o_tree.
  SET HANDLER lcl_event=>on_node_context_menu_sel FOR o_tree.
  SET HANDLER lcl_event=>on_item_context_menu_req FOR o_tree.
  SET HANDLER lcl_event=>on_item_context_menu_sel FOR o_tree.
  SET HANDLER lcl_event=>on_header_context_menu_req FOR o_tree.
  SET HANDLER lcl_event=>on_header_context_menu_sel FOR o_tree.

* weitere Spalten entsprechend der Reihenfolge
  o_tree->add_column( name        = co_matnr
                      width       = 30
                      header_text = CONV #( co_matnr ) ).

  o_tree->add_column( name        = co_arktx
                      width       = 70
                      header_text = CONV #( co_arktx ) ).

  o_tree->add_column( name        = co_netwr
                      width       = 30
                      header_text = CONV #( co_netwr ) ).

  o_tree->add_column( name        = co_flag
                      width       = 5
                      header_text = CONV #( co_flag ) ).

* Inhalt des Trees komplett löschen
*  o_tree->delete_all_nodes( ).

* Rootnode einfügen
  it_nodes = VALUE #( ( node_key  = co_root
                        isfolder  = abap_true ) ).

* Items der Rootnode
  it_items = VALUE #( ( node_key  = co_root
                        item_name = co_auart
                        class     = cl_gui_column_tree=>item_class_text
                        text      = co_root
                        font      = cl_gui_column_tree=>item_font_fixed
                        style     = cl_gui_column_tree=>style_intensified )

                      ( node_key  = co_root
                        item_name = co_matnr
                        class     = cl_gui_column_tree=>item_class_text
                        text      = '' )

                      ( node_key  = co_root
                        item_name = co_arktx
                        class     = cl_gui_column_tree=>item_class_text
                        text      = '' )

                      ( node_key  = co_root
                        item_name = co_netwr
                        class     = cl_gui_column_tree=>item_class_text
                        text      = '' )

                      ( node_key  = co_root
                        item_name = co_flag
                        class     = cl_gui_column_tree=>item_class_text
                        text      = '' ) ).

* Unternodes: Auftragsarten <a> -> Belege <v> -> Positionen <p>
  LOOP AT it_vbak_vbap ASSIGNING FIELD-SYMBOL(<a>) GROUP BY <a>-auart ASCENDING.
* Node für Auftragsarten
    APPEND VALUE #( node_key  = <a>-auart
                    relatkey  = co_root
                    relatship = cl_gui_column_tree=>relat_last_child
                    isfolder  = abap_true
                    expander  = abap_true ) TO it_nodes.

* Items für Auftragsarten
    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_auart
                    class     = cl_gui_column_tree=>item_class_text
                    text      = <a>-auart
                    font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_matnr
                    class     = cl_gui_column_tree=>item_class_text
                    text      = '' ) TO it_items.

    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_arktx
                    class     = cl_gui_column_tree=>item_class_text
                    text      = '' ) TO it_items.

    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_netwr
                    class     = cl_gui_column_tree=>item_class_text
                    text      = '' ) TO it_items.

    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_flag
                    class     = cl_gui_column_tree=>item_class_text
                    text      = '' ) TO it_items.

    LOOP AT GROUP <a> ASSIGNING FIELD-SYMBOL(<v>) GROUP BY <v>-vbeln ASCENDING.
* Node für Belegnummern
      APPEND VALUE #( node_key  = <v>-vbeln
                      relatkey  = <a>-auart
                      relatship = cl_gui_column_tree=>relat_last_child
                      isfolder  = abap_true
                      expander  = abap_true ) TO it_nodes.

* Items für Belegnummern
      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_auart
                      class     = cl_gui_column_tree=>item_class_text
                      text      = <v>-vbeln
                      font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_matnr
                      class     = cl_gui_column_tree=>item_class_text
                      text      = '' ) TO it_items.

      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_arktx
                      class     = cl_gui_column_tree=>item_class_text
                      text      = '' ) TO it_items.

      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_flag
                      class     = cl_gui_column_tree=>item_class_text
                      text      = '' ) TO it_items.

      DATA(lv_sum_netwr) = VALUE vbap-netwr( ).
      DATA(lv_cnt) = 0.

      LOOP AT GROUP <v> ASSIGNING FIELD-SYMBOL(<p>).
* Node für Positionen
* eindeutigen Key erzeugen (max. 12 Zeichen lang)
        DATA(lv_pos_key) = |{ <p>-vbeln ALPHA = OUT }{ <p>-posnr ALPHA = OUT }|.
        APPEND VALUE #( node_key  = lv_pos_key
                        relatkey  = <v>-vbeln
                        relatship = cl_gui_column_tree=>relat_last_child
                        isfolder  = abap_false
                        expander  = abap_false ) TO it_nodes.

* Items für Positionen
        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_auart
                        class     = cl_gui_column_tree=>item_class_button
                        text      = <p>-posnr
                        font      = cl_gui_column_tree=>item_font_default ) TO it_items.

        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_matnr
                        class     = cl_gui_column_tree=>item_class_link
                        text      = <p>-matnr
                        style     = cl_gui_column_tree=>style_intensified
                        font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_arktx
                        class     = cl_gui_column_tree=>item_class_text
                        text      = <p>-arktx
                        font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_netwr
                        class     = cl_gui_column_tree=>item_class_text
                        text      = CONV string( <p>-netwr )
                        font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_flag
                        class     = cl_gui_column_tree=>item_class_checkbox
                        editable  = abap_true
                        text      = <p>-flag ) TO it_items.

* Summierung des NETWR für übergeordnetes Item
        lv_sum_netwr = lv_sum_netwr + <p>-netwr.
        lv_cnt = lv_cnt + 1.
      ENDLOOP.

* Ausgabe der Summe in Item für Position
      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_netwr
                      class     = cl_gui_column_tree=>item_class_text
                      text      = |Summe: { lv_sum_netwr } ({ lv_cnt })|
                      font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

    ENDLOOP.
  ENDLOOP.

* Nodes und Items zum Baum hinzufügen und anzeigen
  o_tree->add_nodes_and_items( node_table                = it_nodes
                               item_table                = it_items
                               item_table_structure_name = 'MTREEITM' ). " Typ muss gleich mit Zeilentyp von it_items sein

* Root-Nodes des Trees expandieren
  o_tree->expand_root_nodes( ).

* Spaltenbreiten anpassen
*  o_tree->adjust_column_width( all_columns     = abap_true
*                               include_heading = abap_true ).

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Erzwingung der Listenausgabe in cl_gui_container=>default_screen und Anzeige des Trees
  WRITE space.

[ABAP] Tree und SALV-Grid auf dem Selektionsbild ohne zus. Dynpro anzeigen, Eventhandling

**********************************************************************
*
* Datentypen, Variablen, Konstanten
*
**********************************************************************
TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
TYPES: ty_it_nodes TYPE STANDARD TABLE OF mtreesnode WITH DEFAULT KEY.

DATA: o_splitter_main TYPE REF TO cl_gui_splitter_container.
DATA: o_container_l   TYPE REF TO cl_gui_container.
DATA: o_container_r   TYPE REF TO cl_gui_container.
DATA: o_tree TYPE REF TO cl_gui_simple_tree.
DATA: o_salv TYPE REF TO cl_salv_table.

DATA: it_tree_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_salv_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_nodes TYPE ty_it_nodes.
**********************************************************************
*
* Eventhandler
*
**********************************************************************
CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
    IF o_salv IS BOUND.
* Element in der Nodes-Tabelle lesen
      ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).

* iTab für SALV-Table neu aufbauen, abhängig vom gewählten Baumelement
      it_salv_spfli = VALUE #( FOR l IN it_tree_spfli WHERE ( carrid = <fs_node>-text )
                               ( mandt = l-mandt
                                 carrid = l-carrid
                                 connid = l-connid
                                 countryfr = l-countryfr
                                 cityfrom = l-cityfrom
                                 airpfrom = l-airpfrom
                                 countryto = l-countryto
                                 cityto = l-cityto
                                 airpto = l-airpto
                                 fltime = l-fltime
                                 deptime = l-deptime
                                 arrtime = l-arrtime
                                 distance = l-distance
                                 distid = l-distid
                                 fltype = l-fltype
                                 period = l-period ) ).

* SALV-Table neu anzeigen
      o_salv->refresh( ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.
**********************************************************************
*
* SELECTION-SCREEN
*
**********************************************************************
* leeres Selektionsbild als Dummy für die Container-Objekte (o_splitter_main ...)
SELECTION-SCREEN BEGIN OF SCREEN 2000.
SELECTION-SCREEN END OF SCREEN 2000.
**********************************************************************
*
* INITIALIZATION
*
**********************************************************************
INITIALIZATION.
  SELECT * INTO TABLE it_tree_spfli FROM spfli.
**********************************************************************
*
* START-OF-SELECTION
*
**********************************************************************
START-OF-SELECTION.
* leeres Selektionbild 2000 anzeigen
  CALL SELECTION-SCREEN 2000.
**********************************************************************
*
* AT SELECTION-SCREEN OUTPUT
*
**********************************************************************
AT SELECTION-SCREEN OUTPUT.
* Doppelte Objekterzeugung unterbinden
  IF NOT o_splitter_main IS BOUND.
* Splitter auf default_screen (SELECTION-SCREEN 2000) erzeugen
    o_splitter_main = NEW #( parent  = cl_gui_container=>default_screen
                             rows    = 1
                             columns = 2 ).

* Breite in % (linke Spalte für den Tree)
    o_splitter_main->set_column_width( id = 1 width = 15 ).

* linken und rechten Splitcontainer holen
    o_container_l = o_splitter_main->get_container( row = 1 column = 1 ).
    o_container_r = o_splitter_main->get_container( row = 1 column = 2 ).

* Tree-Objekt erzeugen
    o_tree = NEW #( parent = o_container_l
                    node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).

* Eventtypten müssen gesondert registriert werden
    DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_selection_changed
                                            appl_event = abap_true ) ).

    o_tree->set_registered_events( events = it_events ).

    SET HANDLER lcl_events=>on_selection_changed FOR o_tree.

* Root-Node einfügen
    it_nodes = VALUE #( ( node_key  = 'ROOT'           " Node-Bezeichner
                          relatship = cl_gui_simple_tree=>relat_last_child
                          disabled  = abap_true
                          isfolder  = abap_true        " Typ Ordner für Root-Element
                          n_image   = icon_folder      " Icon Ordner
                          exp_image = icon_open_folder " Icon geöffneter Ordner
                          style     = cl_gui_simple_tree=>style_default
                          text      = 'Airlines' ) ).

* Childs an Root-Node anhängen
    LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>).
* bei Änderung der carrid neue carrid als Child anhängen
      AT NEW carrid.
        APPEND VALUE #( node_key  = |NODE{ sy-tabix }| " Node-Bezeichner
                        relatship = cl_gui_simple_tree=>relat_last_child
                        relatkey  = 'ROOT'             " an ROOT-Element anhängen
                        style     = cl_gui_simple_tree=>style_intensified
                        text      = |{ <fs_line>-carrid }| ) TO it_nodes.
      ENDAT.
    ENDLOOP.

* Nodes im Baum einfügen
    o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                       node_table           = it_nodes ).

* Root-Nodes des Trees expandieren
    o_tree->expand_root_nodes( ).

* leeres SALV-Grid erzeugen
    cl_salv_table=>factory( EXPORTING
                              r_container    = o_container_r
                            IMPORTING
                              r_salv_table   = o_salv
                            CHANGING
                              t_table        = it_salv_spfli ).

    o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
    o_salv->get_columns( )->set_optimize( abap_true ).
    o_salv->get_functions( )->set_all( ).
    o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
    o_salv->display( ).
  ENDIF.
**********************************************************************
*
* AT SELECTION-SCREEN
*
**********************************************************************
AT SELECTION-SCREEN.
* wenn "Ausführen" (F8) geklickt wurde
  IF sy-ucomm = 'CRET'.
* Selektionbild 2000 wieder anzeigen
    CALL SELECTION-SCREEN 2000.
  ENDIF.

[ABAP] Baumstruktur mit Hilfe des cl_gui_list_tree anzeigen, Events abfangen

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

DATA: it_nodes TYPE treev_ntab.
DATA: it_items TYPE STANDARD TABLE OF mtreeitm WITH DEFAULT KEY.

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_node_double_click FOR EVENT node_double_click OF cl_gui_list_tree
      IMPORTING
          node_key.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_list_tree
      IMPORTING
          node_key.
    CLASS-METHODS: on_item_double_click FOR EVENT item_double_click OF cl_gui_list_tree
      IMPORTING
          node_key
          item_name.
    CLASS-METHODS: on_button_click FOR EVENT button_click OF cl_gui_list_tree
      IMPORTING
          node_key
          item_name.
    CLASS-METHODS: on_link_click FOR EVENT link_click OF cl_gui_list_tree
      IMPORTING
          node_key
          item_name.
    CLASS-METHODS: on_checkbox_change FOR EVENT checkbox_change OF cl_gui_list_tree
      IMPORTING
          node_key
          item_name
          checked.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
  METHOD on_node_double_click.
    WRITE: / |Node double click on node: { node_key }|.
  ENDMETHOD.

  METHOD on_item_double_click.
    WRITE: / |Item double click on node: { node_key }, item: { item_name }|.
  ENDMETHOD.

  METHOD on_link_click.
    WRITE: / |Link click on node: { node_key }, item: { item_name }|.
  ENDMETHOD.

  METHOD on_button_click.
    WRITE: / |Button click on node: { node_key }, item: { item_name }|.
  ENDMETHOD.

  METHOD on_checkbox_change.
    WRITE: / |Checkbox change on node: { node_key }, item: { item_name }|.
  ENDMETHOD.

  METHOD on_expand_no_children.
    WRITE: / |Expand no children on node: { node_key }|.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

* Container-Objekt erzeugen
  DATA(o_dock) = NEW cl_gui_docking_container( no_autodef_progid_dynnr = abap_true
                                               side = cl_gui_docking_container=>dock_at_left
                                               ratio = 20
                                               caption = 'Datenausgabe' ).

* Tree-Objekt erzeugen
  DATA(o_tree) = NEW cl_gui_list_tree( parent = o_dock
                                       node_selection_mode = cl_gui_list_tree=>node_sel_mode_single
                                       item_selection = abap_true
                                       with_headers = abap_false ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid    = cl_gui_list_tree=>eventid_node_double_click
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_item_double_click
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_expand_no_children
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_link_click
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_button_click
                                          appl_event = abap_true )
                                        ( eventid    = cl_gui_list_tree=>eventid_checkbox_change
                                          appl_event = abap_true ) ).

  o_tree->set_registered_events( events = it_events ).

  SET HANDLER lcl_event=>on_node_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_item_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_expand_no_children FOR o_tree.
  SET HANDLER lcl_event=>on_link_click FOR o_tree.
  SET HANDLER lcl_event=>on_button_click FOR o_tree.
  SET HANDLER lcl_event=>on_checkbox_change FOR o_tree.

* Tree-Nodes einfügen -> die Bezeichner müssen eindeutig sein
  it_nodes = VALUE #( ( node_key  = 'ROOT'
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_true )

                      ( node_key  = 'NODE1'
                        relatkey  = 'ROOT'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_true )

                      ( node_key  = 'NODE1_1'
                        relatkey  = 'NODE1'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false )

                      ( node_key  = 'NODE1_2'
                        relatkey  = 'NODE1'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false )

                      ( node_key  = 'NODE1_3'
                        relatkey  = 'NODE1'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false )

                      ( node_key  = 'NODE2'
                        relatkey  = 'ROOT'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false )

                      ( node_key  = 'NODE3'
                        relatkey  = 'ROOT'
                        relatship = cl_gui_list_tree=>relat_last_child
                        hidden    = abap_false
                        disabled  = abap_false
                        isfolder  = abap_false ) ).

* Items für die Nodes definieren
  it_items = VALUE #( ( node_key  = 'ROOT'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_text
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Root'
                        t_image   = icon_led_green )
* Ordner
                      ( node_key  = 'NODE1'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_text
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Node 1'
                        t_image   = icon_led_yellow )
* Item Button
                      ( node_key  = 'NODE1_1'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_button
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Node 1_1'
                        t_image   = icon_led_green )
* Item Checkbox
                      ( node_key  = 'NODE1_2'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_checkbox
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Node 1_2'
                        t_image   = icon_led_green
                        editable  = abap_true )
* Item Link
                      ( node_key  = 'NODE1_3'
                        item_name = '1'
                        style     = cl_gui_list_tree=>style_default
                        class     = cl_gui_list_tree=>item_class_link
                        alignment = cl_gui_list_tree=>align_auto
                        font      = cl_gui_list_tree=>item_font_fixed
                        text      = 'Node 1_3'
                        t_image   = icon_led_green )
* Item mit 4 Spalten
                      ( node_key   = 'NODE2'
                        item_name  = '1'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_auto
                        font       = cl_gui_list_tree=>item_font_fixed
                        text       = ''
                        t_image    = icon_led_green
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE2'
                        item_name  = '2'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_left
                        font       = cl_gui_list_tree=>item_font_fixed
                        length     = 4
                        text       = '1000'
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE2'
                        item_name  = '3'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_left
                        font       = cl_gui_list_tree=>item_font_fixed
                        length     = 10
                        text       = 'Liter'
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE2'
                        item_name  = '4'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_auto
                        font       = cl_gui_list_tree=>item_font_prop
                        text       = 'Testeintrag 1' )
* Item mit 4 Spalten
                      ( node_key   = 'NODE3'
                        item_name  = '1'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_auto
                        font       = cl_gui_list_tree=>item_font_fixed
                        text       = ''
                        t_image    = icon_led_green
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE3'
                        item_name  = '2'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_left
                        font       = cl_gui_list_tree=>item_font_fixed
                        length     = 4
                        text       = '0100'
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE3'
                        item_name  = '3'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_left
                        font       = cl_gui_list_tree=>item_font_fixed
                        length     = 10
                        text       = 'mm'
                        usebgcolor = abap_true )

                      ( node_key   = 'NODE3'
                        item_name  = '4'
                        style      = cl_gui_list_tree=>style_default
                        class      = cl_gui_list_tree=>item_class_text
                        alignment  = cl_gui_list_tree=>align_auto
                        font       = cl_gui_list_tree=>item_font_prop
                        text       = 'Testeintrag 2' ) ).

  o_tree->add_nodes_and_items( node_table                = it_nodes
                               item_table                = it_items
                               item_table_structure_name = 'MTREEITM' ). " Typ muss gleich mit Zeilentyp von it_items sein

* Root-Nodes des Trees expandieren
  o_tree->expand_root_nodes( ).

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe und Anzeige des Trees

Weiterführende Infos: Link und Link

[ABAP] GUI-Simple-Tree und SALV-Grid in Split-Container ohne Dynpro anzeigen, Eventhandling

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
TYPES: ty_it_nodes TYPE STANDARD TABLE OF mtreesnode WITH DEFAULT KEY.

DATA: o_salv TYPE REF TO cl_salv_table.
DATA: it_tree_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_salv_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_nodes TYPE ty_it_nodes.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
* GUI Simple Tree
    CLASS-METHODS: on_keypress FOR EVENT node_keypress OF cl_gui_simple_tree
      IMPORTING
          node_key
          key
          sender.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
* ALV-Events für das SALV-Grid
    CLASS-METHODS: on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING
          e_object
          sender.
    CLASS-METHODS: on_user_command FOR EVENT user_command OF cl_gui_alv_grid
      IMPORTING
          e_ucomm
          sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Tastendruck
  METHOD on_keypress.
    MESSAGE |Node: { node_key } Taste: { key }| TYPE 'S'.
  ENDMETHOD.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
* Element in der Nodes-Tabelle lesen
    ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).

* iTab für SALV-Table neu aufbauen
    CLEAR: it_salv_spfli.

    LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>) WHERE carrid = <fs_node>-text.
      APPEND <fs_line> TO it_salv_spfli.
    ENDLOOP.

* SALV-Table neu anzeigen
    o_salv->refresh( ).
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
  METHOD on_expand_no_children.
    MESSAGE |Node: { node_key }| TYPE 'S'.
  ENDMETHOD.

* Toolbar-Buttons hinzufügen:
* butn_type   Bezeichung
* 0           Button (normal)
* 1           Menü + Defaultbutton
* 2           Menü
* 3           Separator
* 4           Radiobutton
* 5           Auswahlknopf (Checkbox)
* 6           Menüeintrag
  METHOD on_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Daten anzeigen' icon = icon_icon_list function = 'SHOW_DATA' quickinfo = 'Daten anzeigen' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.
* Benutzerkommando (Button-Klick)
  METHOD on_user_command.
    CASE e_ucomm.
      WHEN 'SHOW_DATA'.
        DATA: lv_row TYPE i. " Zeile auf Grid
        DATA: lv_value TYPE char255. " Wert
        DATA: lv_col TYPE i. " Spalte auf Grid
        DATA: lv_row_id TYPE lvc_s_row. " Zeilen-Id
        DATA: lv_col_id TYPE lvc_s_col. " Spalten-Id
        DATA: lv_row_no TYPE lvc_s_roid. " Numerische Zeilen ID

        sender->get_current_cell( IMPORTING
                                    e_row = lv_row
                                    e_value = lv_value
                                    e_col = lv_col
                                    es_row_id = lv_row_id
                                    es_col_id = lv_col_id
                                    es_row_no = lv_row_no ).

        MESSAGE |Zeile: { lv_row }, Spalte: { lv_col }, Wert: { lv_value }, Spaltenname: { lv_col_id-fieldname }| TYPE 'S'.
    ENDCASE.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

  SELECT * INTO TABLE it_tree_spfli FROM spfli.

* Splitter auf screen0 erzeugen
  DATA(o_split) = NEW cl_gui_splitter_container( parent = cl_gui_container=>screen0
                                                 no_autodef_progid_dynnr = abap_true
                                                 rows = 1
                                                 columns = 2 ).

* Breite in % (linke Spalte für den Tree)
  o_split->set_column_width( id = 1 width = 15 ).

* linken und rechten Splitcontainer holen
  DATA(o_spl_left) = o_split->get_container( row = 1 column = 1 ).
  DATA(o_spl_right) = o_split->get_container( row = 1 column = 2 ).

  TRY.
* Tree-Objekt erzeugen
      DATA(o_tree) = NEW cl_gui_simple_tree( parent = o_spl_left
                                             node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).


* Eventtypten müssen gesondert registriert werden
      DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_node_keypress
                                              appl_event = abap_true )
                                            ( eventid = cl_gui_simple_tree=>eventid_selection_changed
                                              appl_event = abap_true )
                                            ( eventid = cl_gui_simple_tree=>eventid_expand_no_children
                                              appl_event = abap_true ) ).

      o_tree->set_registered_events( events = it_events ).

      o_tree->add_key_stroke( cl_gui_simple_tree=>key_enter ).

* Events registrieren
      SET HANDLER lcl_events=>on_keypress FOR o_tree.
      SET HANDLER lcl_events=>on_selection_changed FOR o_tree.
      SET HANDLER lcl_events=>on_expand_no_children FOR o_tree.

* Root-Node einfügen
      it_nodes = VALUE #( ( node_key  = 'ROOT'           " Node-Bezeichner
                            relatship = cl_gui_simple_tree=>relat_last_child
                            disabled  = abap_true
                            isfolder  = abap_true        " Typ Ordner für Root-Element
                            n_image   = icon_folder      " Icon Ordner
                            exp_image = icon_open_folder " Icon geöffneter Ordner
                            style     = cl_gui_simple_tree=>style_default
                            text      = 'Airlines' ) ).

* Childs an Root-Node anhängen
      LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>).
* bei Änderung der carrid neue carrid als Child anhängen
        AT NEW carrid.
          APPEND VALUE #( node_key  = |NODE{ sy-tabix }| " eindeutiger Node-Bezeichner
                          relatship = cl_gui_simple_tree=>relat_last_child
                          relatkey  = 'ROOT'             " an ROOT-Element anhängen
                          style     = cl_gui_simple_tree=>style_intensified
                          text      = |{ <fs_line>-carrid }| ) TO it_nodes.
        ENDAT.
      ENDLOOP.

* Nodes im Baum einfügen
      o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                         node_table           = it_nodes ).

* Root-Nodes des Trees expandieren
      o_tree->expand_root_nodes( ).

* leeres SALV-Grid erzeugen
      cl_salv_table=>factory( EXPORTING
                                r_container    = o_spl_right
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_salv_spfli ).

      o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
      o_salv->get_columns( )->set_optimize( abap_true ).
      o_salv->get_functions( )->set_all( ).
      o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
      o_salv->display( ).

* Trick: Aus dem Split-Container rechts das Grid-Objekt holen und nach cl_gui_alv_grid casten
      READ TABLE o_spl_right->children INDEX 1 ASSIGNING FIELD-SYMBOL(<child>).
      IF <child> IS ASSIGNED.
        DATA(o_alv_grid) = CAST cl_gui_alv_grid( <child> ).

* Eventhandler registrieren
        SET HANDLER lcl_events=>on_toolbar FOR o_alv_grid.
        SET HANDLER lcl_events=>on_user_command FOR o_alv_grid.
      ENDIF.

    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* cl_gui_container=>screen0 erzwingen
  WRITE space.

[ABAP] Baumstruktur mit Hilfe des cl_gui_simple_tree anzeigen, Events abfangen

* Demoprogramme
* RSDEMO_DRAG_DROP_EDIT_TREE
* RSDEMO_DRAG_DROP_TREE_MULTI
* SAPSIMPLE_TREE_CONTROL_DEMO

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.
TYPES: ty_it_nodes TYPE STANDARD TABLE OF mtreesnode WITH DEFAULT KEY.

DATA: it_nodes TYPE ty_it_nodes.

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_keypress FOR EVENT node_keypress OF cl_gui_simple_tree
      IMPORTING
          node_key
          key
          sender.
    CLASS-METHODS: on_double_click FOR EVENT node_double_click OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
* Tastendruck, die Tasten müssen mit add_key_stroke( ) registriert worden sein
  METHOD on_keypress.
    WRITE: / |Node: { node_key } Taste: { key }|.
  ENDMETHOD.
* Doppelklick auf ein aktives Baumelement
  METHOD on_double_click.
* Text in der Nodes-Tabelle anpassen
    ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).
    <fs_node>-text = 'Schonmal geklickt.'.

* Text in der Node anpassen
    sender->node_set_text( node_key = node_key text = <fs_node>-text ).

    WRITE: / |Node: { node_key }, Text: { <fs_node>-text }|.
  ENDMETHOD.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
    WRITE: / |Node: { node_key }|.
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
  METHOD on_expand_no_children.
    WRITE: / |Node: { node_key }|.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

* Container-Objekt erzeugen
  DATA(o_dock) = NEW cl_gui_docking_container( no_autodef_progid_dynnr = abap_true
                                               side = cl_gui_docking_container=>dock_at_left
                                               ratio = 15
                                               caption = 'Datenausgabe' ).

* Tree-Objekt erzeugen
  DATA(o_tree) = NEW cl_gui_simple_tree( parent = o_dock
                                         node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_node_keypress )
*                                        ( eventid = cl_gui_simple_tree=>eventid_node_double_click )
                                        ( eventid = cl_gui_simple_tree=>eventid_selection_changed )
                                        ( eventid = cl_gui_simple_tree=>eventid_expand_no_children
                                          appl_event = abap_true ) ).

  o_tree->set_registered_events( events = it_events ).

* benötigte Tasten registrieren
*cl_gui_simple_tree=>key_f1: F1
*cl_gui_simple_tree=>key_f4: F4
*cl_gui_simple_tree=>key_insert: Einfügen
*cl_gui_simple_tree=>key_delete: Entfernen
*cl_gui_simple_tree=>key_enter: Enter
*cl_gui_simple_tree=>key_cut: Strg+X
*cl_gui_simple_tree=>key_copy: Strg+C
*cl_gui_simple_tree=>key_paste: Strg+V

  o_tree->add_key_stroke( cl_gui_simple_tree=>key_enter ).
  o_tree->add_key_stroke( cl_gui_simple_tree=>key_f1 ).
  o_tree->add_key_stroke( cl_gui_simple_tree=>key_delete ).

* Events registrieren, on_double_click und on_selection_changed
* dürfen nicht gleichzeitig registriert sein, sonst Exception
  SET HANDLER lcl_event=>on_keypress FOR o_tree.
*  SET HANDLER lcl_event=>on_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_selection_changed FOR o_tree.
  SET HANDLER lcl_event=>on_expand_no_children FOR o_tree.

* Tree-Nodes einfügen -> die Bezeichner müssen eindeutig sein
  it_nodes = VALUE #( ( node_key  = 'FLDR1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        disabled  = abap_true
                        isfolder  = abap_true
                        n_image   = icon_folder
                        exp_image = icon_open_folder
                        style     = cl_gui_simple_tree=>style_default
                        text      = 'Ordner' )

                      ( node_key  = 'NODE1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        disabled  = abap_true
                        isfolder  = abap_true
                        relatkey  = 'FLDR1'
                        n_image   = icon_folder
                        exp_image = icon_open_folder
                        style     = cl_gui_simple_tree=>style_intensified
                        text      = 'Datensatz 1' )

                      ( node_key  = 'NODE1_1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'NODE1'
                        n_image   = icon_led_yellow
                        style     = cl_gui_simple_tree=>style_intensified
                        text      = 'Datensatz 1_1' )

                      ( node_key  = 'NODE2'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        n_image   = icon_led_green
                        style     = cl_gui_simple_tree=>style_default
                        text      = 'Datensatz 2' )

                      ( node_key  = 'NODE3'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        disabled  = abap_true
                        n_image   = icon_led_inactive
                        style     = cl_gui_simple_tree=>style_inactive
                        text      = 'Datensatz 3 (inaktiv)' )

                      ( node_key  = 'NODE4'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        disabled  = abap_false
                        n_image   = icon_led_red
                        style     = cl_gui_simple_tree=>style_intensifd_critical
                        text      = 'Datensatz 4' ) ).

  o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                     node_table           = it_nodes ).

* Root-Nodes des Trees expandieren
  o_tree->expand_root_nodes( ).

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe und Anzeige des Trees

Weiterführende Infos: Link und Link