| Java, Eclipse and Web programming Tutorials |
Version 0.2
Copyright © 2008 Lars Vogel
28.01.2007
Abstract
SAP supports Web Dynpro for Java as a development approach for business applications. The following demonstrate how you can develop and deploy an application in Web Dynpro for Java.
Please note that Web Dynpro for Java is a technology which is currently only supported by SAP. Development and deployment requires the SAP Netweaver Development Studio and a Netweaver application server for Java.
This article will demonstrate how to develop a simple application with one view, provide data for the application via the context, explain how you can control the view flow on your application and explain how to display a message on your screen.
Table of Contents
The Netweaver Development Studio is a SAP extension of the open-source Eclipse project. SAP provides additional plugins for Eclipse to enhance Eclipse is relation to SAP technology.
More or less everything you know from the handling of Eclipse can be applied to the NWDS.
To run Web dynpro for Java applications you need the Netweaver application server for Java. To develop these applications you need the SAP Netweaver Development Studio.
You find trivial version of the NWDC on the SAP Developer Network. http://sdn.sap.com
Select here Downloads. Currently the best download is the SAP Netweaver Composition Environment. Downloading the software requires a valid user. Requistration is free of charge.
Webdynpro for Java (Java WD) only runs on the server. You can develop locally with the SAP Netweaver Development Studio but to test and run the application you have to deploy the application to the server.
Java WD runs on the Netweaver application server for Java (NWAS Java) which is decoupled from the SAP ABAP application server. To access the SAP ABAP application server you have to use Remote Function Calls (RFC) or Webservices.
The basic element of WD is the component. Each WD component is a separate Java program. The source for this java program is generated automatically. This source code contains places, so called hooks, to extend the standard coding.
Each component contains out of serveral interfaces and controllers.
There are several types of controllers
Component Controller - controls the component
View Controller - controls the view
In addition to the standard hook methods the programmer can also declare controller instance methods (in the methods tab of the controller) and define the method and its parameters.
Also in addition each controller contains at the end of the source code a coding block in which the programmer can put any code and member variables he likes.
Each controller has one hierarchical data storage structure called context .
The context is a local memory which allows to store hierarchical data for a specific WD component, e.g. view and / or controller.
Each context has a root element. Under that root element the other objects are stored.
The context of each component can be connected.
If the developer would like to structure his work over several project and / or work distributed on several project he can use "Development Components".
Within DC's you can add dependencies via "DC Definition" -> Used DC -> Add Dependency
Dependent DC's are available at design time, to make then available at runtime on the server they need to be deployed to the server.
Select your DC, right mouse click, select Development Component-> Build. This will make the DC available at design time.
Select your DC, right mouse click, select Development Component-> Deploy. This will make the DC available at runtime on the server.
Development Components (DC) are normal project which can create via New -> Development Component.
DC can define the public API, e.g. which elements are avaiable for other development components. E.g. if you define a structure type in one development component you can add it ot the public API via right mouse click -> Add to public part.
Model, e.g. access to external data sources, are usually create as DC.
Switch to the "Web Dynpro" perspective. Please see Eclipse Perspective for details.
Create a new Web Dynpro Project. Name your project it "FirstWebdynpro"


Open your project. Select "Web Dynpro Components". Right click and select create Webdynpro Component. Maintain the data from the following pictures.


Select your view and and right click on the RoootUIElementContainer. Select insert child.

Select Tray from the list.

Right click on the tray and select "Properties". Change the layout to MatrixLayout.

Add a new child "Group" to Tray. Change the layout to MatrixData for this group. Drag the text to the group and change the property "text" of this UI element to "Please select a person:". Change the propertiy "design" to "header 1". Change the layout settings of the Group and the Text UI Element so that the Text UI element is always shown in the first line.


In this chapter we will extend the simple application with the definition of data and the display of this date.
Create context for your application. Select therefore your component controller, right mouse click and select "Edit".

Create a new value node "Person".



Add Value Attributes "FirstName" and "LastName" to this node.


The result should look like this.

Change the cardinality of person to 1:1. To do this, right click on the person and select "Properties".

Now you have a data container available in your application.
To make the data from the component controller avaialble in the view, select your component "Component10", right mouse click and select "Open Data Modeler".
Select a "Create a data link" button, select your view and then your Component Controller. Drag the person from right to the left on the context node and perform the context mapping. After finished once your are done.



After this your data from the content controller will be available in the view.
Create another view "View20". Make the data of the content controller available in this view. The only difference is that these fields should get imported as "TextView" (in the wizward for the form).
The following does not list all necessary steps, only the creation of a view and the definition of the fields in the form wizard. The other steps are the same as performed before.


Select "Window10".

Press "embed a view", and click in the editor field. Select "Embed existing view" and select your View20.


Create create a view set and change the properties of this view set that it has two rows and one column.

Embed the View10 in the first row of the view set and the view20 in the second row. The approach is the same as above.

Embed a empty view in the second row. Same approach but different selection.

Select the view set and change the property "default" to true.
Also make the empty view the default view in the second row.
The result should look like the following.

Add now an outbound plug to View10 and View20. Name it "Out10" and "Out20".



Add Inbound Plug "In20" for View20.

Press now "Create a navigation link". Connect the outbound plug of View10 with the inbound plug of View20 and the outbound plug of View20 with the inbound plug for the empty view.

Now your views are connected but you still need to trigger this connection. We will do this via a button.
Select your View10 and the UI element Group. Select "Apply Template" and select ActionButton.



Make you that you select the outbound plug your created.

Create now also a button for View20 called "Hide Details" and connect this to the action outbound plug of View20.

Deploy and run your application. You should be able to enter some data and by pressing the "Show Details" button to include the detailed screen. Hide Details should hide the second view again.

Web Dynpro has several pre-defined methods which allow you to access data. In the following we will use a very simply approach to set the default values for the first and last name in our small application.
Select your content controller and select the implementation tab. Find the method wdDoInit()

Your coding must be placed between the begin and end tags. You can get access to the context via pre-defined methods of the variable wdContext.
public void wdDoInit()
{
//@@ begin wdDoInit()
wdContext.currentPersonElement().setFirstName("Lars");
wdContext.currentPersonElement().setLastName("Vogel");
//@@ end
}
If you run your application then the first and last name should be defaulted.
Web Dynpro makes it easy to integrate message to the application. The following will give a warning to the user that the default values of the first and last name are currently hard-coded.
Select message pool and select "Open Message Editor".

Right mouse click, select "Add".


Now use your new message area to write a message to your application.
public void wdDoInit()
{
//@@ begin wdDoInit()
wdContext.currentPersonElement().setFirstName("Lars");
wdContext.currentPersonElement().setLastName("Vogel");
// Get the message manager
IWDMessageManager msgMan = wdComponentAPI.getMessageManager();
// Report a message
msgMan.reportMessage(IMessageComponent10.MY_INFORMATION, null, false);
//@@ end
}
If you run your application the result should look like the following.

The recommend way to modify UI elements is to bind the UI elements properties to an context attribute and then modify the context attribute via Java coding during runtime.
The following will describe how to add a fancy graphic to your detail view which receives its source of the graphic via the java program.
The following steps are not all completely described with screenshots. Please (see Your first WD application for details).
Create a new WD project "UIBinding".
Create a new Component "Component10" with a window "Window" and the view "PictureView".
Add to your View10 the UI element "Image". Add a tray if you like and make the UI nice looking.
Select the context of your view and define the value node "MyImage" with the two attributes "MyImageAlt" and "MyImageSource".

Change the property "calculated" of "MyImageAlt" and "MyImageSource" to "true" and set the cardinality of MyImage to 1:1.
Change the property of your Image UI element that property alt is connected to MyImage.MyImageAlt and MyImage.MyImageSource.

Go to the implementation of the view and implement the getter methods.
public
java.lang.String getImageImageSource(IPrivateMainView.IImageElement element)
{
//@@begin getImageImageSource(IPrivateMainView.IImageElement)
return "http://www.vogella.de/images/Java.jpg";
//@@end
}
public
java.lang.String getImageImageAlt(IPrivateMainView.IImageElement element)
{
//@@begin getImageImageAlt(IPrivateMainView.IImageElement)
return "For some reason I did not find the image";
//@@end
}
Create an application "Testing10". Deploy and run your application. The result should look like the following:

For the usage in different area it is easier to pre-define the data types which will be used. This is not necessary necessary to display data in a table.
Create simple data types for "FirstName" - type string, "LastName" - type string, "Married" - type boolean, "Comment" - Type string.





Create a structure "Person".



Create a new Web Dynpro Project "TableHandling". Create a new component "Component" with window "Window" and view "EntryView".
In your component controller create context. Create value note "Person" with structural binding.



Property cardinality should be set to 0:n and selection also to 0:n.
Create a new view "TableView".
Open the Data Modeler and define that EntryView and TableView has access to the component context. Do not map the field "Comment" to the EntryView, only the other fields.
Mapping for EntryView

Mapping for TableView

After the mapping the view should look like the following:

The context Person represents a collection. To enter data in the EntryView we need another value node. Create value node "NewPerson" in the view "EntryView". Set the cardinality to 1:1.

Again do not include the field commment.


Using "Apply Template" create a form for NewPerson in EntryView.
The value attribute "Married" should be displayed as a checkbox.

Create a button "Add to table" which fires the outbound plug "out" to view EntryView.
Finally (uff) to the table. Select your TableView and select "Apply Template". Do not include "Comment" and make "Married" a checkbox.



Again use "Apply Template" to include a form. This form should only include the comment. Select TextEditor for this field.

Format your view a little so that you like it. Mine looks now like the following.

Include a header into the table and a toolbar.


In the toolbar insert a toolbar item. Select ToolBarButton


Name the button "Delete" and press the ... on the property onAction. This will allow you to create a new method which you can later fill with coding.


Add another button "Close Details" the same way to the toolbar. OnAction select that this button fires the plug "Out".

Create, deploy and run the application. The navigation should already work but no data is exchanged.
In the implementation of EntryView select the method wdDoInit() and set some default values for your EntryView.
wdContext.currentNewPersonElement().setFIRSTNAME("Lars");
wdContext.currentNewPersonElement().setLASTNAME("Vogel");
wdContext.currentNewPersonElement().setMARRIED(true);
In the implementation of EntryView select the method onActionAddtotable and include the following coding.
public void onActionAddtotable(
com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent) {
// @@begin onActionAddtotable(ServerEvent)
// $$begin ActionButton(-1044226048)
IPersonElement newPerson = wdContext.nodePerson().createPersonElement();
INewPersonElement entry = wdContext.nodeNewPerson().currentNewPersonElement();
if (entry.getFIRSTNAME() != null && entry.getFIRSTNAME() != null) {
// Mapping
IPersonElement newPerson = wdContext.nodePerson().createPersonElement();
INewPersonElement entry = wdContext.nodeNewPerson().currentNewPersonElement();
newPerson.setFIRSTNAME(entry.getFIRSTNAME());
newPerson.setLASTNAME(entry.getLASTNAME());
newPerson.setMARRIED(entry.getMARRIED());
wdContext.nodePerson().addElement(newPerson);
wdThis.wdFirePlugOut();
}
// Here should be an information for the user to fill in the last and first name
To implement the delete button, select the implementation of TableView and include the following coding in onActionDeleteSelectedItem
List list = new ArrayList();
// Get the element of the multiselection
for (int i = 0; i < wdContext.nodePerson().size(); i++) {
if (wdContext.nodePerson().isMultiSelected(i)) {
list.add(wdContext.nodePerson().getElementAt(i));
}
}
// // Remember also the lead selection
if (wdContext.nodePerson().getLeadSelection() != -1) {
int j = wdContext.nodePerson().getLeadSelection();
list.add(wdContext.nodePerson().getElementAt(j));
}
// Now delete the values for the selection
for (Iterator iter = list.iterator(); iter.hasNext();) {
IWDNodeElement element = (IWDNodeElement) iter.next();
wdContext.nodePerson().removeElement(element);
}
Run your application and enjoy the rich functionality your applications gives your.
Create a new Web Dynpro Project called "SimpleValueHelp" with a component and a view "ValueHelpView".
Create a simple type "PictureSettings" in the dictionary. Select the in tab Enumeration. Create enumerations with key "http://www.vogella.de/images/Java.jpg" and Description "Java" and "http://www.vogella.de/images/Eclipse.jpg" with Description "Eclipse".



Create in the view context "Setting" with the value attribute "Source". In the property "type" of attribute "source" bind it to the type "PictureSettings". Set cardinality of "Setting" to 1:1.

Set tab layout of the view "ValueHelpView". Use "Apply Template" to include the context in the view and select the editor "DropDownByKey". Perform this again and select the editor "InputField". Format your fields they way you like it.


Create application and run it.

Include an image into your view. Add a value attribute "Visibility" to your context of the view and bind it to the package com.sap.ide.webdynpro.uielementdefinitions and field Visibility. Bind this context element to the property visible of the image UI element. Bind attribute "source" to the context element "Settings.Source" and attribute "alt" to "Settings.Source".

In method wdDoInit() of the view hide the image.
wdContext.currentPictureElement().setVisibility(WDVisibility.VISIBLE);
In the drop-down list select properties and press the ... button. Create method "ShowImage" with the follwing coding
wdContext.currentPictureElement().setVisibility(WDVisibility.NONE);
Assign your method "ShowImage" also the the other input selection element. If you change the selection the new picture should get displayed.
Deploy and run your application. Select a value and verify that the picture is displayed.
Context and UI element can also be created via Java coding.
Create a new project "Dynamic" and a component and view "Empty". Delete the existing element on the view. The view should be completely empty.
Switch to the implementation of your view and select the method wdDoInit().
Maintain the following coding.
IWDNodeInfo nodeInfo = wdContext.getNodeInfo();
// Define value node
IWDNodeInfo person =nodeInfo.addChild("Person", null, true, false, true, false, false, true, null, null, null);
person.addAttribute("FirstName", "ddic:com.sap.dictionary.string");
person.addAttribute("LastName", "ddic:com.sap.dictionary.string");
// Get the context node
IWDNode node = wdContext.getChildNode("Person", 0);
// Create an element
IWDNodeElement element = node.createElement();
// Fill it with value
element.setAttributeValue("FirstName", "Lars");
element.setAttributeValue("LastName", "Vogel");
// Add to the content
node.addElement(element);
Switch to the implementation of your view and select the method wdDoModifyView().
Maintain the following coding.
if (firstTime) {
// Get the reference to the UI rool elemnet
IWDTransparentContainer rootElement = (IWDTransparentContainer) view.getRootElement();
// Set the layout manager to MatrixLayout
rootElement.createLayout(IWDMatrixLayout.class);
// Get the metadata of the node
IWDNodeInfo nodeInfo = wdContext.getChildNode("Person", 0).getNodeInfo();
for (Iterator iter = nodeInfo.iterateAttributes(); iter.hasNext();) {
IWDAttributeInfo attributeInfo = (IWDAttributeInfo) iter.next();
IWDLabel label =(IWDLabel) view.createElement(IWDLabel.class,attributeInfo.getName() +"Label");
label.setText(attributeInfo.getName());
label.createLayoutData(IWDMatrixHeadData.class);
label.setLabelFor(attributeInfo.getName() +"Input");
// Add the label to the UI
rootElement.addChild(label);
IWDInputField inputField =(IWDInputField) view.createElement(IWDInputField.class,attributeInfo.getName() + "Input");
inputField.createLayoutData(IWDMatrixData.class);
inputField.bindValue(attributeInfo);
// Add the input field to the UI
rootElement.addChild(inputField);
}
}
Create and run an application and see your dynamically created UI element filled with your dynamically created content.

Select tab Actions of the view and press "New".

This will create a new method. Fill the method so that the context is deleted.
IWDNode node = wdContext.getChildNode("Person", 0);
if (node.getLeadSelection() != -1) {
IWDNodeElement deleteNode = node.getElementAt(node.getLeadSelection());
node.removeElement(deleteNode);
}
Change the method wdDoModifyView() to the following
if (firstTime) {
// Get the reference to the UI rool elemnet
IWDTransparentContainer rootElement = (IWDTransparentContainer) view.getRootElement();
// Set the layout manager to MatrixLayout
rootElement.createLayout(IWDMatrixLayout.class);
// Get the metadata of the node
IWDNodeInfo nodeInfo = wdContext.getChildNode("Person", 0).getNodeInfo();
for (Iterator iter = nodeInfo.iterateAttributes(); iter.hasNext();) {
IWDAttributeInfo attributeInfo = (IWDAttributeInfo) iter.next();
IWDLabel label =(IWDLabel) view.createElement(IWDLabel.class,attributeInfo.getName() +"Label");
label.setText(attributeInfo.getName());
label.createLayoutData(IWDMatrixHeadData.class);
label.setLabelFor(attributeInfo.getName() +"Input");
// Add the label to the UI
rootElement.addChild(label);
IWDInputField inputField =(IWDInputField) view.createElement(IWDInputField.class,attributeInfo.getName() + "Input");
inputField.createLayoutData(IWDMatrixData.class);
inputField.bindValue(attributeInfo);
// Add the input field to the UI
rootElement.addChild(inputField);
}
// Get an action handle
WDActionEventHandler actHandler = WDActionEventHandler.DELETE_DATA;
IWDAction myaction = wdThis.wdCreateAction(actHandler,
"Delete");
// Now create the button
IWDButton button = (IWDButton) view.createElement(IWDButton.class, "DeleteButton");
button.createLayoutData(IWDMatrixHeadData.class);
// Assign handler to button
button.setOnAction(myaction);
rootElement.addChild(button);
}
Test your new functionality.
It is possible to define parameters for actions. These parameters can be used in the methods to determine the behavior of the action.
Select your action and add the parameter "inputValue" to your action. This will add a parameter to the action.

This parameter can be filled via the following coding and used in any way a value can be used, e.g. within a message or as assignment to a context attribute.
// inputValue is the parameter of the method
button.mappingOfOnAction().addParameter("inputValue", "You pressed the button");
If at any point in time you receive a not explainable compilation errors, select your Web Dynpro project and select "Reload". This will reload the XML files and re-created the complete coding.
Thank you for practicing with this tutorial.
Please note that I maintain this website in my private time. If you like the information I'm providing please help me by donating.http://sdn.sap.com SAP Developer Network
http://www.jax-magazine.com/itr/online_artikel/psecom,id,583,nodeid,147.html Highway 1 - From Dynpro To Web Dynpro
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/5439 Filter and Sort in a Web Dynpro Table - Blog Entry
https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/7260 Building a compley OVS Value help - Blog Entry