Some thoughts on Java Platform
Header image

My use case is very simple. I have two pages, the first one has a couple of fields and the second one shows the result of these fields based on specific calculus.

The result page has a print button, which calls a new browser page that is ready to print.

In addition, I would like in this “new browser page” shows also the customer logo above the result, but only in printable page.

The code below shows how I can achieve this requirement:


<af:panelStretchLayout id="psl1" >

 <f:facet name="top">

 <af:panelGroupLayout id="pgl6" halign="center" layout="scroll"
 styleClass="AFStretchWidth">
 <af:image source="/images/logo.gif" shortDesc="logo" rendered="<strong>#{adfFacesContext.outputMode eq 'printable'}</strong>"
 id="i1" />
 </af:panelGroupLayout>

 </f:facet>

 <f:facet name="center">

<af:panelBox id="pcg7"
 text="Result">

<af:panelGroupLayout layout="horizontal"
 id="pgl5"
 halign="right"
 styleClass="AFStretchWidth">
 <af:commandLink id="cl1">
 <af:image shortDesc="Imprimir" source="/images/bt_imprimir.gif" inlineStyle="border:none" id="image2"/>
 <af:showPrintablePageBehavior />
 </af:commandLink>
 </af:panelGroupLayout>

</af:panelBox>
 </f:facet>
 </af:panelStretchLayout>

 

The secret was the rendered property: #{adfFacesContext.outputMode eq ‘printable’}. That is it!


One more easily requirement, where everybody needs! I have a simple use case. Imagine a authentication form, where I have to know If the user exists in my database first before tried to login him. I just want to throw a exception and I would like to my exception message have been showed to my user in friendly way. My demo shows how to do this!

First of all, I will show my session bean, with 4 methods and different exceptions throw:

 


@Stateless(name = "SessionEJB", mappedName = "SessionEJB")

public class SessionEJBBean implements SessionEJB, SessionEJBLocal {

@Resource    SessionContext sessionContext;
 public SessionEJBBean() {    }

@Override    public void authenticateJbo(String email) throws JboException{        throw new JboException("Authenticate failed jbo");    }

@Override    public void authenticateRuntime(String email) throws RuntimeException{        throw new JboException("Authenticate failed runtime");    }

@Override    public void authenticateChecked(String email) throws Exception{        throw new JboException("Authenticate failed checked");    }

@Override    public void authenticateCustomJbo(String email) {        throw new CustomJboException("Authenticate failed custom jbo exception");    }

}

 

I did the method binding with my JSF view, just to show the exceptions:



In every exception, there is no exception by adf controller framework. So, look what It’s happening:

Of course, It’s so ugly, It’s not what I want. Therefore, I will show the correct way to do this. You have to implement a custom DCErrorHandler, it’s easy, you have to just extend the DCErrorHandlerImpl class from ADF Controller Framework and handle the exception. The example class is below:


package com.oracle.demo.view.exception;
import oracle.adf.model.BindingContext;import oracle.adf.model.binding.DCBindingContainer;import oracle.adf.model.binding.DCErrorHandlerImpl;
import oracle.jbo.JboException;

public class CustomErrorHandlerImpl extends DCErrorHandlerImpl {

&nbsp;

public CustomErrorHandlerImpl(boolean b) {        super(b);    }

&nbsp;

public CustomErrorHandlerImpl() {        super(true);    }

&nbsp;

@Override    public void reportException(DCBindingContainer bc, Exception ex) {

BindingContext ctx = bc.getBindingContext();

ex = (Exception)getRootException(ex);

disableAppendCodes(ex);

super.reportException(bc, ex);    }

private void disableAppendCodes(Exception ex) {

if (ex instanceof JboException) {

JboException jboEx = (JboException)ex;

jboEx.setAppendCodes(false);

Object[] detailExceptions = jboEx.getDetails();

if ((detailExceptions != null) && (detailExceptions.length > 0)) {

for (int z = 0, numEx = detailExceptions.length; z < numEx;                     z++) {

disableAppendCodes((Exception)detailExceptions[z]);

}

}

}

}

public Throwable getRootException(Throwable ex) {

Throwable rtEx = null;

if ((rtEx = ex.getCause()) == null) {            return ex;        }

else {

return getRootException(rtEx);

}

}

@Override

public String getDisplayMessage(BindingContext ctx, Exception th) {        return super.getDisplayMessage(ctx, th);    }

}

&nbsp;

 

Right now, we have to register this error handler in databindings.cpx :

 

 

We are ready to show the messages to the final User:

That’s it!


This is my first post about Oracle ADF technology. First of all, I have to explain why after this post will be many others. A few months ago, I changed for work to Oracle Corp. For that reason, It’s normal that I’ll see products and technologies from this company.

Today’s post I will talk about how to adding a parameter to ValueChangeListener event from JSF. In fact, I didn’t find a nice way to do this. So, the reason for I’m writing this post is also share my knowledge and find other way to do the same thing.

My issue was: I have a beauty datatable built using af:table. This table has a column with a af:selectOneChoice, because the user can choose in a dropdown which value is better for him. Simple and clean. When the User change this value, I have to show a friendly message, based on the value from another column in the same row. Therefore, I would like to have in my backing bean this row selected or this specific other column value to my purpose.

The unique option that I found is using ValueChangeListener and navigate to the components in runtime. I will explain with the code.

That’s my af:column:


<af:column width="10%" align="center" sortable="false" headerText="Regular (%)" id="c9">
<af:inputText id="limiteMaximo" <strong>visible="false"</strong> value="#{row.limitesContribuicaoPP2.limiteMaximo}">
<f:convertNumber />
</af:inputText>
<af:selectOneChoice autoSubmit="true"
value="#{row.limitesContribuicaoPP2.percentualRegularToString}"
id="comboRegular"  valuePassThru="true"
valueChangeListener="#{Petros2MB.onChangePercentualRegular}">
<f:selectItems value="#{row.percentuaisRegular}" id="si4"/>
</af:selectOneChoice>
</af:column>

There are two components inside the column: af:inputText and af:selectOneChoice. The trick is, the component inputText is not visible (the old h:inputHidden), I prefer put in this way, just to simplify my managed bean. In the valueChangeListener method I can get this value in inputText and make my decision. Let’s go to the MB code:


public void onChangePercentualRegular(ValueChangeEvent evt){
if (evt.getNewValue() != null){

String strNewValue = (String)evt.getNewValue();
Integer newValue = Integer.parseInt(strNewValue);
RichColumn column = (RichColumn)evt.getComponent().getParent();
RichInputText inputLimiteMaximo = (RichInputText)column.getChildren().get(0);
Integer limiteMaximo = (Integer)inputLimiteMaximo.getValue();

if (newValue < limiteMaximo){//process what i want to do}
}
}

In fact, I woudn’t need to put the component inputText visible=false inside my column, but I prefer in that way for simplify my MB code. I can navigate for all components in this page, just using getParent and getChildren. However, It’s not a good tip, because If you need to change something in the page, probably this could affect in your MB. So, be careful!