Thursday, December 27, 2012

ADF Mobile : Device Interaction API - Pictures, GPS and Email With Attachments

During the AMIS ADF Masterclass I showed how to take a picture from within an ADF Mobile application, attach it to an Email and send that email out to several recipients. To top it of, I even added the GPS coordinates to the subject, so you know where the picture was taken. And all of that with the push of one single button. Sounds complicated ? Well actually it is very simple.

There are two ways to interact with device services. One is by using the page Definition, the second is by using the API.I decided not to use the pageDef, but to invoke the device datacontrol from java by using the API. Then it is also possible to invoke multiple actions in one java method. In this case I take a picture, get the coordinates and send an email.

How to take a picture ?
Taking a picture is easy. Just call the getPicture() method, and make sure (for this use case) to set Destination Type to File.
 public String getPicture(){  
   //destinationType = 1 so that the image is returned as a filename      
   String theImage = DeviceManagerFactory.getDeviceManager().getPicture(  
            100  
           ,DeviceManager.CAMERA_DESTINATIONTYPE_FILE_URI  
           ,DeviceManager.CAMERA_SOURCETYPE_CAMERA  
           , false  
           ,DeviceManager.CAMERA_ENCODINGTYPE_PNG  
           ,0  
           ,0);  
   return theImage;  
   }  

That takes care of taking the picture.

How to get the current coordinates ?
By invoking getCurrentPosition it is very easy to get the GPS coordinates. Simply call the getCurrentPosition() method, and you will get the current coordinates. The coordinates are refreshed every 60 seconds.
 public Location getPosition(){  
   Location currentPosition = DeviceManagerFactory.getDeviceManager().getCurrentPosition(  
                                    60000  
                                   , true);  
   return currentPosition;  
 }  


How to send an email ?
First take a look at the signature of the sendEmail() method. This immediately makes clear how to proceed from here...
 DeviceManagerFactory.getDeviceManager().sendEmail(  
         java.lang.String to  
         ,java.lang.String cc  
         ,java.lang.String subject  
         ,java.lang.String body  
         ,java.lang.String bcc  
         ,java.lang.String attachments  
         ,java.lang.String mimeTypes)  

The signature explains how it works. All that is needed are Strings. If you want to use multiple recipients, you need to separate them by comma's. The final question is: "how to attach the image that was just created ?".

Attaching the image.
You can do two things. Either use the String that is returned by calling getPicture(), or directly attach the file from the Temporary Directory which I do in this case.
 public void sendEmail(String attachment, Location here){  
   String directoryPathRoot = AdfmfJavaUtilities.getDirectoryPathRoot(0); //TemporaryDirectory  
   String content = "Amis wishes you all the best for 2013. This email contains an image as attachment. ";  
       content = content + "The picture was taken at: latitude=" + here.getLatitude() +  
            ", longitude=" + here.getLongitude();  
   attachment = directoryPathRoot+"/Pic.png";  
   DeviceManagerFactory.getDeviceManager().sendEmail("my.mail@company.org"  
                            , null  
                            , "Merry Xmas and a Happy new year"  
                            , content  
                            , bcc  
                            , attachment  
                            , "image/jpg");  

The content and bcc in the above code sample are Strings that can be set in the method.

Putting it all together
The only thing you need is a button to invoke a method in the bean.
 amx:commandButton text="Take Picture" id="cb3"  
                actionListener="#{pageFlowScope.interactionBean.executeLogic}"  

The method executeLogic() does the magic by invoking all three methods described above.
 public void executeLogic(ActionEvent actionEvent) {  
   String att = getPicture();    
   Location whereAmI = getPosition();  
   sendEmail(att, whereAmI);  
   }  


Push the button, the camera is invoked, and after that, the email client is invoked, showing an email with the attachment, the content (including GPS coordinates) and the recipients.

Sunday, December 16, 2012

Book Review : Oracle ADF Real World Developer's Guide

In October 2012 yet another ADF Book was published. This book "Oracle ADF Real World Developer's Guide" is authored by Jobinesh Purushothaman. Jobinsh works with Oracle as a Principal Solutions Architect for the Oracle Application Development Framework. The book is full of essential tips and tricks for building ADF applications. In this post I will share my book review with you and I give you the chance to win a free copy.



This book is suitable for ADF developers who are looking forward to build healthy and better performing applications using Oracle ADF. A book filled with step-by-step instructions and real-time examples with illustrations, diagrams, and tips that help developers learn the visual and declarative programming model offered by ADF. Using this book, readers will learn to get started with building business services using ADF business components, validate business data in different layers of an application and understand the use of EJB and web services in an ADF application.

The book contains 12 Chapters containing anything from getting started to Advcance topics.

Before I go into each chapter, I must say that this book has a couple of outstanding ways of explaining the ADF Framework. First of all there are many simple diagrams (and images) explaining the framework and parts of the framework. These diagrams are easy to understand, because thay only contain relevant information. You are not being distracted by colors or misleading images. It is just simple images, but very clear.

Next there are the sequence diagrams. These diagrams explain what exactly happens (at class level) when for instance you issue execute query from an ADF Application. As far as I know this is the first book that uses these sequence diagrams to explain ADF in a very clear way.

Finally I need to point out the valuable code samples that are in the book. Get yourself a digital copy so you can easy copy and past these code snippets into your ADF application.

Now lets take a look at the chapters.

Part I : getting started

1 : Getting Started with Oracle ADF
The most interesting part for me is the section on "Comparing the Fusion web application technology stack to the Java EE web application". This is explaining ADF in the context of a Java EE application. Currently I am involved in a project where we need to "rebuild" a Java EE application in ADF. There is a lot of discussion in this project about responsiblity of eaach layer. This chapter can help Java EE developers understand the ADF framework. The image on page 13 of the book ADF and Java EE by putting both in one diagram next to eachother.

Also the part about the generated Metadata files is valuable. Ussualy these files (like adf-settings, weblogic-application) are taken for granted, but Jobinesh explains what all the metadata files are about.

Part II : ADF Business Components

2 : Introduction to ADF Business Components
3 : Introducing Entity Object
4 : Introducing View Object
5 : Advanced Concepts on Entity Objects and View Objects
6 : Introducing the Application Module
This part provides a detailed look at how entities, view objects and application modules are defined and how they work at runtime. I was impressed by the level of detail in chapter 2. It is great that I have a couple of more chapters that go even into more detail.  This chapter really made me wanna continue reading. Chapters 3 and 4 are introducing the basic concepts of View Objects and Entity Objects. Both chapters contain very helpful sequence diagrams explaining what happens internally within entity objects and view objects.

At the start of chapter 5 Jobinesh tells the reader to "Take a deep breath and prepare yourself".  The part that follows takes a deep dive into entity objects. This chapter is full of in depth Entity Object knowledge. Allthough I have been working with ADF for many many years there were some interesting featured in this chapter that I did not know about. (mainly because I never had to use these). For instance, did you know that you can call getAttribute(attrIndex,EntityImpl.ORIGINAL_VERSION) on an entity object to read the originally retrieved value for an attribute ? I allways use(d) getPostedAttribute(int attribIndex).

At the end of the Entity Object section there is an interesting part on "Building programmatically managed entity objects" including code samples.

The most interesting part of the View Object section is about working with ViewCriteria Programmatically. Also the section about working with XML data is a noce one. I never got to use this functionallity in real life. Jobinesh explains very well how to do this, and I hope to get a use case soon. The chapter ends with a section about "Building business components dynamically".

After reading chapter 5 I can only say one thing: "I am impressed !".

Chapter 6 covers important topics like properties, passivation, activation, application module pooling.

7 : Binding Business Services with the User Interface
Chapter 7 really contained nothing new to me. However, if you are new to ADF, this chapter contains very good explanation of the binding layer. There is an interesting part about "Invoking an application module from a Java servlet". I did use this approach in several occassions. It is good to have a section on this in the book. Again in this chapter there are several simple diagrams that help you understand what happens in the binding layer.

8 : Building Data Bound Web User Interfaces

This is about building data bound web user interfaces. It has a small section on layout components. It also talks about working with tree and treetables programmatically. One of the things I learned form this chapter is how to use the "RowCountThreshold" attribute in an iterator binding. Never did that before.... On page 327 there is a "best practice" that you should know about: "If the scope of the managed bean is higher than the request, then you should not bind the UI components' elements in the JSF page with the UI component instances defined in a managed bean using the binding attribute in the component tag"

9 : Controlling the Page Navigation
For me there really wasn't anything new but, if you are new to ADF, it is again a very nice chapter.

10: Taking a Closer Look at the Bounded Task Flow
This chapter takes a deep dive into the bounded taskflow. There are sections on "dynamic taskflow calls, Lazy Loading and there is even a section on Contextual events.

11: More on Validations and Error Handling
Yet another chapter containing very valuable tips. Very interesting is the part where you learn how to vreate a custom validator containing client side java scriupt validation.
Also you learn how to define model layer validation which is in fact rarely used. And there is an interesting diagram that helps you understand how the framework engages
DCErrorHandlerImpl during the page life cycle for handling exceptions thrown by business components when accessing them in the binding context

12: Oracle ADF Best Practices
This chapter summarizes the best practices and coding tips that developers will find useful when building ADF applications. Learning the best practices will help you to avoid common pitfalls that others might have faced.  The content for this chapter is based on input from various teams who have successfully used ADF.

My advise is that you should really buy this book ! It is full of valuable tips and tricks ! When you buy this book, all code samples in this book are available online so you can download these and play with them.
The book is available here.

Get yourself a free Christmas present !

For the contest I have two copies of Oracle ADF Real World Developer’s Guide to be given away to two lucky winners.

How you can win:
To win your copy of this book, all you need to do is come up with a comment below highlighting the reason "why you would like to win this book”.

Please note: Winners residing only in the USA and Europe would get a chance to win print copies. Others would be provided with eBook copies.
Duration of the contest & selection of winners:The contest is valid for 7 days (contest ends 23-12-2012 23:59 GMT) , and is open to everyone. Winners will be selected on the basis of their comment posted.

Wednesday, October 31, 2012

ADF Mobile : Your First Navigation and Device Interaction

Now ADF Mobile is generally availble, it is now time to create your first ADF Mobile application. In this post I will show you how to create a simple application that contains of two pages with navigation. A bonus for this post is that you will see how to get a picture from the filesystem (or by using the device camera) from within your ADF mobile application Getting started To work with ADF mobile you need to download the JDeveloper 11.1.2.3 and the ADF mobile extension and install both. After installing JDeveloper and adding the ADF Mobile extension, you will be able to create a new ADF Mobile Application. In the new gallery you wil find the ‘Mobile Application’ under the applications node.
Accept all the defaults and the JDeveloper application is created for you. What you see are two projects. One called the application controller, and a second one, the viewController. JDeveloper also adds application-level and project-level artifacts.
The applicationController contains several artefacts such as the Datacontrol definition, files for skinning, and a class called LifeCycleListenerImpl. This class can be used to add your own functionality during the different stages of the application life cycle. In the viewController you only see a file called adfmf-feature.xml. This file is used to add, remove, or edit the application features embedded within the mobile application. At an application level, the adfmf-application.xml file is created, which enables you to configure the mobile application. You will also find application level files that are created for you such as platform specific images for splashscreens and application icons. These can be customized.
That is all you need to get started, and luckily, it is all created for you. Your first simple ADF Mobile Application Lets create a two simple java classes to be our data provider.
and ...
Now create a datacontrol based on the Contacts class.
With the datacontrol in place, it is now time to create the page that will use the Contact collection. Creating features, taskflows and pages Go to the adfmf-feature.xml file in order to add a new feature. This can be done by clicking the plus icon. For now, lets call this feature ‘contacts’.
This only adds an entry in the xml file, but the actual page or taskflow implementing the feature is not created. This is also an action that can be done from within the adfmf-feature.xml file. By clicking the plus icon (you must be on the content tab for the feature) you can pick either AMX page or taskflow. Choose taskflow and continue.
The taskflow editor now appears with the empty newly created taskflow. Now it is time to add view activities to the taskflow. If you are familiar with ADF development, this the exact same approach as if you were building a ‘regular’ ADF application. Just drag the viewactivities from the component pallet onto the taskflow diagram and add navigation between them. In this case I created two viewactivities. One to show the list, and a second on create a picture of the selected contact.
Creating the pages The next step is creating the actual pages. This can be done by doubleclicking the view activities on the taskflow diagram. Start with the list page. In the create page wizard, uncheck ‘both’ action checkboxes. There is no need got these now.
On the list page it makes sense to show the content in a ‘List’ layout. With ADF Mobile and JDeveloper you can create this exactly the way you want. Drag and drop the contact collection from the datacontrol onto the page and select ‘ADF Mobile List View’ from the context menu.
In the ListView gallery you can pick from a lot of different Lists, but for now, just stick with the default. For the list view only display the last name. No need for the firstname, however, if you really want to….. just add it. The result should look somewhat like this:
This page will work if all went according to plan. The next step is to add navigation to the second page. Adding navigation In order to navigate to the second page, and to see the selected trainee on this second page you need to do two things. The page needs to know when to navigate. For that, we can use the action property of the component. Change the action property to “add” which corresponds to the navigation case defined in the taskflow. Either type it, or select it from the dropdown.
Next make sure that the selected row is made available on the second page. For this a setPropertyListener can be used (Hey, you already knew that from your ADF experience). Set the from property to #{row}, and the to property to #{pageFlowScope.row}.
Now create the second page by doubleclicking on the viewactivity in the taskflow editor, or via invocing the new gallery and pick create new ADF Mobile Page (AMX). In the header facet the #{pageFlowScope.row} reference can be used to display the whole name of the selected contact. Now create the second page by doubleclicking on the viewactivity in the taskflow editor, or via invocing the new gallery and pick create new ADF Mobile Page (AMX). In the header facet the #{pageFlowScope.row} reference can be used to display the whole name of the selected contact.
 <amx:facet name="header"/>  
 <amx:outputText value="Take picture of #{pageFlowScope.row.firstname} #{pageFlowScope.row.lastname}" id="ot1"/>  
 <;/amx:facet>;  
Creating the picture This page will be used to take a picture of the contact. This looks pretty complicated but as a matter of fact, it is very straightforward. ADF Mobile ships with a deviceFeature datacontrol. On of the operations in here is the ‘getPicture’. Drag this operation from the datacontrol onto your page, and drop it as a ADF Mobile Button.
In the Edit Action Binding set destinationType to 1 so the image is returned as a fileName, and specify width and height for the image.
You might want to play with the sourcetype. On a simulator this makes no sense, but on an actual device you can invoke the camera by setting sourceType = 1. An action binding is added to the corresponding pagedefinition file. Again, you already know this from regular ADF development.
 <methodAction id="getPicture" RequiresUpdateModel="true" Action="invokeMethod" MethodName="getPicture"  
 IsViewObjectMethod="false" DataControl="DeviceFeatures"  
 InstanceName="data.DeviceFeatures.dataProvider"  
 ReturnName="data.DeviceFeatures.methodResults.getPicture_DeviceFeatures_dataProvider_getPicture_result">  
 <NamedData NDName="quality" NDType="int"/>  
 <NamedData NDName="destinationType" NDValue="1" NDType="int"/>  
 <NamedData NDName="sourceType" NDType="int"/>  
 <NamedData NDName="allowEdit" NDType="boolean"/>  
 <NamedData NDName="encodingType" NDType="int"/>  
 <NamedData NDName="targetWidth" NDValue="150" NDType="int"/>  
 <NamedData NDName="targetHeight" NDValue="200" NDType="int"/>  
 </methodAction>  
Now drop the returnvalue of the getPicture from the datacontrol on your page as an outputtext. Remove that textfield immediately. The Dnd action was only nessecary in order to create a binding for this returnvalue. It can now be used as the source for an component.
 <amx:image id="file" source="#{bindings.Return.inputValue}"/>  
Finally add a button to navigate back to the list page. The page would look like this:
 <?xml version="1.0" encoding="UTF-8" ?>  
 <amx:view xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xmlns:amx="<a href="http://xmlns.oracle.com/adf/mf/amx">http://xmlns.oracle.com/adf/mf/amx</a>"  
 xmlns:dvtm="<a href="http://xmlns.oracle.com/adf/mf/amx/dvt">http://xmlns.oracle.com/adf/mf/amx/dvt</a>">  
 <amx:panelPage id="pp1">  
  <amx:facet name="header">  
    <amx:outputText value="Take picture of #{pageFlowScope.row.firstname} #{pageFlowScope.row.lastname}" id="ot1"/>  
  </amx:facet>  
  <amx:commandButton actionListener="#{bindings.getPicture.execute}" text="getPicture" disabled="#{!bindings.getPicture.enabled}" id="cb1"/>  
  <amx:image id="file" source="#{bindings.Return.inputValue}"/>  
  <amx:commandButton action="return" text="List" id="cb2"/>  
 </amx:panelPage>  
 </amx:view>  
Deploying and testing Before being able to test the application you need to create a deployment profile. Go to your application properties and select “new deployment profile” and create one for ADF Mobile for iOS. Accept the defaults for now.
Now you can deploy the application to an iOS simulator or device. After deploying to an iOS simulator the application works. Click on the application icon to start the application. The app starts and you will see the list view. Click (or tab on a real device) on one of the names in the list view. The Picture view opens empty with the name of the selected contact in the header. Now you can invoke the getPicture button. .
On a real device the camera can be invoked if you would set sourcetype = camera (or 1), on the simulator, you get to pick an image from the gallery. After taking the picture (or selecting it), the image displays in the application, right where we want it.
I created this application on a Macbook so I can use the iOS simulator to run the application. However, the exact same application will run on an iPhone, iPad if you deploy it to the device instead of deploying it to the simulator. And it will also run on Android devices. The only thing you need to do is create a deployment profile for Android and deploy to the actual device. Footnote This blogpost (originally posted on the amis technology blog) is created under the assumption that you have already installed all SDK’s for Android Development, and the xCode for iOS development. Also all settings for Android and iOS development in JDeveloper need to be set and point to the android SDK and xCode locations. Running on Android Simulators is extemely slow, so you will probably need to connect your device and deploy to it in order to test your application. I will propbably write more on these topics in the near future.

ADF Mobile : Finally released and ready to use

After extensive beta testing oracle announced last week that ADF Mobile is now generally available and can be used to build multi platform on device apps. I finally am allowed to share my knowledge in blogposts and other kinds of publications. Using JDeveloper and the ADF Mobile extension, it is very easy to create apps for both the iOS and Android platform. If you only want to create apps for Android, you don’t need a mac, however if you want to create apps voor iOS you really do need a mac to compile the ADF mobile app for iOS.
ADF Mobile provides a natural extension of enterprise/internet applications to mobile clients by providing tools, services, and infrastructure to protect against technology shifts. An application built with ADF Mobile framework installs on a smart device, renders user interface via HTML5, and has access to device services. This means the programming model is primarily web-based, which offers consistency with other enterprise applications as well as easier migration to new platforms. But the application has access to device services, enabling a richer experience for users than a browser alone can offer. The architecture of ADF Mobile.
A short explanation of the components on the image: The Device Native Container represents an application container or template compiled as device native application binary which provides the run-time environment for an ADF Mobile application to run as an on-device, native application in the mobile device’s operation system (for example, Apple iOS). The Web View is a part of the device native container that uses a mobile device’s web engine to display and process web-based content. In an ADF Mobile application, the web view is the primary mechanism to render and deliver the application user interface. Server HTML represents a web-based user interface that is generated on the server (ADF Mobile browser and Oracle ADF Faces rich client-based pages) and delivered as a Web page to the ADF Mobile application. The Local HTML represents web pages developed using JDeveloper or third-party tools that are directly embedded within an ADF Mobile application. ADF Mobile AMX Views are based on the ADF Mobile AMX technology that delivers a JSF-like development experience to working with an HTML5-based user interface. ADF Mobile AMX views are defined using UI and code editors provided by JDeveloper. These views are embedded into an ADF Mobile application and deployed to a mobile device. At run time, the JavaScript engine in the web view renders ADF Mobile AMX view definitions into HTML5 components. ADF Mobile AMX components are built to deliver a mobile optimized user experience out of box. These components support the device native user experience through extensive animation and gesture support. The ADF Controller is represented by a mobile version of Oracle ADF controller that supports a subset of Oracle ADF task flow components available to a server-based Oracle ADF application. Java provides a Java run-time environment for an ADF Mobile application. This Java Virtual Machine (JVM) is implemented in device-native code, and is embedded (or compiled) into each instance of the ADF Mobile application as part of the native application binary. Managed Beans are Java classes that can be created to extend the capabilities of ADF Mobile, such as provide additional business logic for processing data returned from the server. The ADF Model in an ADF Mobile application supports a subset of business logic components available to a server-based Oracle ADF application. ADF model contains the binding layer that provides an interface between the business logic components and user interface, as well as the execution logic to invoke REST or SOAP-based web services. PhoneGap is an open-source code library that provides a common JavaScript API to access various mobile device services, such as the camera. PhoneGap provides a majority of the device services integration for an ADF Mobile application. Local Data refers to data stores that reside on the device. In ADF Mobile, these are implemented as encrypted SQLite databases. ADF mobile enables you to interact with mobile device services such as the camera, the email client, contacts and more. There is no need for you to know how to interact with the device because ADF mobile uses phonegap to abstract these device specific api’s. On top of that ADF mobile uses a device datacontrol to even abstract phonegap. The device datacontrol can be used in the exact same way as any other datacontrol. You can drag and drop operations from the data control onto your page. In ADF Mobile, data controls behave similarly to the way they work in Oracle ADF. Device data controls appear within the Data Controls panel in JDeveloper, allowing you to drag and drop the primary data attributes of data controls to your application as (text) fields, and the operations of data controls as command objects (buttons). Performing such drag and drop actions will generate standard EL bindings in your application in the appropriate properties for the controls that are created. The normal ADF bindings for those actions (represented by a general DataControls.dcx file, to point at the data control source, and the page bindings, to link the specific page’s reference to the data control) will be present, allowing the runtime to process the bindings when your application executes.

Sunday, September 30, 2012

My OOW 2012 Session Schedule, and more

This years visit to Oracle Open World is for me the best of both worlds. First of all I get to attend one of the biggest, if not the biggest, IT conferences in the world. Second, I have two presentations. Both are on Sunday afternoon. The first one is a Fusion Middleware Live Development session where we as a team show you the steps involved in creating an application using nearly all parts of Fusion Middleware. My role in the team is to explain how we build the UI part of the application and how we used ADF to do that. Also I will show you how you can create an interactive dashboard using DVT components such as graphs and gauges. More info on this session can be found here. Right in the middle of this session I have to leave the room in order to go to my next presentation. This presentation is called "mobile development with Oracle JDeveloper and ADF". In this session I show you some of the options that you have if you want to extend your enterprise application to mobile devices. I cannot go into much detail yet. Having said that, I've probably said enough. More info is available here. After my presentation I head straight to the Oracle Benelux Networking Event which is sponsored by AMIS. The rest of the week is also dedicated ADF and to mobile development. Monday, I'll be attending one of the 8 Hand on Labs where one can develop mobile applications for iOS and Android with ADF mobile. Tuesday is a mashup day containing session about ADF, Forms and SOA. After that, on Wednesday I have several more sessions on mobile development. Data Visualization best practices on mobile devices, spatial mashup on mobile devices, and about next generation infrastructure for HTML5 and mobile apps. And maybe I will meet you at the OOW 2012 Bloggers Meetup. Thursday I call a "whatever comes up day", where I will probably do a lot of handson stuff, and in the evening I have diner with all of the AMIS employees that are also at OOW. Keep an eye on this weblog and read all my Oracle Open World news and experiences. Now if your are trying to find me, this is where I am:
The conference season doesn't end here. After Oracle Open World I will present at one more international conference this year. In december I have two presentations at the UKOUG 2012 conference.I'm proud of having presentations at OBUG Connect 2012, ODTUG KScope12, Oracle Open World 2012 and UKOUG Conference 2012.

Thursday, July 12, 2012

ADF 11g : Adding close this / close others / close all to the UIShell

During one of my presentations at ODTUG KScope12 in San Antonio I showed how to add a menu with close this / close others / close all to the UIShell. This pattern is very common throughout modern browsers and other programs that use any kind of tabbed navigation.

Even JDeveloper itself uses this functionality. In this post I'll describe how to add this functionality to the UIShell.

The UI Shell.
The UIShell used in this post is not the UIShell that can be downloaded from Oracle OTN. There are several reasons why I do not use this particular UIShell, but the main reason is that it is not state safe. The UI Shell that I use, is the one that is available on blogs.oracle.com/jheadstart/entry/core_adf11_uishell_with_dynamic
With that UI Shell it is actually very simple to implement this pattern.

The Menu Itself
The menu is implemented in a popup, containing a menu component woth nested commandmenuitems. These items are responsible for either close this, close all and close others. When the menu item is invoked, a set propertyListener is fired in order to store the actual tab, that the menu was invoked on, in memory. Notice that I user a managed bean called DynTabManager. I will show what code to add to this class later.
The menu is placed in the DynamicTabsPageTemplate.


 <af:popup id="contextMenu" contentDelivery="lazyUncached" 
   eventContext="launcher" launcherVar="source"> 
   <af:menu id="men1" text="#{source.attributes.menuInvokedOnTab}"> 
    <af:commandMenuItem id="cmi1" text="close" 
     actionListener="#{viewScope.dynTabManager.closeThis}"> 
     <af:setPropertyListener from="#{source.attributes.menuInvokedOnTab}" 
      to="#{viewScope.
dynTabManager.menuInvokedOnTab}" 
      type="action"/> 
    </af:commandMenuItem> 
     <af:commandMenuItem id="cmi2" text="close others" 
      actionListener="#{viewScope.
dynTabManager.closeOthers}"> 
      <af:setPropertyListener from="#{source.attributes.menuInvokedOnTab}" 
      to="#{viewScope.
dynTabManager.menuInvokedOnTab}" 
      type="action"/> 
     </af:commandMenuItem> 
     <af:commandMenuItem id="cmi3" text="close all" 
      actionListener="#{viewScope.
dynTabManager.closeAll}"> 
      <af:setPropertyListener from="#{source.attributes.menuInvokedOnTab}" 
      to="#{viewScope.
dynTabManager.menuInvokedOnTab}" 
      type="action"/> 
     </af:commandMenuItem> 
    </af:menu> 
   </af:popup> 



Invoking the menu
The menu will be invoked on a tab. The DynmicTabs.jsff is responsible for this. The tabs are implemented by a navigationpane, containing commandNavigationItems. By adding a clientListener to the commandNavigationItem, I am able to invoke a javascript function that will show the context menu.

   <af:navigationPane ...........>  
   <af:commandNavigationItem ...............>  
    <f:attribute name="tabId" value="#{tab.id}"/>  
    <af:clientListener method="showMenu" type="contextMenu"/>  
    <af:clientAttribute name="menuInvokedOnTab" value="#{tab.id}"/>  
   </af:commandNavigationItem>  
   </af:navigationPane >  
 




 This javascript finally shows the context menu. 
 

 function showMenu(evt) { 
   var popup = AdfPage.PAGE.findComponent("pt:contextMenu"); 
   …………….. 
   popup.show(hints); 
   evt.cancel(); 
 } 


Implementing the closeAll, CloseThis and CloseOthers
For implementing the actual functionality backing the menu, I use an existing method in th DynTabManager class. This class contains the removeTab() method that is responsible for closing a tab when the close icon is clicked.

I simply call this method for all tabs that I need to be closed, regardless of what menu item was invoked. Take a look at closeThis(). Becasue of the setPropertyListener that is invoked in the menu (see previous code sample) I know on which tab I invoked the menu. I use this to search the list with ActiveTabs. As soon as the Tab matches, I add it to a List with tabs to remove. I then simply call removeTab() for all tabs that need to be removed. In this case (closeThis) only one tab is added to the list with tabs to close. I also need to add one extra property to the DynTabManager class.

 private String _menuInvokedOnTab = null;  
For this I generate getters and setters, and I can use it in order to set and get the id of the Tab that the menu is invoked on.


 public void closeThis(ActionEvent action) { 
   String id = getMenuInvokedOnTab(); 
   List&lt;String&gt; tabsToRemove = new ArrayList(); 
   for (DynTab t : getActiveTabList()) { 
    String x = t.getId(); 
    if (id == x) { 
      tabsToRemove.add(x); 
    } 
   } 
   for (String t : tabsToRemove) { 
    removeTab(t); 
   } 
 } 

If I invoke close others, the method for this is almost similar, except that I don't remove the tab that matches the one that the menu was invoked upon. Instead of that, I remove all the other tabs (which makes sense when I pick closeOthers)

public void closeOthers(ActionEvent action) { 
   String id = getMenuInvokedOnTab(); 
   List&lt;String&gt; tabsToRemove = new ArrayList(); 
   for (DynTab t : getActiveTabList()) { 
    String x = t.getId(); 
      if (id != x) { 
       tabsToRemove.add(x); 
      } 
   } 
   for (String t : tabsToRemove) { 
     removeTab(t); 
   } 
 } 

Final option is the closeAll where I add all tabs in the ActiveTabList to the tabsToRemove. And for all the TabsToRemove I simply call removeTab(), that will handle the functionality to close a tab.


 public void closeAll(ActionEvent action) { 
   List&lt;String&gt; tabsToRemove = new ArrayList(); 
   for (DynTab t : getActiveTabList()) { 
    tabsToRemove.add(t.getId()); 
   } 
   for (String t : tabsToRemove) { 
    removeTab(t); 
   } 
 } 




The result
The result is a contextMenu that can be invoked on an open tab in de UIShell. It doesn't matter if you use an active or inactive tab. The menu will know where it was invoked.


 So when I pick closeOthers on the Jobs tab, the result looks like this.


Resources
JHeadstart weblog about UI Shell
Workspace can be downloaded here.

Thursday, June 28, 2012

My report from ODTUG KScope 2012.


I landed only a couple of hours ago and here's my report form Kscope 2012 in San Antonio. As I write this, KScope is still waking up for the final day. Anyway, for me KScope was over yesterday.

The venue, the JW Marriott San Antonio, was IMHO somewhat in the middle of nowhere, which is a pity given the fact that downtown San Antonio is beautiful. It took the free shuttle bus about 35 minutes to get there.

Anyway, I was not around for site seeing, I was visiting the conference. At the conference I joined the Fusion Middleware track, not only as an attendee but also as a presenter of two sessions..

With over 30 sessions and the Sunday Symposium, this years FMW track again was a very usefull track for everyone that wanted to learn about FMW.Most of the session where ADF related, however there were a couple of webcenter and SOA sessions as well.

Sunday

The FMW Sunday symposium started with a status update for Oracle ADF. Three product managers (sorry Duncan, I'm still not used to you not being one of them) talk about Oracle ADF. The most interesting news in this session was the announcement of the ADF Sample Page, a page with a growing number of ADF sample applications. Next session was about Mobile Design Patterns where Lynn Rampoldi and Edward Roske discussed design patterns for mobile solutions and actually showed these in action.
By the time that session ended, my jet-lag kicked in. I skipped a couple of session, but I was back in time to join the Oracle Fusion Middleware Experts Panel. We got some good questions. One of the attendees wanted to know from each panel member what his or hers favorite part of the ADF Framework was. Being in the middle of the panel (Duncan picked MDS, Chris picked Bounded Taskflows), I had to come with something different, but luckily nobody picked DVT yet so that was (and actually is) my favorite part. Sunday ended with the Speaker reception and the general welcome Reception.

Monday

Monday was a hard day for me. I didn't get any sleep (it were 3 hrs actually) and I had to give my first presentation at 8.30.... This presentation was called : "ADF - a Special Report" and was all about reporting solutions in ADF.  The slides, demos, and technical details will be posted in the next couple of weeks. I was somewhat nervous, given the fact that it was the first presentation of the conference, but I managed to deliver a presentation that in the end proofed to be the best one for that day in the Fusion Middleware Track. So I was very happy with that.


After this session I helped out Chris Muir for the rest of the morning (1000-1200) with a Hands On Training for Oracle ADF Data Visualization Components (ADF DVT). I think there were about 30 people attending the hands on and that they were all having a good time. Always funny to see how in hands on sessions trainees manage to create situations that I've never ever seen before. That is why I like to help out at handson labs.

Because of my busy schedule, Monday afternoon was the only possibility for me to get a glimps of San Antonio down town. I took the shuttle bus and walked around in downtown San Antonio. Very beautiful.





Tuesday

Tuesday was interview and meeting day. I started with an interview with the Usability team where  I could spill all of the enhancements me and my colleagues from AMIS want to see in JDeveloper. Next I had Lunch with Susan Duncan and David Folk, productmanager of ADF Mobile. During the lunch we discussed the ADF Mobile framework, things you can do with it, and things you can not (yet) do with it. After lunch I attended two more presentations.

The presentation of Chris Muir was about the UI Shell, and how to implement it in your application. Happy to see that Chris was fair enough to mention the facat that the UI Shell that is shipped by Oracle is not state safe. Next session was Lynn Munsingers session about ADF Mobile. Lynn explained the different scenarios for ADF in mobile environments. Somewhat confusing for the audience, where even 1 attendee asked the following question : “Can you explain what you mean by ADF ?” LOL

Anyway, now it was time to sit down and prepare for my second presentation.

Wednesday

My second presentation was titled “How to bring common UI patterns to ADF”. The slides, demos, and technical details will be posted in the next couple of weeks. In this session I talked about extensions to the UI Tabshell that make it even more usable. Also I showed how to record navigation history, and how you can use Active Data Service in order to push changes from the database to the browser. I had a good feeling about the presentation, and the reactions from the audience were fine. After lunch and some goodbye handshakes I took of to the airport and now I’m home. Had a great conference, did a lot of networking and got to know a bunch of nice people. Hope to see you next year in New Orleans

Thursday, May 31, 2012

ADF 11g : How to create a climate Graph with ADF DVT

While preparing my trip to ODTUG KScope I needed to know whether or not I have to take shorts with me. I looked up the average temperature in San Antonio for June and July, and I it was clear. Shorts are needed..... I struck me that wherever I looked, all the climate data was displayed in the same kind of graph.  Climate Graphs as shown in the picture below ussually contain information about temparature and precipitation, Maximum, Minimum and Average temperature per month as well as precipitation per month.

I wondered if it is possible to create such a graph with ADF Data Visualization Tools. In this post I'll show you how to create such a climate graph.

It looks quit obvious. Create a graph with 3 line sections and one bar section, a combination of several types. The DVT component set contains a component. This is the one to go for. You can even pick a Dual Y axis in order to show a temperature axis and precipitation axis


When you use this component you will find out that simply dragging and dropping, and setting the datapoints will not do the trick for you.

Because when you run the graph you will not get the desired result.


JDeveloper configures one type per datapoint, so you get an Area-, Line- and Bar graph all in one

There is need for some extra configuration.I need to tell what kind of markerType will be used by each series. First I set a default Marker type for the Lines. That will be applied to all series that do not have their own markertype defined. Next I set Bar as the marker type for the precipitation points.






  <dvt:seriesSet defaultMarkerType="MT_CURVE_LINE">
   <dvt:series markerType="MT_BAR" index="0" assignedToY2="true"/>
   <dvt:series index="1" assignedToY2="false"/>
   <dvt:series index="2" assignedToY2="false"/>
  </dvt:seriesSet>  


Finally I make sure that the Y axes do not autoscale, and have predefined MIN and MAX values.

<dvt:y1Axis axisMaxValue="120" axisMinValue="0" axisMaxAutoScaled="false"/> 
 <dvt:y2Axis axisMaxValue="10" axisMinValue="0" axisMaxAutoScaled="false"/> 



After these minor changes, I get exactly what I expected to see. At home it is chilly..............

............................................ while in San Antonio it is hot.
 

Monday, April 30, 2012

ADF Conference Season

Last week I attended OBUG Connect Conference, the Oracle Benelux User Group Conference. It was a great conference where I presented about the new to come ADF Mobile Framework. This is not yet Generally Available, but because of the good relationship with Oracle Productmanagement I was able to get hold of some very early sneak peaks so I could prepare a great presentation. I am not yet able to share anything in this post, however, feel free to contact me if you need to know more. I will see what I can do for you. As soon as I can share the presentation, I will host a link on my blog.

There is an oline photo impression of this conference, with a couple of photos of the presentation, and the live Fusion Middleware Development session.

Not only did I do my presentation, I was also part of the live Fusion Middleware Development team, next to Ronald van Luttikhuizen, Lonneke Dikmans, Steven Davelaar, Edwin Biemond en Lucas Jellema. An impression of this session can be found here.

Next month is all about preparing two sessions for ODTUG KScope 12, and writing papers for these presentations


The first session is about Reporting in ADF applications.

An ADF Special Report 
Oracle ADF is a very powerful framework for building enterprise applications. The framework, however, has no built-in solutions for reporting. In this session, you will learn how to fill this gap by using open source reporting solutions and solutions provided by Oracle.

The second one is about common UI patterns in ADF applications.

How to Bring Common UI Patterns to ADF 
When working with enterprise applications, you want to have the same user experience that you know from for instance office applications and browsers. People know how to use the features that can be found in browsers such as bookmarking, favorites, and working with tabs. The search mechanism provided by Google, that uses suggestions based on the text typed by the user, is so common that people expect this in every application. And there are more of these UI patterns. In this session, you will learn how to implement some of the common UI patterns in your ADF application.

I will keep you posted on this blog.