Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Abhi105
Advisor
Advisor
0 Kudos

1. Objective

JNET is a technology used for modelling graphical networks however not much technical information is available on the topic apart from the link  http://graphics1.wdf.sap.corp:1080/jnet/Home.html.  One would find it extremely difficult to locate a colleague who has worked on a project consuming JNET for modelling. This does not leave too much room but to explore the area by debugging some sample programs available in a few SAP systems. Hence I want to pen my understanding and experiences which I am sure will be helpful for colleagues who wish to use this technology by integrating in ABAP GUI. It is assumed that the developer who reads this document is aware of  XML basics.

2. Description

This Document will cover the following topics:

     1. Introduction

     2. Installation : Java 1.7 Vs Java 1.8

     3. Pre-requisite notes

     4. Pre-requisite SICF activations

     5. Program structure

3. Introduction

JNet is a generic editor for network graphics. It can be used to display anything that can be visualized as a set of nodes and links between nodes.

                                                                                          Figure 1

For more details, please refer to

http://graphics1.wdf.sap.corp:1080/jnet/Home.html

 

4. Installation: Java 1.7 Vs Java 1.8

Please refer to http://graphics1.wdf.sap.corp:1080/jnet/Download.html

Java 1.7 requires JNET installation as part of GUI installer.

                              Figure 2

Java 1.8 does not require such specific installation. However a few notes needs to be installed in the system for Java 1.8 to be workable. Please refer to section 5.

5. Pre-requisite notes

1538367

WDA: HTTP 404 when accessing "frog.jar"

1637307

new method GET_THEMENAME in CL_GUI_RESOURCES

1693098

ValueSuggest in accessibility mode

1721445

WDA: ACF control - Browser no longer responds

1812323

Sessions are not reduced in Web Dynpro ABAP

1832111

Popup window doesn't close when fired the EXIT Plug

1855672

Firefox: buttonWidth remains unchanged

1891893

WDA: Adjusting the Web Dynpro ABAP renderings part 11

1958962

Network/Gantt: Java security prompt: IMS: Mimes Part .IV

1959347

Network/Gantt: Java security prompt: IMS: Mimes Part II

1978813

Network/Gantt: Java security prompt: IMS: Mimes Part III

1978815

Network/Gantt: Java security prompt: IMS: Mimes Part IV

1978998

Network/Gantt: Java security prompt: IMS: Mimes Part I

1979266

Network/Gantt: Java security prompt: IMS: Mimes Part .I

1979267

Network/Gantt: Java security prompt: IMS: Mimes Part .II

1979268

Network/Gantt: Java security prompt: IMS: Mimes Part .III

1984545

Network/Gantt: Java security prompt: IMS: Mimes Part V

1984558

Network/Gantt: Java security prompt: IMS: Mimes Part .V

1987719

GOS: Attachment List not refreshed after deleting third atta

2105752

Abap corrections for note 2103687

2158689

Subsequent correction to SAP Note 2103687

2164890

JNET in SAP GUI support of HTTP (not only HTTPS)

1926137

New version of JNet/JGantt JAR files for WebDynpro/ABAP appl

2103687

New implementation of JNet and JGantt in SAP GUI for Windows

2016249

SAP GUI (for Windows) Error Message "JNet not installed"

2103200

JNet/JGantt with Java 8 - ClassNotFoundException: 'com.sap.t

 

6. Pre-requisite SICF activations

There are few SICF paths which need to be activated before JNET can be consumed.

/default_host/sap/public/bc/Webdynpro/sap

/default_host/sap/public/bsp/sap/public/graphics/jnet_handler

/default_host/sap/public/myssocntl

/default_host/sap/webcuif

 

7. Program structure

Please refer to sample programs mentioned at the link http://graphics1.wdf.sap.corp:1080/jnet/Documentation.html.

In general any ABAP program which uses JNET consists of 3 parts.

    1. JNET container
    2. XML
    3. Event Handler

                                                                              

   Figure 3

7.1 Integrate JNET container in SAP GUI

As depicted in the diagram above,  UI screen contains a customer container inside which a JNET container is embedded. Customer container needs to be created in the ABAP GUI screen and a JNET object of type CL_GUI_JNET needs to be embedded in this container. It works the way a Tree or ALV container is created and embedded. Please refer to the code snippet below.


CREATE OBJECT go_container
EXPORTING
CONTAINER_NAME           = 'CUSTOM_CONTAINER'.

CREATE OBJECT go_jnet
EXPORTING
PARENT = go_container.

7.2 Prepare XML

The exchange of data between JNet controller and the underlying programs is done via an XML. The XML has a pre defined structure and must be complied to so it can be parsed by JNet controller. This XML renders the intended graph on the layout and consists of the following parts.

        1. Type repository
        2. User Interface
        3. Graph

Please note that the below XML code is for explanation purpose. For a complete XML please refer to http://graphics1.wdf.sap.corp:1080/jnet/Demos.html.


7.2.1 Type Repository

It contains all the type declarations that can be used as properties of a UI element within the JNET. This section contains the various Types of      Colors, Labels, Edge, Nodes etc. the XML supports. For example

        • Color types defined below can be used in the XML.

Color:  <COLOR>

<type name="color.OIL">

<rgb hex="#A5D7F7"/>

                                 </type>

<type name="color.GAS">

<rgb hex="#FC7171"/>

</type>

        </COLOR>

        • Edge is the linkage between 2 nodes. Different edge types can be defined and different properties can be set for each Edge type.  Edge is used in the graph section where it takes its UI properties from edge type defined below. For example the edge shown below is of green color because a type ‘color.OIL’ has been defined within the <COLOR> </COLOR> tags and used in the Edge type ‘OIL’.

                                                      

                                                                   Figure 4

Edge : <EDGE>

                        <type name="GAS" >

<color type="color.GAS"/>

</type>

<type name="OIL" >

<color type="color.OIL"/>

</type>

      </EDGE>

An Edge type GAS will show a different color. Similarly other properties of the edge can be set. For example the below edge type will be a non-movable, dashed edge.                                                           

<type name="Water">

<editprops><moveable>FALSE</moveable></editprops>

<stroke>DASHED</stroke>

</type>


        • A node is a starting or ending point of an edge. Different node types can be defined and different properties can be set for each node type. Node is used in the graph section where it takes its UI properties from the node type defined below. For example the Node Type ‘NodeBasic’  has shape type = Box with border color and fillColor defined. There are 5 label positions also defined. The 2 texts visible below are 2 labels inside the node.

Figure 5

Node :

<type name="NodeBasic">

<shape type="Box"><size>120,70</size>

<border>

<color><rgb>221,221,221</rgb></color>

<thickness>2</thickness>

</border>

<filled>TRUE</filled>

<layout type="Layout"/>

<fillColor><rgb>226,220,226</rgb></fillColor>

</shape>

<label index="0">

                                 <location originAtBox="CENTER,BOTTOM"/>

<halign>CENTER</halign>

<halignText>CENTER</halignText>

<valign>TOP</valign>

<valignText>TOP</valignText>

</label>

<label type="Label" index="2">

<location originAtBox="LEFT,25%" offset="20,0"/>

<valign>CENTER</valign>

<halign>LEFT</halign>

<valignText>CENTER</valignText>

</label>

<label type="Label" index="3">

<location originAtBox="LEFT,50%" offset="20,0"/>

<valign>CENTER</valign>

<halign>LEFT</halign>

<valignText>CENTER</valignText>

</label>

<label type="Label" index="4">

<location originAtBox="LEFT,75%" offset="20,0"/>

<valign>CENTER</valign>

<halign>LEFT</halign>

<valignText>CENTER</valignText>

</label>

<label type="LabelIcon" index="5">

<location originAtBox="LEFT,TOP" offset="4,24"/>

<valign>TOP</valign>

<halign>LEFT</halign>

</label>

      </type>

7.2.2 User Interface

As the name suggests this section contains the UI elements and the JNET layout. It also offers commands which a user can execute via buttons or context menu. Some of the commands are standard commands offered by JNET (example PRINT_PREVIEW, PRINT, ZOOM etc.  ) and some are custom commands (example DisplayObj, EditLink etc.) freely created by the user. Standard commands are handled by JNET itself whereas custom commands need to be handled by explicit ABAP coding.

<UserInterface version="1.0">

<Commands>

          <!---Standard commands--->

<Command name="PRINT_PREVIEW" enabled="TRUE" visible="TRUE"/>

<Command name="PRINT" visible="TRUE"/>

<Command name="CUT" visible="FALSE"/>

<Command name="COPY" visible="FALSE"/>

<Command name="PASTE" visible="FALSE"/>

<Command name="UNDO" visible="FALSE"/>

<Command name="REDO" enabled="FALSE" visible="FALSE"/>

<Command name="FIND" visible="TRUE"/>

<Command name="ZOOM" visible="TRUE"/>

<Command name="NAVIGATE" visible="FALSE"/>

<Command name="OPTIONS" visible="TRUE"/>

<Command name="LAYOUT" visible="TRUE"/>

<Command name="LAYOUT_OPTIONS" visible="TRUE"/>

<Command name="FILTER" visible="TRUE"/>

<Command name="FILTER_OPTIONS" visible="TRUE"/>

<!---Custom commands-->

<Command name="CreateLink" visible="TRUE" text="Create Object Link"/>

<Command name="CreateObj" visible="TRUE" text="Create Network Object"/>

<Command name="EditLink" visible="TRUE" text="Edit Object Link"/>

<Command name="RemoveLink" visible="TRUE" text="Remove Object Link"/>

<Command name=" DisplayLink " visible="TRUE" text="Display Object Link"/>

<Command name="DisplayObj" visible="TRUE" text="Display Network Object"/>

</Commands>

This below section allows setting of UI properties of the JNET layout like Visibility of the status bar, visibility of the Tool bar, color etc. Context menu events like “OnSingleNodeSelect” (which gets fired when a node is right clicked) are also handled here. Commands which are intended to be called on right click of node can be defined under the XML tag <item command />. These commands can be handled in the ABAP code.

<Components>

<StatusBar visible="TRUE"/>

<NavigationArea withZoom="TRUE"/>

<ToolBar visible="TRUE"/>

<MainContainer layout="SPLITPANE">

<ToolsArea layout="VERTICAL_FLOW" vAlignment="TOP" hGap="10">

<Background>

                <rgb>221,221,221</rgb>

</Background>

</ToolsArea>

<WorkArea layout="SCROLLEDPANE" scrollbars="ALWAYS">

<Background><rgb>255,255,255</rgb></Background>

<Grid>

<Show>FALSE</Show>

<Color><rgb>0,0,0</rgb></Color>

<Size>40,40</Size>

<DrawingSize>10,10</DrawingSize>

</Grid>

<PopupMenu event="OnSingleNodeSelect">

<Item command="DisplayObj"/>

<Item command="ObjStatInfo" separator="TRUE"/>

</PopupMenu>

<PopupMenu event="OnSingleEdgeSelect">

<Item command="DisplayLink"/>            

<Item command="RemoveLink"/>

</PopupMenu>

</WorkArea>

</MainContainer>

</Components>

</UserInterface>

7.2.3 Graph

This section contains the actual Nodes and links shown on the JNET. The logic to generate this section of the XML is covered in section 7.3.1.2

Node section contains the Node data with properties like Type, ID etc.

<Graph version="1.0" type="Graph">

<node type=" NodeBasic " id="AB BT 0112123">

<locationalignment="TOPLEFT" coords="ABSOLUTE">0,0</location

<label index="1"/>

<label index="2">AB BT 0112123</label>

<label index="3">AB BATTERY</label>

<label index="4"/>

<label index="5"/>

</node>

<node type=" NodeBasic " id="FAC_GP_INV">

<location alignment="TOPLEFT" coords="ABSOLUTE">0,0</location>

<label index="1"/>

<label index="2">FAC_GP_INV</label>

<label index="3">FAC_GP_INV</label>

<label index="4"/>

<label index="5"/>

</node>

Edge section contains the Edge data with properties like Type, Id, Starting and Ending nodes. It also contains the direction from which the edge is originating. In the below screen shot, the edge is originating from the eastern side and going into the western side. Hence the position is marked as EAST to WEST.

   

     Figure 6

<edge type="OIL" id="005056AC7E771EE5ABA3D7F5D8C95FA4">

<thickness>2</thickness>

<from node="AB BT 0112123" position="EAST" plug="00"/>

<to node="FAC_GP_INV" position="WEST" socket="01"/>

</edge>

</Graph>

This XML ( assume is stored in variable gv_xml) needs to be loaded in the JNET container via JNET command LOAD_DATA.

                                                Call Method go_jnet->Load_data

                                                                Exporting

Xml = gv_xml

7.3 Handle JNET events

Once the custom container is created and XML ( with Type Repository and User Interface ) defined, an Event handler needs to be coded which will handle all the events triggered out of JNET. Please refer to code snippet below. A method on_event is created in a local class whose instance is go_event_handler.

SET HANDLER go_Event_handler->on_event FOR go_jnet.

Method on_event will have an importing parameter ‘EVENT’ which will contain the name of the event fired. For example

                        

Event ID

Short Description

CUSTOM_COMMAND

Indicates that a custom (i.e. application specific) command was invoked (by the user or some external controller).

JNET_INITIALIZED

indicates that JNet was initiated (the applet's init() method)

LINK_ADDED

indicates that a link was added to the graph (a lose edge was plugged into a node's socket)

NODE_ADDED

indicates that a node was added to the graph

NODE_SELECTED

indicates that a node has been clicked (not just selected)

ABAP integration of the events is explained in section 7.3.1.

 

7.3.1      Event Handlers and data exchange

Method on_event gets called when an action is carried out on JNET. The events are in the form of an XML which need to be broken down into commands (event name) and component (node/edge id). For example, when a node is clicked, NODE_SELECTED event gets fired. The event XML is similar to what is shown below.

<?xml version="1.0" encoding="UTF-8"?>

<JNetEvent id="NODE_SELECTED" jnet="AppWin0" component="AB BT 0112123">

<parameter>3</parameter>

</JNetEvent>

A transformation needs to be called, which will break it into subcomponents

Command or Event         : NODE_SELECTED

Component or Id             : AB BT 0112123

Transformation uml_class_diagram_jnet_event, as mentioned in the sample programs, can be called for this purpose.

CALL TRANSFORMATION uml_class_diagram_jnet_event
SOURCE XML iv_event
RESULT
id                          = lv_command
component           = lv_component
node                    = lv_node.

Once the Event name is available, normal ABAP logic can be written for each event. There are further 2 parts to it

7.3.1.1 ABAP logic

ABAP logic to capture entered data can be written as is done in normal ABAP. For example, if a node is required to be added via ‘NODE_ADDED’ event, a pop up/ screen with Node Id and other details can be called, where the user can enter node details. This can be captured in local internal tables and work areas. Once captured, XML parser logic needs to be called to modify the XML. This modified XML needs to be reloaded using the command mentioned below.

Call Method go_jnet->Load_data

                Exporting

Xml = gv_xml

7.3.1.2 XML parser

Type repository and User interface are usually static and the XML containing these 2 sections can be stored in MIME repository/local desktop from where it can be read into the ABAP program. An XML parser needs to be written to generate XML code in ‘Graph’ section of the XML. This is required because the JNET layout is required to be completely reloaded with the new XML. Unless the XML is modified with the newly added node and loaded again, changes will not be reflected on the JNET screen.

If the newly added node is FAC_GP_1, the XML needs to be modified with the below addition in the graph section.


<node type=" NodeBasic " id="FAC_GP_1">

<location alignment="TOPLEFT" coords="ABSOLUTE">0,0</location>

<label index="1"/>

<label index="2">FAC_GP_1</label>

<label index="3">FAC_GP_1</label>

<label index="4"/>

<label index="5"/>

</node>

Code snippet for the modifying the XML via ABAP parser is as shown below.

Parser needs to be initialized.

Variable initialization

Data :

lo_ixml              TYPE REF TO   if_ixml,
lo_doc               TYPE REF TO   if_ixml_document,
lo_streamf           TYPE REF TO   if_ixml_stream_factory,
lo_istream           TYPE REF TO   if_ixml_istream,
lo_parser            TYPE REF TO   if_ixml_parser,

…..

Parser Logic

lo_ixml    = cl_ixml=>create( ).
lo_streamf = lo_ixml->create_stream_factory( ).
lo_istream  = lo_streamf->create_istream_xstring( cv_xml ).
lo_doc     = lo_ixml->create_document( ).
lo_parser  = lo_ixml->create_parser(    stream_factory  = lo_streamf
                                                               istream             = lo_istream
                                                              document          = lo_doc ).

An internal table with the newly added node details ( Id, description etc. ) needs to be looped over


      LOOP AT it_node ASSIGNING <ls_node_tmp>.
       CLEAR: ls_node, lv_value.

CLEAR lt_attr.

ls_attr-name = 'type'.

ls_attr-value = <ls_node>-node_type.


APPEND ls_attr TO lt_attr.

ls_attr-name = 'id'.

ls_attr-value =  <ls_node>-obj_id.

APPEND ls_attr TO lt_attr.


lo_elem = io_doc->create_element( name =  'node').

Loop at lt_attr INTO ls_attr.

lv_attr_name = ls_attr-name.

lv_attr_value = ls_attr-value.

lo_attribute = io_doc->create_attribute( name = lv_attr_name ).

lo_attribute->set_value( value = lv_attr_value ).

lo_elem->set_attribute_node( new_attr = lo_attribute ).

Endloop.

               ENDLOOP.

The above logic will create the XML line

<node type=" NodeBasic " id="FAC_GP_1">

Other lines for nodes and edges can be created using similar logic in the above loop

4 Comments