About Timo Hahn

I'm a principal consultant at virtual7 GmbH and work as developer and architect for Java and J2EE applications. Since 2004 I'm working with Oracle tools, starting with JDeveloper on Struts based web application using BC4J JBO Tags, BC4J business components and Oracle DB 10g up to JDeveloper 11.1.2 using ADF Rich Faces and the full ADF technology stack and web services. I'm an active member of hte OTN JDeveloper forum and blog on Oracle, JSF and ADF in special (https://tompeez.wordpress.com). I'm active participant in the local German ADF Community (a group of Oracle partners that strive for improving ADF and FMW sales in Germany and other German speaking countries).

JDeveloper 12c: Save IDE Window Positions

A question on the ODC JDeveloper and ADF space about how to save a specific arrangement of the editor windows came caught my attention. After thinking about this a moment I could not think of any configuration to do this. ‘Reset Windows To Factory Setting’ is not what was asked for.

Idea

I wanted to figure this out and came up with the idea to make a snapshot of the current running JDeveloper folder, then change the editor window settings, take another snapshot and then compare them.

Solution

I did this with my current installation of JDeveloper 12.1.3.0.0, but it should work the same way in other JDeveloper versions. After comparing the two snapshots using KDiff3 it turned out, that the information about the size, position, and visibility of the editor windows are stored in a subfolder of the system12.1.3.x.xx.xxxxxx.xxxx folder named ‘system_cache/config/Preferences’.

This folder contains many subfolders holding information about your preference settings. To save the data make a copy of this folder and store it somewhere. If you messed up the IDE you can restore the windows by removing the current ‘system_cache/config/Preferences’ folder and restore it from the saved one.

Attention

Before you restore the settings you should close JDeveloper and make another copy of the current ‘system_cache/config/Preferences’ folder.

Advertisements

ADF TreeTable Advanced Sample

Building a tree table isn’t straightforward if you want an appealing design. By design, I don’t mean something fancy with different fonts or colors, but I’m talking about the definition of the tree and its sub-notes.

Look at an af:treetable which is generated automatically for you using the Departments and Employees tables of the HR DB.

<af:treeTable value="#{bindings.DepartmentsView1.treeModel}" var="node"
              selectionListener="#{bindings.DepartmentsView1.treeModel.makeCurrent}"
              rowSelection="single" id="tt1">
    <f:facet name="nodeStamp">
        <af:column id="c1">
            <af:outputText value="#{node}" id="ot2"/>
        </af:column>
    </f:facet>
    <f:facet name="pathStamp">
        <af:outputText value="#{node}" id="ot3"/>
    </f:facet>
</af:treeTable>

This code, when put inside a simple page with an af:panelColletion, will produce this output:

As you see, there is only one column. You would not even know that you look at an af:treeTable. OK, the af:treeTable binding used is very simple:

For the first level and for the second level

In the remainder of this post, I show how to build a better-looking version with columns for the different data shown.

As usual, you can download the sample code from GitHub. See the link at the end of this post.

Small changes

To see the whole information in the one tree table column, we change the size of the column to 200px

<af:treeTable value="#{bindings.DepartmentsView1.treeModel}" var="node"
              selectionListener="#{bindings.DepartmentsView1.treeModel.makeCurrent}"
              rowSelection="single" id="tt1">
    <f:facet name="nodeStamp">
        <af:column id="c1" width=”200”>
            <af:outputText value="#{node}" id="ot2"/>
        </af:column>
    </f:facet>
    <f:facet name="pathStamp">
        <af:outputText value="#{node}" id="ot3"/>
    </f:facet>
</af:treeTable>

to get this output which shows all data, but still all in one column:

nodeStamp and pathStamp

When you look at the generated af:treeTable tag you’ll notice two facets:

nodeStamp and pathStamp

 

The nodeStamp facet is used to render the tree table and lets you drill down the data defined in the binding of the tree table.

To render the tree table a special EL, normally ‘#{node}’, is used to stamp out the data of each level. Which data is stamped is defined in the tree binding. We defined to show the DepartmentName name for the first level and EmployeeId, LastName and FirstName for the second level. This is why we get the output in the image above.

In summary: the nodeStamp renders the first column of the tree table.

The pathStamp is used for navigation inside the af:treeTable like when you select a node and make it the top node of the tree or tree table. For more info on this check the documentation.

Building columns:

An af:treeTable, like a table, can and should have columns. As you see in the image above, the af:treeTable looks like a normal tree when you don’t define columns yourself.

Columns are defined outside the ‘nodeStamp’ facet (and pathStamp facet) of an af:treeTable. The tag doc tells us:

Columns

Like the Table, the TreeTable’s children must be Column components (see Table Columns). Like the Tree, the TreeTable has a “nodeStamp” facet which renders the “Object Name” Column. The “Object Name” Column contains the primary identifier of an element in the hierarchy. For example, in an organization chart of employees, the “Object Name” Column might be the employee name.

 

Sample: to show columns for Lastname and FirstName of an Employee we add af:column tags like

<af:treeTable value="#{bindings.DepartmentsView1.treeModel}" var="node"
              selectionListener="#{bindings.DepartmentsView1.treeModel.makeCurrent}"
              rowSelection="single" id="tt1">
    <f:facet name="nodeStamp">
        <af:column id="c1" width=”200”>
            <af:outputText value="#{node}" id="ot2"/>
        </af:column>
    </f:facet>
    <f:facet name="pathStamp">
        <af:outputText value="#{node}" id="ot3"/>
    </f:facet>
    <af:column id="c2" width="200">
        <af:outputText value="#{node.LastName}" id="ot4"/>
    </af:column>
    <af:column id="c3">
        <af:outputText value="#{node.FirstName}" id="ot3"/>
    </af:column>
</af:treeTable>

outside the nodeStamp facet. This will get us this output

Now we have a problem. The second level nodeStamp prints out all attributes of hte node. This is exactly what the EL ‘#{node}’ does. The first level doesn’t have this problem as we only defined one attribute ‘DepartmentName’ for this node.

We don’t like to see the sting in the 2nd level. There exist two solutions to solve this problem.

  1. We use the EL ‘#{node.DepartmentName}’ instead of ‘#{node}’. As the attribute DepartmentName doesn’t exist in level 2, the EL evaluates to nothing (or empty string). However, keep in mind that this only works if the attribute only exists in level one.

  1. We define an EL for the node depending on their level. This solution will work in all cases. To implement this we use an af:switcher component which we use to find out which level we are currently stamping out. This allows us to use attributes defined for the level and build some output for the nodeStamp. Details for this solution follows below.

How to find out which node level currently is stamped out?

One easy way is to look at the view objected used for the level. If you are using some other source you can add an attribute (static) for each level which can then be used in the EL for the af:switcher.

To find out the name of The view object used we can look at the source of the tree binding in the pagedef

  <bindings>
    <tree IterBinding="DepartmentsView1Iterator" id="DepartmentsView1">
      <nodeDefinition DefName="de.hahn.blog.treetable.model.views.DepartmentsView" Name="DepartmentsView10">
        <AttrNames>
          <Item Value="DepartmentName"/>
        </AttrNames>
        <Accessors>
          <Item Value="EmployeesView"/>
        </Accessors>
      </nodeDefinition>
      <nodeDefinition DefName="de.hahn.blog.treetable.model.views.EmployeesView" Name="DepartmentsView11">
        <AttrNames>
          <Item Value="EmployeeId"/>
          <Item Value="LastName"/>
          <Item Value="FirstName"/>
        </AttrNames>
      </nodeDefinition>
    </tree>
  </bindings>

The name we are looking for is the DefName of the nodeDefinition. But how do we access this information in an EL?

Frank Nimphius blogged about this here https://blogs.oracle.com/jdevotnharvest/how-to-determine-the-adf-tree-node-type-using-el. We use the EL

#{node.hierTypeBinding.viewDefName}

which returns the nodes DefName from the binding.

With this info, we can build the af:treeTable

<af:treeTable value="#{bindings.DepartmentsView1.treeModel}" var="node"
              selectionListener="#{bindings.DepartmentsView1.treeModel.makeCurrent}"
              rowSelection="single" id="tt1">
    <f:facet name="nodeStamp">
        <af:column id="c1" width="200">
            <af:switcher facetName="#{node.hierTypeBinding.viewDefName}"
                         defaultFacet="default" id="sw1">
                <f:facet name="de.hahn.blog.treetable.model.views.DepartmentsView">
                    <af:outputText value="#{node}" id="ot2"/>
                </f:facet>
                <f:facet name="de.hahn.blog.treetable.model.views.EmployeesView">
                    <af:outputText value="ID: #{node.EmployeeId}" id="ot11"/>
                </f:facet>
                <f:facet name="default">
                    <!-- use this facet if the other facets don't match! -->
                    <af:outputText value="#{node}+++++#{node.hierTypeBinding.viewDefName}"
                                   id="otd11"/>
                </f:facet>
            </af:switcher>
        </af:column>
    </f:facet>
    <af:column id="c2" width="200">
        <af:outputText value="#{node.LastName}" id="ot4"/>
    </af:column>
    <af:column id="c3">
        <af:outputText value="#{node.FirstName}" id="ot3"/>
    </af:column>
</af:treeTable>

to get this output

Using the same technique in the columns allows showing even more information.

How about showing the manager of each department next to the department in the column where the employees are shown?

Easy, after changing the DeparmentView to return the manager info together with the department

and adding attributes for MgrEmployeeId, MgrLastName and MgrFirstName we can implement this using the following code

<af:treeTable value="#{bindings.DepartmentsView1.treeModel}" var="node"
              selectionListener="#{bindings.DepartmentsView1.treeModel.makeCurrent}"
              rowSelection="single" id="tt1">
    <f:facet name="nodeStamp">
        <af:column id="c1" width="200">
            <af:switcher facetName="#{node.hierTypeBinding.viewDefName}"
                         defaultFacet="default" id="sw1">
                <f:facet name="de.hahn.blog.treetable.model.views.DepartmentsView">
                    <af:outputText value="#{node.DepartmentName}" id="ot2"/>
                </f:facet>
                <f:facet name="de.hahn.blog.treetable.model.views.EmployeesView">
                    <af:outputText value="ID: #{node.EmployeeId}" id="ot11"/>
                </f:facet>
                <f:facet name="default">
                    <!-- use this facet if the other facets don't match! -->
                    <af:outputText value="#{node}+++++#{node.hierTypeBinding.viewDefName}"
                                   id="otd11"/>
                </f:facet>
            </af:switcher>
        </af:column>
    </f:facet>
    <af:column id="c2" width="200">
        <af:switcher facetName="#{node.hierTypeBinding.viewDefName}" defaultFacet="default"
                     id="sw2">
            <f:facet name="de.hahn.blog.treetable.model.views.DepartmentsView">
                <af:outputText value="#{not empty node.MgrLastName ? 'Manager: ' : ''}"
                               id="ot5" inlineStyle="font-weight:bold;"/>
                <af:outputText value="#{not empty node.MgrLastName ? node.MgrLastName : ''}"
                               id="ot6"/>
                <af:outputText value="#{not empty node.MgrLastName ? ', ' : ''}" id="ot4"/>
                <af:outputText value="#{not empty node.MgrLastName ? node.MgrFirstName : ''}"
                               id="ot7"/>
            </f:facet>
            <f:facet name="de.hahn.blog.treetable.model.views.EmployeesView">
                <af:outputText value="#{node.LastName}" id="ot211"/>
            </f:facet>
            <f:facet name="default">
                <!-- use this facet if the other facets don't match! -->
                <af:outputText value="#{node}+++++#{node.hierTypeBinding.viewDefName}"
                               id="otd211"/>
            </f:facet>
        </af:switcher>
    </af:column>
    <af:column id="c3">
        <af:outputText value="#{node.FirstName}" id="ot3"/>
    </af:column>
</af:treeTable>

Will produce this tree table:

You can add more, like icons in each column or …

You can download the sample application from GitHub: BlogTreeTable. The sample was built using JDev 12.2.1.3 but the same technique should work in other JDev versions too (11g or newer).

Adding missing extensions to JDeveloper 12.2.1.3

The current version of JDeveloper 12.2.1.3 is missing some extensions which are popular in the older version of JDeveloper. One of them, which is asked for a couple of times, is the MAF extension. Other extensions like ‘BI ADF ViewRegions’ are missing too.

Here are the images from the update page of JDeveloper 12.2.1.3

As you see, there is no ‘Mobile Extension’.

In general, you have two options to get the missing extensions installed:

  1. Download the extension from the ‘Extension Exchange’ and install it from a local file
  2. Add the ‘Extension Exchange’ to the known sources of extensions and load the extension right from JDeveloper

Personally, I prefer the second way as it only shows the extensions available for your version of JDeveloper. You can only install extensions which are configured for your version anyway.

Extension Exchange on the WWW

You’ll find all extensions available for all version of JDeveloper on the public ‘Extension Exchange’ at

http://www.oracle.com/technetwork/developer-tools/jdev/index-099997.html

From there you can download an extension and install it in JDeveloper from the local file. When you download an extension make sure to load the right version as you can only install extensions which are configured for your version (check the min and max version of the extension!).

Once you have an extension downloaded you can install it from this local file. As a sample show images how to install a MAF extension from a local file. As a sample, we’ll use JDeveloper 12.2.1.3.

Download the extension to your local file system and remember the folder you saved the file to. In JDeveloper go to menu ‘Help’->’Check for Updates’. Select ‘Install From Local File’ and search the file downloaded

Click finish and the extension gets installed.

If you try to install an extension which is not compatible to your JDeveloper version you get

So make sure you download the right version of an extension you like to install.

URL to add the ‘Extension Exchange’

To avoid the hassle of selecting the right version, let JDeveloper do this work for you. We simply add the URL of the ‘Extension Exchange’ to the ‘Update Centers’ and JDeveloper will search for extensions compatible to your JDeveloper version.

The URL we have to add is:

http://www.oracle.com/webfolder/technetwork/jdeveloper/downloads/1213center.xml

Open ‘Help’->’Check for Updates’ again and click the ‘Add’ button

Enter a name for the URL and the URL itself and click OK. Now, after clicking ‘Next’ you’ll get

and can select the ‘MAF Extension’ or any other missing extension right from the dialog. The installation is identical to the one shown in the ‘Extension Exchange on the WWW’ section.

JDev 12.2.1.3: Creating a shared skin jar (Part 2)

In part 1 or the series we created a simple skin, built an ADF-Library from it and tried to reuse it by deploying it to a WebLogic Server. This approach failed. In this part, we try another option to share a jar with

Sharing the skin with other applications

To share the skin with other application we can

  1. Create an ADF Library
    1. Add this library to the other application
    2. Add this library as a shared library to a WebLogic Server
  2. Create a normal jar
    1. Add this library to the other application
    2. Add this library as a shared library to a WebLogic Server

For this blog the way we want to use if 2b. This allows to create the skin once, deploy it to a server and use it in every other application. In the next paragraph, we try out option 1a to show the problems when reading resources from a jar file.

Using a shared skin

Option 2b

Here we create a jar file containing the skin and additional resources like images and deploy it directly to a WebLogic Server as a shared library. The advantage is, that other applications can use the skin and other resources directly and that the jar can be versioned to allow different versions of the same jar on the server.

Option 1a which we discussed in the previous chapter doesn’t work for images. However, the documentation ‘Deploying a Custom Skin File in a JAR File’ and Frank Nimphius pointed it out in e.g. 86. Reading boilerplate images and icons from a JAR or How-to share skin definition files across applications how the jar file must be structured to allow the resource servlet to read the resources. The essential sentence is

‘All image resources and CSS files must also be under the META-INF directory.’

In his article, Frank suggested using the command line jar tool to create the jar. I show how to use JDev to create the jar with the needed structure and how to deploy it to a server as a shared library.

A sample application is used to use the skin and to show an image load from the jar.

The building plan for a skin in a shared Library which can be deployed to a WebLogic server is given in the article as:

To implement the shared library approach, developers need to change their existing skin definition so it can be deployed in a JAR file. The steps for this include

– Creating a META-INF directory – Creating a trinidad-skins.xml file that defines the skins deployed with the JAR file

– Creating an META-INF/adf sub directory for images and icons served from the JAR file

– Changing the image reference in the CSS to include the “adf” directory, which makes sure images and icons are handled by the ADF Faces resource loader, which can read resources from JAR files

– JAR the META-INF directory to create the library file

Looking at the current project for the skin we see a different layout

In the article Frank instructed to create the needed folders yourself and copying or moving the files to the new structure, then to use the command line to build a jar from the structure.

I’ll show how this can be done with a special deployment descriptor from within the project. The image below shows the needed layout of the final jar file.

To transform the folder structure present in JDev to the needed structure of the final jar, we create a new deployment descriptor in JDev

In image 4 we see the first part of the solution: here we set the path inside the jar to ‘MEAT-INF’. This will guarantee the structure we need. Then we add another contributor to the list (public_html) to get everything we need into this folder. Then we use the ‘Filters’ node to select all content we need skin part

Next part is to create another path in the jar for the metadata of the skin

We add another file group for the resources

Now we can deploy the jar using the new deployment descriptor

And the jar file is created in the deploy folder. It holds all files in the right folders

Finally, we can deploy this jar to the WebLogicServer. In this case, I use the integrated WLS, but it can be any stand-alone WLS too.

The error message you see on the 7th image can be ignored. It only tells you that the library can’t be deployed as an application but only as a shared library. This is exactly what we want to do 🙂

Now the jar file is deployed on the WLS as a shared library and can be used for every application on this server.

We use the existing application from part one to consume the jar skin from the shared library and show the images deployed with the jar.

Before we go any further, we have to remove the ADF Library we added to show the problem from the project. For this open the project properties and select the ‘Library/Classpath’ node and remove the ‘ADFLibrary’ entry

The page should now look like no skin is used at all.

As we already added a skin (with the ADF Library) we don’t have to do this again. However, we have to add a library reference to configure the application to use the shared library deployed on the server. For this, we open the application descriptors and edit the ‘weblogic-application.xml’ file by double clicking the entry in the application resources section

In the ‘Shared Library Reference’ section, we add a reference to the now deployed shared jar ‘blogsharedskin’

Saving everything we don’t see any change to the page design, as the library isn’t part of the application yet. Starting the application we get

Just what we liked to see. The images are visible, checking the page with Chrome’s Dev Tools shows that the images are correctly loaded

This proves that the shared library with the skin and the images are working correctly.

To make the skin visible in JDev during development, we can add the jar we developed to the server a library. We create a library

and make sure the ‘Deploy by default’ is NOT set. Adding the library to the project

will make the skin visible in design mode

The unset checkmark prevents the jar from being packed into the WAR or EAR file. It’s just used in the IDE. That you can’t see the images is normal as there is no full server to serve the images to the design view.

Summary

In this mini-series, I showed the problem when creating a skin as ADF Library and trying to share it on a Weblogic Server. Then I showed how to create a deployment descriptor for the skin and other resources and how to deploy the resulting jar to a WebLogic Server.

The sample application can be downloaded from BlogSharedSkin. The sample was created by using JDev 12.2.1.3 but the same technique can be used in any 12.2.1.x JDev version. There is no database connection needed.

JDev 12.2.1.3: Creating a shared skin jar (Part 1)

In earlier versions of JDev, skins have been created either by pure code or by using the free Skin Editor. However, since JDev 12.2.1.x the skin editor has been integrated into JDeveloper itself.

A couple of questions in the ODC JDeveloper space are about how to create a skin with JDev which can be deployed as a shared library to a WebLogic Server. I gave this a try and it turned out, that you can build an ADF library jar from a skin project but you can’t use images to this jar which you might want to use in the application.

In this blog, I’ll show how to create a skin with resources like images and how to build a jar file from the skin together with the images and deploy it aa s shared jar to a WeblogicServer.

Building a skin project

The first part is to build a small skin project. The project we use to create a minimal skin, just to show that the skin is changing something. Then we add some images to the skin which we want to use in the application which uses the skin. Such images can e.g. used on an af:button component.

We start by creating a new application as an ‘ADF Fusion Web Application’

As we don’t need the created model project we delete it completely

If you get another dialog, telling you that you can’t undo the action, answer ‘Yes’ to delete the project. Now you should see a workspace with just the one project:

Know that we have a project we add a skin and e.g. add some skin selectors to change to the color of the button text. For this, we right click the ‘Web Content’ folder in the project and select ‘New from Garaly’ and then select ‘ADF Skin’ from the ‘JSF/Facelets’ node and fill in the basic information:

This will create the needed css file and the descriptors which define our skin (trinidad-config.xml and trinidad-skins.xml).

We open the sharedskin.css file if it’s not open already and switch to source mode. Here we add two simple skin selectors

which are changing the color of the text of a button and a link. You can add more sophisticated selectors but for this blog, it’s enough to show the working skin. To make it more interesting, and because that’s the real reason for this blog, we add some images to the skin which we like to use in the application using the skin. We add the images into a new folder like shown below

The reason for this structure is, that to read the images from the jar in the consuming application, we need a special resource loader. In case of ADF it’s the resource servlet which listens to the URL pattern ‘/adf/’’. This servlet is installed automatically for ADF Web Applications and is configured in the web.xml file

The final task for the skin project is to create a jar file which we can use in other applications. The easiest way to get such a jar is to create an ADF Library deployment descriptor. Open the project properties of the skin project and select the ‘Deployment’ node

And click the ‘New Profile’ icon, select to create an ADF Library Jar

and click ‘OK’. The remaining dialogs you can just click ‘OK’ or ‘Finish’.

To create the library we have to execute the descriptor by right-clicking on the project and selecting ‘Deploy’ and choosing the ‘sharedskinadflib’

This will create the jar in the ‘deploy’ folder of the project.

Sharing the skin with other applications

To share the skin with other application we can

  1. Create an ADF Library
    1. Add this library to the other application
    2. Add this library as a shared library to a WebLogic Server
  2. Create a normal jar
    1. Add this library to the other application
    2. Add this library as a shared library to a WebLogic Server

For this blog, we want to use option 2b. This allows to create the skin once, deploy it to a server and use it in every other application. In the next paragraph, we try out option 1a to show the problems when reading resources from a jar file.

Using a shared skin

Option 1a

We start with option 1a, just to show the problem when we try to read a resource from a jar. We build another ADF Fusion Web application and add the skin as ADF library from a ‘File System Connection’ which we create and let it point to the ‘deploy’ folder

Right-click on the ‘sharedskinadflib’ and add it to the new sample project. This will make the skin available to the application. To use the skin we have to add a skin to the application like we did to create the skin project. The difference is that we now choose the shared skin as the base skin

Creating a new page and adding a button and/or a link to the page we see the new style introduced by the ‘sharedskin’

So, the shared skin is working. Well, yes, but what about the images we added to the ‘sharedskin’?

Let’s try to add one to the button. In the property editor, we select the icon property of the button and click ‘Edit’ to get

However, we don’t see any image in the whole project. As we know where we put the images (or we can look into the sharedskinadflib) we can just add the path to the image like ‘skins/sharedskin/adf/images/home.png’ and we see the image

Running the application we get the page with the button but don’t see the image

Using DeveloperTools we see that the resource couldn’t be found. Inspecting the button element we see

The path to the image is not found 😦

If we change the address of the image to ‘/adf/images/home.png’ to use the resource servlet we still get an error

The reason is that the resource servlet expects the resources in a different path inside the jar. Every resource which should be read from a jar should be in a folder named ‘META-INF’.

The ADF library did not put the images into the META-INF folder

The problem is that we can’t change the layout of the ADF Library. When you create an ADF Library there is no option to make any changes to the content of the jar.

The conclusion is that using a skin in an ADF Library is problematic if there are other resources which you need to share.

To be continued…

In the final part 2 of the series, we see how the skin can be shared with other applications.

JDev 12c: Badge Button reloaded

In my article JDev: Badge Button I showed how to build a special button with a notification ‘badge’:

The declarative component of this sample was build using JDev 11g (11.1.1.9.0 to be exact).

I received a couple of question on how to work with this declarative component in JDev 12c projects. In general, you can use the same source and build the declarative component in JDev 12c. However, as JDev 12c is using a different document type, Facelets instead of JSP XML, you can use the badge button only on JSPX type pages.

So, in this blog, I show how to create a declarative component which is usable in Facelets type pages. I don’t change the behavior of the badge button but reuse the code. This blog is more about how to create a declarative component in 12c and show the differences to 11g.

JSPX vs. Facelets

With the introduction of JSF 2.0 (JavaServer Faces 2.0 Overview and Adoption Roadmap in Oracle ADF Faces and Oracle JDeveloper 11g) a new document type Facelets was introduced. The difference and the motivation behind this is outlined in the document.

We are only interested in the fact that you can’t mix components designed for JSPX XML pages or fragments with Facelets type pages or fragments. This means that you can’t add the badge button created for 11g to a jsf page of jsff fragment of type ‘Facelet’.

Building a Declarative Component for 12c

We start from the old application workspace I created for the 11g implementation. Opening this workspace will migrate it to the 12c. At the end of the blog, you’ll find a link to download the final workspace for 12c.

After the migration we add a new project ‘BBB12cDeclarativeComponent’ of type ‘ADF ViewController Project’ to the workspace:

After creating a new project for the 12c badge button, we create a new ‘Declarative Component’ in the ‘Web Content’ folder

In the wizard, we now select ‘Facelets’ as the document type. Selecting ‘Facelets’ will create the 12c kind of declarative component.

Once we finished the wizard, we get the skeleton declarative component in the ‘BadgeButton12c.jsf’ file. If you got a file name ‘BadgeButton.jspx’ you did not set the document type to ‘Facelets’.

Now we can copy the code from the original sample written for 11g and copy it after the componentDef tag. Once you copied the code from the original sample you have to change the EL used to address the action and the actionListener to match the componentVar property in the componentDef tag. To make this distinguishable from the 11g sample, I changed the componentVar to ‘compButton’. The other change is to use an af:button tag instead of the af:commandButton tag. While the af:commandButton tag can still be used, 12c application should use the af:button tag.

 

The final code looks like

Adding the declarative component to the faces palette

You already know, that to use the declarative component in a project, you first have to add it to the component palette. The difference to the 11g sample is that we have to choose a different node in the project definition to add the library.

First, we need to deploy the declarative component project to an ADF Library. For this, all we need to do is to execute the deployment profile created with the project

Next, we add a ‘File System’ resource which points to the folder the jar is created in

And the jar should show up

To make it usable in the view controller project, we have to add the jar to the project

Now, when we look into the view controller projects properties, we find the new declarative component in the ‘Facelets Tags Libraries’ node. In JDev 11g the tab libraries can be found in the node ‘JSP Tag Libraries’. Again, the difference is where the tags or declarative component are usable. You use JSP tags in JSP XML files and you use Facelets tags in JSF files.

Next step is to create a new JSF Page in the adfc-config.xml, the unbounded task flow.

Again, we make sure to select ‘Facelets’ as document type as we otherwise will not be able to use the declarative component created for ‘Facelets’.

The layout of the page is similar to the one for 11g. 12c uses a panelGridLayout instead of the panelStretchLayout, but that’s all.

As we are now using a JSF page and added the 12c component library and find the BadgeButton in the component palette

and use this on the page. The final layout looks like

Or when running the JSF page

Clicking the button we get the log messages

Sample Application

You can download the sample application from GitHub BlogBadgeButton12.2.1.2

Problems running JDeveloper 12c

In the last couple of weeks, I get more and more reports of problems running JDeveloper 12.2.1.x. (to be exact 12.2.1.1.0, 12.2.1.2.0 and 12.2.1.3.0)

The problems reported are

  • properties editor not working
  • JDeveloper hangs during start
  • showing wireframe instead of page design
  • problems to configure the JDBC connection
  • problems compiling expression on attributes (not 100% verified that this is JDK problem)
  • problems migrating projects created with earlier versions of JDeveloper
  • problems with the groovy script engine
  • deadlocks within JDeveloper when editing multiple java files

to name some. The problems are not ADF related but IDE related. It turned out that they only could be reproduced if the used JDK to run JDeveloper on was newer than JDK 1.8.0_101. All problems are not reproducible when running JDeveloper with JDK 1.8.0_101.

Currently, there is a bug pending (Bug 26766333) with support.oracle.com for some but not all mentioned issues. At the moment of writing this, there is no patch available.

My recommendation is to install JDK 1.8.0_101 and run JDeveloper using this JDK. You can do this by

  1. installing JDK 1.8.0_101 on your machine. The download for this old version is hard to find in the WWW. To make it easier, you can find it on this page: Java SE 8 Archive Downloads
  2. change the product.conf file you’ll find in your .jdeveloper folder inside your home folder. Open the file and set the SetJavaHome property
  3. to be on the safe side, you can recreate the integrated WLS to make it use JDK 1.8.0_101 too. If you know our way in the jungle of script files which are used to start the embedded WLS, you can change those files directly. As there typically are not many changes made on the integrated WLS, I find it easier to delete the integrated WLS and create it again. It’ll pick up the JDK JDeveloper is running on automatically and use it to run the WLS too.

You don’t need to update or change the JDK your standalone server is running on. To my knowledge, the problems are only IDE related, so they don’t affect the running application.

If you find a problem, which is related to using a JDK newer than 1.8.0_101, feel free to leave a comment on this post. I’ll add them to the list for reference.

JDeveloper: Info about the clicked cell in an af:table

JDeveloper allows to easily create tables with the af:table component. The table allows easy access to the selected row or rows. However, if you are interested in which cell of a table has been clicked, ADF needs some tweaking. This blog is about how to tweak an af:table to get exactly this info.

Use Case

You like to know which cell in an af:table a user has clicked, e.g. to get some detailed information about the clicked item or cell in the selected row. The sample I show get the information about the current row, and column of the cell and the value of the cell clicked. The final sample will show the info like

How to do it?

The normal af:table component doesn’t give information about the cell a user has clicked on. The ADF pivot table offers this but is complex to use.

We use JavaScript in form of a clientListener to intercept the click on a cell and a serverListener to call a bean method to get more data on the cell. This article 011. ADF Faces RC – How-to use the Client and Server Listener Component shows how to use clientListener and serverListener in detail.

As we are interested in the selected cell, we add a clientListerer to each af:outputText which shows the column value in the af:table which fires on the click event. The clientListener calls a JavaScript method. In the JavaScript method, we build a payload of the UIComponent which is used to show the column value and the column name of the cell. To get this information we have several possible ways:

  1. We can use our knowledge of the DOM tree and get the column via the parent of the component which fired the event. The parent component should be the af:column.
  2. We add a client attribute to the component which shows the cell value adding the column name from the af:column as EL

In this sample, we choose the second solution. With this information, we call the serverListener from the JavaScript method. The serverListener method is implemented in a request scope bean and uses the information passed to get the details about the clicked cell we show in the UI.

Implementation

The sample uses the HR DB schema and only needs one table, Employees in this case. We create a simple page with the table in read-only mode, sortable and filterable. As you see in the image above the table is just build be dragging the Employees VO onto the page and drop it as a read-only table.

Now we add a clientListener and a serverListener to each outputText component which is used to show the cell value

In the image above we see the listener for two columns. In addition, we add an af:clientAttribute with the name ‘columnName’ which we pass the EL of the af:column headerText property.

Next, we add an af:resource component to the af:document where we specify the JavaScript for the clientListener method ‘clientCellSelectionCall’. We use a JavaScript file to code the method. We could have added the method to the page directly, but if we want to reuse the pattern, it’s better to use a JavaScript file

The file is located in the public_html folder (Web Content) in a subdirectory ‘javascript’

The method code is

The click event on the af:outputText component triggers a call to the javascript method ‘clientCellSelectionCall’ (via the clientListener) with the source of the event, the af:outputText component. The method reads the clientAttribute added (line 3) and calls the serverListener of type ‘cellSelection’. This event is defined by the af:serverListener on the af:outputText. The component which triggered the event and the column name added as client attribute are passed to the serverListener.

The serverListener is a bean method defined in a request scope bean on the af:outputText component as

method="#{TableCellSelectionBean.handleTableCellSelection}"

In the bean, the method looks like

public void handleTableCellSelection(ClientEvent event) {
  // get payload which is the ui component which fired the event
  UIComponent ui = (UIComponent)event.getParameters().get("payload");
  // get the column from the event which is sent too
  String column = (String)event.getParameters().get("column");
  RichOutputText rt = (RichOutputText)ui;
  // get current row key
  DCBindingContainer bindingContainer = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
  DCIteratorBinding binding = bindingContainer.findIteratorBinding("EmployeesViewIterator");
  Row currentRow = binding.getCurrentRow();
  Key key = currentRow.getKey();
  // compile info about clicked cell
  String out = "Payload:" + ui + "
  column: "+ column + "
  val: " + rt.getValue() + "
  key: "+key.toString();
  logger.info(out);
  setCellInfo(out);
}

Here we get the component which triggered the event (as payload) and the name of the column. Using this information we can get e.g. to the value of the column (via the UI component). The row of the cell we get via the current row of the iterator. With this information, we get the key of the row. We can get much more information here, like historical data about the current employee’s salary, if the salary cell was clicked.

We just create a string from the information which we show in the UI to the user

Here are some images of different cells clicked in the UI:

Download

You can download the sample, which was built using JDeveloper 11.1.1.9, from GitHub BlogTableCellSelection. The sample uses the HR DB schema.

JDeveloper: Skin Radio Buttons

In this blog article, I like to share how to use a skin to alter the look of radio buttons in ADF. The use case was a question on the ODC space JDeveloper & ADF which asked about how to provide more space for the radio buttons.

Here is an image of the default and the resulting radio buttons:

As you see, in the first radio group the space between the selectItems is narrower than in the second group.

In my older post about JDeveloper: Advanced Skin Technique I showed how to find out which style to change, so I spare this here.

The image above shows the standard “radiogroup” in Chrome Developer Tools. As you can see the radiogroup consists of “div” elements, each specifying one of the selectItem.

To change the spacing, we add a style class to the skin file like

.mysor af|selectOneRadio::content div {
  padding: 0px 0px 10px 0px;
}

The “.mysor” is the name of the style class which we later use on the page. The magic is done by specifying the base style as af|selectOneRadio::content and from there style each “div” element having the base style as a parent. This way we style the blue marked div in the image above.

One question remains. Why do we use a skin and don’t add the code right into the page?

Well, using a skin is the preferred method. The skin is created once and can be used everywhere in the application. If you need to make changes, you don’t have to search for the pages where the style has been added, but you just change the skin file and you are done.

Download Sample

You can download the sample which is build using JDev 12.2.1.2.0 and uses the HR DB schema from GitHub BlogAdvancedSkin

 

 

JDev: Badge Button

In this article, I describe how to build what I call a ‘Badge Button’. This is a button we know from many mobile applications which shows, e.g., how many new messages have arrived since the last visit.

The image above shows what I have in mind. We see a standard button with a badge indicating the number of new items. The badge can be used to display text as well

The idea behind this came from a question on the ODC JDev & ADF space. When I first read the question I wanted to answer “No, there isn’t such a component in ADF”, but after thinking about it, I decided to build one myself.

The Problem has two parts:

  1. How to build the badge
  2. How to create the component looking like a button with a badge

Solution Part 1

Making the badge turned out to be very easy. Searching the web, you find plenty of solutions for such components using CSS. As you might know, it’s not very straightforward to add a CSS solution to ADF. However, there are ways to do this. In the end, I used the following CSS to generate the badge:

.badge {
 background: radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background: -moz-radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background: -ms-radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background: -o-radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background: -webkit-radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background-color: red;
 border: 2px solid white;
 border-radius: 12px; /* one half of ( (border * 2) + height + padding ) */
 box-shadow: 1px 1px 1px black;
 color: white;
 font: bold 15px/13px Helvetica, Verdana, Tahoma;
 height: 16px;
 padding: 4px 3px 0 3px;
 text-align: center;
 min-width: 14px;
 margin: 0px 0px 20px -10px;
 position: relative;
}

Solution Part 2

ADF uses CSS which is built from skin files. It’s not straightforward to add any other CSS to a component as you don’t see the generated HTML where you need to add the CSS. So adding the CSS class just as style to the button doesn’t work, as you can’t add new properties to ADF components. You will get an error like

To create a badge, you need to create a span or div with the CSS class and some data which is put into the badge like
Selection_474

This can’t be added to an existing component easily. However, ADF has a component which renders as a div tag, the af:outputText. If you add an af:outputText to a page and look at the resulting HTML you get
Selection_475
So, the value of the outputText is just surrounded by a div tag. The problem still is that you can’t add your own property to the ADF component, but we can add the div with the needed style and the data as the value you the af:outputText component. All we have to do, other than to add the div is to set the escape property of the outputText to false. This setting avoids that ADF encodes the value which would transform the ‘<’ into ‘<’, essentially making a string out of the value. The reason for that is to prevent security issues (injection), so be aware of this!

Putting this on a page would look like

And generates

The solution works somehow, if we put an af:button on the page instead of the af:spacer. However, it looks ugly or ‘uncool’ to see the ‘div’ in the af:outputText.

Final Solution

The final solution is to hide the ‘how to build it’ in a declarative component. The use case is a perfect fit for an ADF declarative component. We move the CSS, the button and the outputText in such a component and can use the component in the page to get

The new solution looks clean, as the CSS and odd looking outputText isn’t visible. Here are some images of the running test application.

The input field is used to set the data to be shown on the badge. It can be numbers, text or both. Clicking on the button calls the action listener and the action.

And this is the log output.

Building the Declarative Component

There are many other blogs about how to create a declarative component so I will not do this in detail. However, I like to point out some things you should keep in mind when you create such a declarative component.

To make the component work, it’s not enough to just add a button and the outputText holding the CSS. We have to make properties available for the action and the actionListener of the button. If we don’t do this, all we get is a button, which is looking good but which can’t be used to start a navigation or to call an actionListener. The same is true for other properties of the button inside the declarative component. We have to add a property for the button text at least. If you like to enable/disable the badge button, you have to expose an attribute in the declarative component interface to get the value from the outside, your page See later).

When we build the declarative component, we start by adding another ‘ADF View Controller Project’ to the workspace. Declarative components should be developed in a separate project. They are deployed as adfLibrary jar files. We add a new JSF Declarative Component to the project.

And fill out a dialog with necessary data. This data can be changed later if needed. Here is a sample

Once we click OK, a jspx page with the selected name will be created alongside a meta-data file holding the information about the tag library.

In the JSPX page, we create the layout of the component. We already know how to add the badge, all we need to do is to put an af:button onto the page and add the code to the badge to it. The resulting declarative component looks like

Select the af:componentDef tag and open the property editor. There you can define metadata like attributes and methods you want to pass to the component from the outside.

And the methods to activate the button.

The data you specified in the property editor is added to the af:componentDef tag.

A special case is the partialTrigger property. You can’t set a partialTrigger from the outside to a component used in the declarative component. However, you can surround the declarative component with another component which has a partialTrigger property and use this outer component to send a ppr. In the code above I surrounded the declarative component with an af:panelGroupLayout which listens for ppr send from the af:inputText with the id “it1”. This partial refresh is needed in the sample to refresh the button with a new value entered in the field.

If you need more attribute to control the behavior of the component, you can add them via the property editor. For this simple test case, the attributes and methods are enough.

The sample application and declarative component is build using JDev 11.1.1.9.0 and can be downloaded from GitHub BlogBadgeButton. The sample doesn’t need a DB.