[ABAP] GUI-Toolbar mit statischem Context-Menü, Eventhandling

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

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
        IMPORTING
            fcode
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Toolbar: Button oder Menüpunkt geklickt
  METHOD on_function_selected.

* Funktionscode auswerten
    CASE fcode.
      WHEN 'BTN_CLOSE'.
        LEAVE PROGRAM.
      WHEN 'M1'.
      WHEN 'M2'.
    ENDCASE.

* fcode ausgeben
    MESSAGE fcode TYPE 'S'.

  ENDMETHOD.
ENDCLASS.

INITIALIZATION.

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 24 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 24 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id    = 1
                            type  = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id    = 1
                            type  = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).

* Toolbar hoizontal
  DATA(o_tool) = NEW cl_gui_toolbar( parent       = o_container_top
                                     display_mode = cl_gui_toolbar=>m_mode_horizontal ).

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

  o_tool->set_registered_events( events = it_events ).

* Toolbar-Buttons und Menüs hinzufügen
* Buttontypen sind in Typgruppe CNTB definiert
  o_tool->add_button( fcode       = 'BTN_MENU'
                      icon        = icon_activate
                      butn_type   = cntb_btype_menu
                      text        = 'Menü'
                      quickinfo   = 'Menü anzeigen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* statisches Kontextmenü für Button "BTN_MENU" erstellen
  DATA(o_menu) = NEW cl_ctmenu( ).
  o_menu->add_function( fcode   = 'M1'
                        checked = abap_false
                        text    = 'Punkt1' ).

  o_menu->add_function( fcode   = 'M2'
                        checked = abap_false
                        text    = 'Punkt2' ).

* statisches Kontextmenü mit Button verknüpfen, Zuordnung erfolgt über den Namen
* daher muss "function" gleich "fcode" des Menü-Buttons sein, sonst Exception
  DATA(it_ctxmenu) = VALUE ttb_btnmnu( ( function = 'BTN_MENU'
                                         ctmenu   = o_menu ) ).

* siehe auch Methode "set_static_ctxmenu"
  o_tool->assign_static_ctxmenu_table( it_ctxmenu ).

* Separator
  o_tool->add_button( fcode       = ''
                      icon        = ''
                      butn_type   = cntb_btype_sep
                      text        = ''
                      quickinfo   = ''
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Schließen-Button
  o_tool->add_button( fcode       = 'BTN_CLOSE'
                      icon        = icon_close
                      butn_type   = cntb_btype_button
                      text        = 'Schließen'
                      quickinfo   = 'Schließen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Eventhandler registrieren
  SET HANDLER lcl_events=>on_function_selected FOR o_tool.

* im unteren Splitter Beispieldaten anzeigen
  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

  DATA: o_salv TYPE REF TO cl_salv_table.

  cl_salv_table=>factory( EXPORTING
                            r_container  = o_container_bottom
                          IMPORTING
                            r_salv_table = o_salv
                          CHANGING
                            t_table      = it_sflight ).

  o_salv->get_functions( )->set_all( ).
  o_salv->display( ).

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

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

[ABAP] GUI-Toolbar mit dynamischen Context-Menü, Eventhandling, Umschaltung checked-state

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

TYPES: BEGIN OF ty_menuitem,
         fcode   TYPE ui_func,
         checked TYPE cua_active,
         text    TYPE gui_text,
       END OF ty_menuitem.

TYPES: ty_it_menuitems TYPE STANDARD TABLE OF ty_menuitem WITH DEFAULT KEY.

DATA: it_menuitems TYPE ty_it_menuitems.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
        IMPORTING
            fcode
            sender.
    CLASS-METHODS:
      on_dropdown_clicked FOR EVENT dropdown_clicked OF cl_gui_toolbar
        IMPORTING
            fcode
            posx
            posy
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Toolbar: Button oder Menüpunktgeklickt
  METHOD on_function_selected.

* Checked-Status eines Dropdown-Menüpunktes umschalten
    IF line_exists( it_menuitems[ fcode = fcode ] ).
      ASSIGN it_menuitems[ fcode = fcode ] TO FIELD-SYMBOL(<mc>).
      <mc>-checked = COND #( WHEN <mc>-checked = abap_true THEN abap_false ELSE abap_true ).
    ENDIF.

* Funktionscode auswerten
    CASE fcode.
      WHEN 'BTN_CLOSE'.
        LEAVE PROGRAM.
      WHEN 'BTN_DROP'.
      WHEN 'M1'.
      WHEN 'M2'.
    ENDCASE.

* fcode ausgeben
    MESSAGE fcode TYPE 'S'.

  ENDMETHOD.
* Toolbar: Dropdown aktiviert
  METHOD on_dropdown_clicked.
* Menü erzeugen
    DATA(o_ctx_menu) = NEW cl_ctmenu( ).

    LOOP AT it_menuitems ASSIGNING FIELD-SYMBOL(<m>).
      o_ctx_menu->add_function( fcode   = <m>-fcode
                                checked = <m>-checked
                                text    = <m>-text ).
    ENDLOOP.

* Kontextmenü an der akt. Position anzeigen
    sender->track_context_menu( context_menu = o_ctx_menu
                                posx         = posx
                                posy         = posy ).
  ENDMETHOD.
ENDCLASS.

INITIALIZATION.

  it_menuitems = VALUE #( ( fcode   = 'M1'
                            checked = abap_false
                            text    = 'Punkt1' )
                          ( fcode   = 'M2'
                            checked = abap_true
                            text    = 'Punkt2' ) ).

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 24 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 24 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).

* Toolbar hoizontal
  DATA(o_tool) = NEW cl_gui_toolbar( parent = o_container_top
                                     display_mode = cl_gui_toolbar=>m_mode_horizontal ).

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

  o_tool->set_registered_events( events = it_events ).

* Toolbar-Buttons hinzufügen
* Buttontypen sind in Typgruppe CNTB definiert
  o_tool->add_button( fcode       = 'BTN_DROP'
                      icon        = icon_activate
                      butn_type   = cntb_btype_dropdown
                      text        = 'Menü'
                      quickinfo   = 'Menü anzeigen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = ''
                      icon        = ''
                      butn_type   = cntb_btype_sep
                      text        = ''
                      quickinfo   = ''
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = 'BTN_CLOSE'
                      icon        = icon_close
                      butn_type   = cntb_btype_button
                      text        = 'Schließen'
                      quickinfo   = 'Schließen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Eventhandler registrieren
  SET HANDLER lcl_events=>on_function_selected FOR o_tool.
  SET HANDLER lcl_events=>on_dropdown_clicked FOR o_tool.

* im unteren Splitter Beispieldaten anzeigen
  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

  DATA: o_salv TYPE REF TO cl_salv_table.

  cl_salv_table=>factory( EXPORTING
                            r_container    = o_container_bottom
                          IMPORTING
                            r_salv_table   = o_salv
                          CHANGING
                            t_table        = it_sflight ).

  o_salv->get_functions( )->set_all( ).
  o_salv->display( ).

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

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

Weiterführender Link zur Ideen-Quelle: Link

[ABAP] Eigene GUI-Toolbar in einem Split-Container anzeigen, Eventhandling

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

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
        IMPORTING
            fcode
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Toolbar Button geklickt
  METHOD on_function_selected.

    CASE fcode.
      WHEN 'BTN_CLOSE'.
        LEAVE PROGRAM.
      WHEN 'BTN_TEST'.
        MESSAGE 'TEST' TYPE 'I' DISPLAY LIKE 'S'.
    ENDCASE.

  ENDMETHOD.

ENDCLASS.

INITIALIZATION.

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 24 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 24 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).

* Toolbar hoizontal
  DATA(o_tool) = NEW cl_gui_toolbar( parent = o_container_top
                                     display_mode = cl_gui_toolbar=>m_mode_horizontal ).

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

  o_tool->set_registered_events( events = it_events ).

* Toolbar-Buttons hinzufügen
* Buttontypen sind in Typgruppe CNTB definiert
  o_tool->add_button( fcode       = 'BTN_TEST'
                      icon        = icon_activate
                      butn_type   = cntb_btype_button
                      text        = 'Test'
                      quickinfo   = 'Test'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = ''
                      icon        = ''
                      butn_type   = cntb_btype_sep
                      text        = ''
                      quickinfo   = ''
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = 'BTN_CLOSE'
                      icon        = icon_close
                      butn_type   = cntb_btype_button
                      text        = 'Schließen'
                      quickinfo   = 'Schließen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Eventhandler registrieren
  SET HANDLER lcl_events=>on_function_selected FOR o_tool.

* im unteren Splitter Beispieldaten anzeigen
  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

  DATA: o_salv TYPE REF TO cl_salv_table.

  cl_salv_table=>factory( EXPORTING
                            r_container    = o_container_bottom
                          IMPORTING
                            r_salv_table   = o_salv
                          CHANGING
                            t_table        = it_sflight ).

  o_salv->get_functions( )->set_all( ).
  o_salv->display( ).

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

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

[ABAP] Splitter (cl_gui_splitter_container) fixieren und dessen absolute Höhe festlegen

INITIALIZATION.

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 40 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 40 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).
  
  ...

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

[ABAP] Eigenständiges Dialogfenster (cl_gui_dialogbox_container) fullscreen (maximized) mit SALV-Table ohne zus. Dynpro anzeigen

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_close FOR EVENT close OF cl_gui_dialogbox_container
        IMPORTING sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
  METHOD on_close.
    IF sender IS NOT INITIAL.
      sender->free( ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA: it_sflight TYPE STANDARD TABLE OF sflight WITH DEFAULT KEY.

  SELECT * INTO TABLE it_sflight FROM sflight WHERE carrid = 'LH'.

  DATA(o_cnt) = NEW cl_gui_dialogbox_container( no_autodef_progid_dynnr = abap_true
                                                caption                 = 'Flüge'
                                                top                     = 1
                                                left                    = 1
                                                width                   = 640
                                                height                  = 480 ).

* Dialogbox-Container fullscreen (maximized) setzen
  o_cnt->set_alignment( cl_gui_control=>align_at_left + cl_gui_control=>align_at_right + cl_gui_control=>align_at_top + cl_gui_control=>align_at_bottom ).

* OnClose-Handler setzen
  SET HANDLER lcl_events=>on_close FOR o_cnt.

  DATA: o_salv TYPE REF TO cl_salv_table.

* SALV-Grid erzeugen
  cl_salv_table=>factory( EXPORTING
                            r_container  = o_cnt
                          IMPORTING
                            r_salv_table = o_salv
                          CHANGING
                            t_table      = it_sflight ).

  o_salv->display( ).

* cl_gui_container=>screen0 erzwingen
  WRITE: / space.

[ABAP] GUI Containertypen

cl_gui_container

* cl_gui_container=>default_screen
* cl_gui_container=>screen0 ... cl_gui_container=>screen9
  • Fullscreen-Container der Listenausgabe
  • Erzeugung erfolgt z.B. bei WRITE (Bsp.: WRITE space.)
  • können als Basis für weitere Container genommen werden

Beispiel für cl_gui_container: Link

cl_gui_splitter_container

  • Splitter mit Subcontainern
  • benötigt Parent (z.B. cl_gui_container=>screen0, cl_gui_docking_container, cl_gui_custom_container)

Beispiel für cl_gui_splitter_container: Link

cl_gui_docking_container

  • Dock-Seite kann angegeben werden
  • Breite / Höhe kann absolut (extension) oder relativ (ratio) angegeben werden

Beispiel für cl_gui_docking_container: Link

cl_gui_dialogbox_container

  • erzeugt ein neues eigenständiges Fenster
  • Event “on_close” sollte behandelt werden, damit auf das Schließen-Kreuz reagiert werden kann

Beispiel für cl_gui_dialogbox_container: Link

cl_gui_custom_container

  • Containerobjekt zur Verwendung auf Dynpros
  • ein Name muss vergeben werden

Beispiel für cl_gui_custom_container: Link

cl_gui_gos_container

  • Containerobjekt für Anzeige von Generic Object Services (GOS) in der Titlebar
  • beliebige Untercontainer können eingebettet werden

Beispiel für cl_gui_gos_container: Link

cl_gui_container_bar

  • vertikales Tabstrip mit Auswahl-Buttons

Beispiel für cl_gui_container_bar: Link

cl_gui_container_bar_2

  • vertikales Tabstrip mit Auswahl-Buttons und Schließen-Kreuz
  • drei Anzeigemodi (fix (Feste Anordnung), tile (Menü), outlook (Anordnung klappt))

Beispiel für cl_gui_container_bar_2: Link

cl_gui_container_bar_xt

  • vertikales Tabstrip mit Auswahl-Buttons und Schließen-Kreuz
  • zwei Anzeigemodi (fix (Feste Anordnung), outlook (Anordnung klappt))

Beispiel für cl_gui_container_bar_xt: 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

[ABAP] SALV-Table: Anzeige in einem DockingContainer, Einfügen von Buttons und Eventhandling

Variante 1 (cl_gui_docking_container)

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING e_object
                sender.
    CLASS-METHODS:
      handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm  " Benutzerkommando
                  sender.  " Sender
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
  METHOD handle_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Print-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Klick!' icon = icon_change_text function = 'PRINT_DATA' quickinfo = 'Etwas ausgeben' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.

  METHOD handle_user_command.
* TypeCast auf Sender
    DATA: o_grid TYPE REF TO cl_gui_alv_grid.
    o_grid ?= sender.

    CASE e_ucomm.
* Daten speichern
      WHEN 'PRINT_DATA'.
        WRITE: / 'Klick: ', o_grid->m_guid.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA: it_data TYPE STANDARD TABLE OF t000.
  DATA: o_salv TYPE REF TO cl_salv_table.

* Daten holen
  SELECT *
    INTO TABLE it_data
    FROM t000.

  DATA(o_dock) = NEW cl_gui_docking_container( no_autodef_progid_dynnr = abap_true
                                               side = cl_gui_docking_container=>dock_at_top
*                                               style = cl_gui_container=>ws_visible + cl_gui_container=>ws_thickframe + cl_gui_container=>ws_child
                                               ratio = 90
                                               caption = 'Datenausgabe'
                                               name = 'CNT1' ).

* Datenanzeige
  TRY.
* Bei Angabe des Containers o_dock bleibt die Abarbeitung nach o_salv->display( ) nicht
* stehen, sondern läuft weiter und die Referenz auf das ALV-Grid kann geholt werden.
* Eine Anzeige des SALV-Grids erfolgt so aber nur, wenn eine Listenausgabe erfolgt, daher das WRITE space.
      cl_salv_table=>factory( EXPORTING
                                r_container    = o_dock
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_data ).

      o_salv->get_functions( )->set_all( ).
      o_salv->display( ).

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

* Eventhandler registrieren
      SET HANDLER lcl_event=>handle_toolbar FOR o_alv_grid.
      SET HANDLER lcl_event=>handle_user_command FOR o_alv_grid.

* Anzeige neu aufbauen
      o_alv_grid->refresh_table_display( ).

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

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe

Variante 2 (cl_gui_splitter_container)

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING e_object
                    sender.
    CLASS-METHODS:
      handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm  " Benutzerkommando
                    sender.  " Sender
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
  METHOD handle_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Klick!' icon = icon_change_text function = 'PRINT_DATA' quickinfo = 'Etwas ausgeben' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.

  METHOD handle_user_command.
* TypeCast auf Sender
    DATA: o_grid TYPE REF TO cl_gui_alv_grid.
    o_grid ?= sender.

    CASE e_ucomm.
* Daten speichern
      WHEN 'PRINT_DATA'.
        WRITE: / 'Klick: ', o_grid->m_guid.
    ENDCASE.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

  DATA: it_data TYPE STANDARD TABLE OF t000.
  DATA: o_salv TYPE REF TO cl_salv_table.

* Daten holen
  SELECT *
    INTO TABLE it_data
    FROM t000.

  DATA(o_split) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                 no_autodef_progid_dynnr = abap_true
                                                 rows = 1
                                                 columns = 2 ). " wenn columns = 1, dann FullScreen

* Referenz auf linken Container holen
  DATA(o_spl_left) = o_split->get_container( row = 1 column = 1 ).

* Datenanzeige
  TRY.
* Bei Angabe des Containers o_spl_left bleibt die Abarbeitung nach o_salv->display( ) nicht
* stehen, sondern läuft weiter und die Referenz auf das ALV-Grid kann geholt werden.
* Eine Anzeige des SALV-Grids erfolgt so aber nur, wenn eine Listenausgabe erfolgt, daher das WRITE space.
      cl_salv_table=>factory( EXPORTING
                                r_container    = o_spl_left
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_data ).

      o_salv->get_functions( )->set_all( ).
      o_salv->display( ).

* Trick: Aus dem Container das Grid-Objekt holen und nach cl_gui_alv_grid casten
      READ TABLE o_spl_left->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_event=>handle_toolbar FOR o_alv_grid.
        SET HANDLER lcl_event=>handle_user_command FOR o_alv_grid.

* Anzeige neu aufbauen
        o_alv_grid->refresh_table_display( ).
      ENDIF.
    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe 

Variante 3 (cl_gui_container=>screen0)

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING e_object
                sender.
    CLASS-METHODS:
      handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm  " Benutzerkommando
                  sender.  " Sender
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
  METHOD handle_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Print-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Klick!' icon = icon_change_text function = 'PRINT_DATA' quickinfo = 'Etwas ausgeben' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.

  METHOD handle_user_command.
* TypeCast auf Sender
    DATA: o_grid TYPE REF TO cl_gui_alv_grid.
    o_grid ?= sender.

    CASE e_ucomm.
* Daten speichern
      WHEN 'PRINT_DATA'.
        WRITE: / 'Klick: ', o_grid->m_guid.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA: it_data TYPE STANDARD TABLE OF t000.
  DATA: o_salv TYPE REF TO cl_salv_table.

* Daten holen
  SELECT *
    INTO TABLE it_data
    FROM t000.

* Datenanzeige
  TRY.
* Bei Angabe des Containers cl_gui_container=>screen0 bleibt die Abarbeitung nach o_salv->display( ) nicht
* stehen, sondern läuft weiter und die Referenz auf das ALV-Grid kann geholt werden.
* Eine Anzeige des SALV-Grids erfolgt so aber nur, wenn eine Listenausgabe erfolgt, daher das WRITE space.
      cl_salv_table=>factory( EXPORTING
                                r_container    = cl_gui_container=>screen0
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_data ).

      o_salv->get_functions( )->set_all( ).
      o_salv->display( ).

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

* Eventhandler registrieren
      SET HANDLER lcl_event=>handle_toolbar FOR o_alv_grid.
      SET HANDLER lcl_event=>handle_user_command FOR o_alv_grid.

* Anzeige neu aufbauen
      o_alv_grid->refresh_table_display( ).

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

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe

[ABAP] Ein SALV-Table IDA und ein GUI-Picture in einem Dockingcontainer direkt auf dem Selektionsbildschirm anzeigen

DATA: o_cnt_bottom TYPE REF TO cl_gui_docking_container.
DATA: o_cnt_right TYPE REF TO cl_gui_docking_container.
DATA: o_alv_bottom TYPE REF TO if_salv_gui_table_ida.
DATA: o_pic TYPE REF TO cl_gui_picture.
DATA: o_collector_bottom TYPE REF TO cl_salv_range_tab_collector.
DATA: lv_mtart TYPE mara-mtart.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE title2.
SELECT-OPTIONS: s_mtart FOR lv_mtart.
SELECTION-SCREEN END OF BLOCK b1.

AT SELECTION-SCREEN OUTPUT.

* Verhindern, dass der Container mehrfach erzeugt wird, wenn der Focus aus
* best. Oberflächenelementen zurück kommt.

* Container unten erzeugen
  IF NOT o_cnt_bottom IS BOUND.
    o_cnt_bottom = NEW #( repid = sy-repid
                          dynnr = sy-dynnr
                          side  = cl_gui_docking_container=>dock_at_bottom " unterer Bildschirmrand
                          extension = 300 ).                               " 300 hoch, damit die Selektionskriterien nicht überdeckt werden
* Container rechts erzeugen

    o_cnt_right = NEW #( repid = sy-repid
                         dynnr = sy-dynnr
                         side  = cl_gui_docking_container=>dock_at_right  " rechter Bildschirmrand
                         extension = 800 ).                               " 800 breit, damit die Selektionskriterien nicht überdeckt werden

* IDA-Grid unten erzeugen
    o_alv_bottom = cl_salv_gui_table_ida=>create( iv_table_name    = 'MARA'
                                                  io_gui_container = o_cnt_bottom ).
    o_alv_bottom->display_options( )->set_title( 'MARA' ).

* Picture rechts erzeugen
    o_pic = NEW #( parent = o_cnt_right ).
    o_pic->set_display_mode( display_mode = cl_gui_picture=>display_mode_normal_center ).
    o_pic->load_picture_from_sap_icons( icon  = icon_delete ).

* Suchkriterien unten setzen
    o_collector_bottom = NEW #( ).
    o_collector_bottom->add_ranges_for_name( iv_name = 'MTART' it_ranges = s_mtart[] ).
    o_collector_bottom->get_collected_ranges( IMPORTING et_named_ranges = DATA(it_name_range_pairs_bottom) ).

    o_alv_bottom->set_select_options( it_ranges = it_name_range_pairs_bottom ).
  ENDIF.