Sunday, January 31, 2010

Setting the current row of a view object with custom key programmatically

I came across a use-case where I needed to set the key of a View Object manually through the backing bean. Usually setCurrentRowWithKey() or setCurrentRowWithKeyValue() can be used to set the current row of a view object. But What if you don't know the exact key but part of it and you want to create the key yourself and set the current Row programmtically.  Well you can use the following function on click of a command button or customize it happily to put to any specific use...

    public String setNewRowKey() {
        // Get the iterator displayed on the Page
         FacesContext ctx = FacesContext.getCurrentInstance();
         Application app = ctx.getApplication();
         ValueBinding bind = app.createValueBinding("#{bindings}");
         DCIteratorBinding iter = ((DCBindingContainer) bind.getValue(ctx)).findIteratorBinding("DepartmentsEmployeeVOIterator");
         if (iter == null) {
           throw new RuntimeException("Iterator not found");
         }
         
         // Create the key manually. It requires providing all primary keys for all 
         // the Entity Objects included in the View Object
         Object [] keyValues = new Object[2];
         keyValues[0] = null;  // Any Department
         keyValues[1] = "114"; // Employee ID
         
         // find all the rows matching the above criteria using the RowSetIterator. 
         // You can also use the same to find rows matching any key criteria.
         Row [] rows = iter.getRowSetIterator().findByKey(new Key(keyValues), -1);
        
         if (rows.length > 0)  {
             // get the first row and its key and set current row of iterator with this key string
             iter.setCurrentRowWithKey(rows[0].getKey().toStringFormat(true));
         }
         
        return "navigation-rule";
    }




Tuesday, January 19, 2010

"AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0

While trying to run Application Module in Jdeveloper 10.1.3.3, I got the following error.
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
at oracle.sql.NUMBER._fromLnxFmt(NUMBER.java:3199)
at oracle.sql.NUMBER.toString(NUMBER.java:761)
at oracle.sql.NUMBER.stringValue(NUMBER.java:2090)
at oracle.jbo.domain.Number.toString(Number.java:390)
at javax.swing.table.DefaultTableCellRenderer.setValue(DefaultTableCellRenderer.java:298)
at javax.swing.table.DefaultTableCellRenderer.getTableCellRendererComponentDefaultTableCellRenderer.java:190)
at javax.swing.JTable.prepareRenderer(JTable.java:3924)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2070)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:1972)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1895)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:142)
at javax.swing.JComponent.paintComponent(JComponent.java:742)
at javax.swing.JComponent.paint(JComponent.java:1005)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4963)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4916)
at javax.swing.JComponent._paintImmediately(JComponent.java:4859)
at javax.swing.JComponent.paintImmediately(JComponent.java:4666)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:451)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:114)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
BC4J Tester exit code(0)

As a basic human nature, I searched on the internet to find out that it was a bug as reported here.
http://forums.oracle.com/forums/thread.jspa?messageID=1617924?

But the same was fixed in Jdeveloper 10.1.3.3. Then why did it bug me now. It was then I realized that I had synchronized my Entity Object with the database. I opened one of my entity object and was wondering to see the Type of one of the attributes as String although it was a Number, something similar to this.




So I just modified all the Attribute types according to the ones in the database and hurrah it was working fine.

Saturday, January 9, 2010

Clear values in Search form fields

I have designed a Search form to search for specific records based on search criteria. But once I have searched I want to clear the criteria fields to conduct a fresh search. There are 3 ways





1. Reset the bind parameters of the view objects by calling them in the bean that can be found at the below links.
http://forums.oracle.com/forums/thread.jspa?messageID=2563498#2563498 


http://forums.oracle.com/forums/thread.jspa?messageID=1579998#1579998 


http://radio.weblogs.com/0118231/2006/11/21.html


2. Use ResetButton to reset the form parameters. But it will reset the form fields’ values to the previous search criteria parameters.


3. The third way originates from the user experience. According to my experience users are least concerned about the VO bind parameters being refreshed or not, but what they actually want is to clear the form instantly and preferably with no server call that means on the client-side itself. The reason for the same is that all countries/clients/users do not have very fast internet as to virtually diminish the time taken to reset the form. Hence this method came up to clear the search form using Java Script. This way might not be suitable for all the situations and also does not replace the other two mentioned above but still it is very much efficient and helpful to provide the end-users pleasant experience.
All you have to do is follow the below 3 steps and it is done.
  • Change your search form to <af:form> instead of <h:form>. After this the form looks like this.
<af:form id="searchForm">
   <af:panelPage title="Clear Search Form Parameters Example">
   <af:panelForm>





   <af:inputText id="firstName" value="#{bindings.TheFirstName.inputValue}"    label="#{bindings.TheFirstName.label}" required="#{bindings.TheFirstName.mandatory}"  columns="#{bindings.TheFirstName.displayWidth}">
      <af:validator binding="#{bindings.TheFirstName.validator}"/>
   </af:inputText>
   <af:inputText id="salary" value="#{bindings.TheSalary.inputValue}"  label="#{bindings.TheSalary.label}" required="#{bindings.TheSalary.mandatory}" columns="#{bindings.TheSalary.displayWidth}">
   <af:validator binding="#{bindings.TheSalary.validator}"/>
  </af:inputText>
  • Create a Clear CommandButton as shown below and set the onClick property as clearAllFormFields() function.
<af:panelButtonBar>
   <af:commandButton actionListener="#{bindings.ExecuteWithParams.execute}" text="Search"  disabled="#{!bindings.ExecuteWithParams.enabled}"/>
   <af:commandButton text="Clear" onclick="return clearAllFormFields();"/>
</af:panelButtonBar>


  • Now add the scriptlet function in the jspx page as shown below.
<script type="text/javascript">
   function clearAllFormFields(){
      //check if the object is not null. The object will be null when it is not rendered on the page  or is disabled. 
      if(document.forms["searchForm"].elements["firstName"] != undefined)


     document.forms["searchForm"].elements["firstName"].value="";
     if(document.forms["searchForm"].elements["salary"] != undefined)
     document.forms["searchForm"].elements["salary"].value="";
     return false;
   }
</script>

And it is done. Now just test run the page.