domingo, 31 de agosto de 2014

Crear un ViewObject en 11g

Descripción: En este artículo veremos cómo crear un viewobject en Oracle ADF 11g.
Nota: Si quieres ver cómo se crea en 10g lo puedes ver el articulo Cómo crear un Viewobject en 10g

Para crear un ViewObject (y casi cualquier elemento del Model), se selecciona el elemento Model en Application Navigator, y con el menú contextual seleccionamos New ViewObject.

crear new viewobject menu contextual model
creando con el menú contextual

Al hacerlo se abre un asistente que nos permite ir paso a paso a crear el viewObject.
En este primer paso se solicita el Nombre que va a tener el viewObject, y también indicamos el Data Source (fuente de datos), de donde va a tomar los datos.

En este ejemplo que estamos viendo, vamos a seleccionar Entity.
Es decir, que tomará los datos de una Entity que hayamos definido anteriormente.

Nota Importante:
Si no se selecciona Entity, no podremos aprovechar la posibilidad de actualizar los valores en la base de datos a través de alguno de los objetos gráficos y del binding que nos ofrece ADF.
Es decir, no podremos añadir registros o modificar los valores en base de datos a través de los componentes. Con lo que perderíamos gran parte de la potencia que nos ofrece este framework y tendríamos que ir a hacerlo en base de datos a través de código en un bean.



poner nombre viewobject
poner nombre del ViewObject

En el siguiente paso, seleccionamos la Entity que queremos que se incluya en nuestra view.
Puede ser más de una, aunque sólo una podrá ser actualizada en operaciones de insert o update.


seleccion entity para viewObject
selección entity para el viewObject

Selección de los atributos del viewObject.



Configuración de los atributos. Es parecido en muchos aspectos a la página de configuración de atributos cuando se crea una Entity.


configuracion de atributos de viewobject
configuración de atributos

Consulta de la Viewobject. Este componente se guía principalmente de una consulta sql que indicará qué registros y qué campos (atributos), se quieren mostrar.
En este espacio, podremos incluir en la cláusula where las condiciones que querramos añadir, así como ordenar (order by) por un campo concreto.


consulta sql del viewobject
Consulta SQL del viewObject

Bind variables, variables de enlace, para incluir parámetros en las consultas.
Nota: En el artículo Creación de formulario: variables bind en la consulta, podrás encontrar más información sobre su funcionamiento.

bind variables
bind variables en la consulta

Generación de ficheros java asociados al nuevo objeto que estamos creando.
No es obligatoria esta generación de ficheros, a menos que queramos incluir código en situaciones muy específicas.

creacion ficheros java
creación ficheros java asociados


Inclusión en el Appmodule. Un ViewObject si queremos aprovechar todo su potencial, se asocia a un AppModule, que gestionará la conexión con la base de datos.
Si el Appmodule no está creado, y no lo tenemos claro, lo podemos asignar más adelante. 

asignar appmodule
asignar a un Appmodule

Resumen final de creación del viewobject, los atributos, las entidades incluidas y otros elementos vistos durante el proceso.

resumen viewobject
resumen del viewobject

El nuevo objeto en el Model.


martes, 26 de agosto de 2014

Crear una Entity en 11g

Descripción: En este artículo veremos cómo crear una entity en 11g.
Esta entity (entidad) se va a basar en una tabla en base de datos por lo que dicha tabla va a existir.
En nuestro ejemplo utilizaremos una tabla del schema HR.

Nota: Hay otro articulo en este Blog que explica cómo crear una entity en 10g.

Para Crear una entity, se selecciona el proyecto Model en nuestro proyecto, y en el menú contextual seleccionamos crear un Entity Object.

Al hacer esto se nos mostrará un asistente que paso a paso nos ayudará a crear la Entity.





Indicamos el Campo nombre (Name), y seleccionamos la fuente de datos (data source).
En este ejemplo vamos a utilizar el esquema HR que tenemos en la base de datos.

Junto a la indicación de la base de datos, también debemos seleccionar la tabla cuyos damos tomaremos para nuestra Entity. Seleccionamos "Departments".





El siguiente paso corresponde a los Atributos (Attributes), y vamos a seleccionar aquellos atributos que queremos que nuestra Entity contenga. En el caso de que no queramos tener alguno, disponemos de la opción "Remove".



Atribute Settings (configuración de atributos).
En este paso podremos configurar ciertas característica de cada atributo:
Indicar si es clave primaria o no (primary key), si es un campo obligatorio (mandatory), si se realizarán consultas sobre él (queryable), etc.

Estudiar todos estos atributos requiere más de un artículo, y recomiendo que se observe con calma.
Normalmente, a menos que queramos un comportamiento específico, comprobaremos que casi todos estos atributos están más o menos de acuerdo con lo que necesitamos.

Aún así, se puede echar un vistazo y comprobar que todo está como esperamos.





A continuación se nos consulta si queremos crear ficheros específicos Java. En estos ficheros se puede añadir código en operaciones concretas de la Entity.



En el siguiente paso, se nos consulta sobre el crear una View que contenga la Entity. Esta operación la podremos hacer más adelante.





Resumen final del objeto:



Podremos observar la nueva Entity Departments en nuestro proyecto.




Artículos Relacionados: 
- Crear una Entity (en 10g)

sábado, 16 de agosto de 2014

Acceder a otro bean desde un bean

Descripción: En este articulo veremos cómo acceder a otro bean, y ejecutar un método o tomar el valor de una variable. Veremos los objetos getSessionMap y getRequestMap.

En primer lugar tenemos que tener en cuenta qué tipo de bean es el que queremos acceder, si es un bean de tipo session o de tipo request.
Dependiendo de cual sea, se utilizara el objeto getSessionMap (beans de tipo sesión) o getRequestMap (beans de tipo request).

Para acceder a un valor en un bean de sesión (session bean): 

Object objeto = context.getExternalContext().getSessionMap().get("nombreDelBean");
nombreDelBean objetoBean = null;
if (objeto != null)
{
     objetoBean = (nombreDelBean) objeto;
}

A partir de aquí, podemos llamar a cualquier método público del objetoBean o acceder a cualquier variable.
Esta es otra de las razones por las que es preferible crear accesors en las propiedades del bean, para no permitir el acceso directo si no es a través de una función.

Hay que tener en cuenta de que un bean de sesión no estará activo hasta que no haya sido llamado con anterioridad. Es decir, si intentamos obtener el bean que queremos obtener, si no ha sido llamado antes, no aparecerá dentro del objeto getSessionMap() o en el caso de devolvernos un valor, obtendremos un null.
Por eso se realiza la comprobación más adelante, para evitar estas situaciones.

Para acceder a un valor que se encuentra en un bean de request (request bean)

objeto = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("nombreDelBean");
nombreDelBean objetoBean = null;
if (objeto != null)
{
     objetoBean = (nombreDelBean) objeto;
}

En objetoBean, dejamos una instancia del bean de tipo request que existe en la aplicación.


Artículos relacionados:
-
-
-


Pasar un valor del binding al bean

Descripción: En este artículo veremos cómo pasar un valor del binding hacia el bean.

Este tipo de operaciones se suelen utilizar para recoger un valor que se encuentra en el binding, por ejemplo un campo cuyo atribute value esté asignado al binding, así como otros componentes. Habitualmente, este valor se suele encontrar en el binding como atributeValue.

Para ello hacemos lo siguiente:

FacesContext fc = FacesContext.getCurrentInstance();
ValueBinding expr;
expr = fc.getApplication().createValueBinding("#{bindings.NombreCampo.inputValue}");
if (expr != null)
        variable =  expr.getValue(fc);


Como podemos observar la estructura es muy similar a la vista en el artículo pasar un valor del bean al binding.

Debemos tener en cuenta el tipo de la variable donde vamos a guardar el valor que estamos recogiendo. No nos va a llegar con el mismo tipo con el que está definido en el viewObject, sino que muy probablemente tendremos que hacer un cast para convertir al tipo de datos que nos interesa. 

En el caso de que no se recoja el valor del binding, habría que comprobar que hemos escrito correctamente la variable, o bien si el valor se encuentra definido como AtributeValue o con otra estructura que permita recoger el valor.

Artículos relacionados:
- Acceder a otro bean desde un bean
- Pasar valores de un bean a un binding
- Pasar un valor de un bean al procesScope

Pasar valores de un bean a un binding

Descripción: En este artículo veremos cómo pasar un valor de un bean al binding en oracle ADF 10g. 

Es bastante común encontrarse que no todo puede conseguirse con un formulario y un commit, sino que es necesario hacer operaciones en un bean antes de guardarlo.

Para pasar ese resultado de nuestras operaciones al binding, para que pueda luego ser guardado con el commit del Application Module haremos lo siguiente:

FacesContext fc = FacesContext.getCurrentInstance();
ValueBinding expr;
expr = fc.getApplication().createValueBinding("#{bindings.NombreCampo.inputValue}");
if (expr != null)
        expr.setValue(fc, valor);

La condición expr != null, viene de que podemos encontrarnos con que el valor no esté definido, o que en el momento de consultarse el bean, el binding de la página actual todavía no existe.
Esto ocurre cuando estamo llamando desde un método del bean, en un momento en el cual todavía no se ha terminado de construir la página.

Errores comunes

También debemos tener en cuenta que el nombreCampo donde queremos poner el valor en el binding, debe existir en la página de definición de la página que estamos trabajando en ese momento. Normalmente, será un elemento de tipo atributeValue, aunque puede haber otros tipos.

Puede darse el caso de que estemos reutilizando un método en un bean, que ha sido escrito pensando en una página, y ahora la estemos utilizando en otra que no contiene el mismo campo en el binding. Esto puede hacer que expr = null.

Artículos relacionados:
-
-

Pasar un valor de un bean al procesScope

Descripción: En este artículo veremos cómo pasar un valor desde un bean al processScope.
Nota: Este artículo es para Oracle ADF 10g.

El principal uso del processScope es el de poder pasar valores entre páginas.
Esta función también puede ser realizada por un bean de sesión (session bean) .

Si queremos pasar un valor a un processScope debemos seguir la siguiente estructura:

AdfFacesContext.getCurrentInstance().getProcessScope().put("Variable", valor);

En el momento de pasar el valor, hay que tener en cuenta el tipo de dato que es compatible con esta operación.

Artículos relacionados:
- Recoger el valor de un processScope en un bean
- Pasar un valor desde la pagina de diseño al ProcessScope con setActionListener
- Introducción al ProcessScope

miércoles, 13 de agosto de 2014

Recoger el valor de un processScope en un bean

Descripción: En este artículo vamos a ver cómo un valor que se encuentra en un processScope lo recoge un bean. 
Nota: Este artículo está orientado a ADF 10g.

Para recoger un valor que está en processScope, debemos tener en cuenta de que se trata de un objeto que es propio del ADF, es decir, no es algo que hemos aportado a través de una variable o de una función en nuestro código.

Utilizaremos una construcción como la siguiente:

AdfFacesContext.getCurrentInstance().getProcessScope().get("valorGuardado")

AdfFacesContext.getCurrentInstance().getProcessScope() nos lleva a tener el objeto processScope para que podamos manejarlo.

Como podemos observar por los nombres, son variables que contienen el contexto de la sesión.

En cuanto tenemos este objeto, podemos acceder a un valor concreto, dentro de ese "array asociativo". Nos basta con hacer un get con el nombre del valor que queremos recuperar para obtenerlo.

Dependiendo del tipo de variable donde vayamos a recoger el valor es posible que haya que realizar alguna conversión (operador cast).

Hay otras funciones que pueden ser de interés:
AdfFacesContext.getCurrentInstance().getProcessScope().size()
Obtiene el número de valores que hay en ese momento en el processScope.

AdfFacesContext.getCurrentInstance().getProcessScope().clear()
Borra todos los valores guardados

Consejo:
Cuando recogemos un valor guardado en un processScope, puede que tenga un valor nulo.
Recomendaría una comprobación de que dicho valor se encuentra, antes de operar con él. Es más, cada vez que se vaya a recoger un valor de un processScope habría incluir dicha comprobación.
La razón es que hay que estar muy seguro de que eso no pueda ocurrir durante la ejecución de la aplicación.



Artículos relacionados:
- Pasar un valor desde la página de diseño al processScope con setActionListener

lunes, 11 de agosto de 2014

Pasar un valor desde la pagina de diseño al ProcessScope con setActionListener

Descripción: En este artículo vamos a explicar cómo pasar un valor desde la página de diseño o vista de diseño al processScope. Para ello utilizaremos el componente setActionListener.
Nota: Este artículo está escrito para Oracle ADF 10g. La filosofía es similar para 11g, y más adelante veremos un artículo.

Para explicar este mecanismo vamos a utilizar un ejemplo en el que al pulsar un botón (commandButton) se pasará un valor al processScope, y se mostrará este valor en pantalla.

Colocamos en la página el commandButton con el que trabajaremos y le pondremos una etiqueta.
Vamos a ponerle como etiqueta: Asignar 3.

A continuación añadimos un componente setActionListener desde la paleta de componentes, como hijo del commandButton.

vista estructura de la pagina
vista estructura



se arrastra el componente desde el Component Palette
se arrastra el componente desde el Component Palette



Al arrastrarlo sobre el commandButton en la pestaña de Estructura, veremos que se nos abre una ventana de diálogo con el título "Insert SetActionListener".

datos necesarios para el setActionListener





Nos solicita dos valores:
From: Que sirve para indicar el valor de origen. Por ejemplo, si el valor proviene de una variable en un bean, de un processScope, de un valor que está en el binding, etc. También se puede colocar valores literales, por ejemplo, valores enteros, strings, etc.

To: El destino donde se guardará dicho valor. Puede ser una variable en un bean, el processScope, binding, etc. Aquí no podemos utilizar literales.

En la parte derecha tenemos unos botones con el título "Bind...", que nos abre un cuadro en el cual podemos buscar el elemento que queremos utilizar.






Buscamos el componente processScope, que estará en JSF Managed Beans / processScope.
Si no queremos buscarlo siempre podemos escribirlo directamente

#{processScope}

Hemos dicho que el processScope se puede ver como un array asociativo.
Si queremos crear una variable en el processScope basta con utilizarla directamente.
En nuestro ejemplo
#{processScope.valorGuardado}

asistente expresión del lenguaje
asistente expresión del lenguaje





Vamos a asignar un 3 al campo From, y luego en el To a la variabla valorGuardado dentro del processScope.


setActionListener campos from y to
setActionListener campos from y to


Vamos a crear otro botón que asigne un 4, y lo llamaremos Asignar 4.
Y a este botón le añadiremos un setActionListener que pasará el valor 4, a #{processScope.valorGuardado}

Con lo que cada vez que pulsemos un botón, estaremos pasando un valor.

Para este botón, he añadido el setActionListener, pulsando el botón derecho en el componente, e indicando en el menú contextual lo que queremos añadir. Tal como aparece en la siguiente imagen.

Añadiendo setActionListener desde el menú contextual
Añadiendo setActionListener desde el menú contextual






Finalmente para que podamos ver el valor que tiene actualmente processScope.valorGuardado, añadiremos un outputText que se actualizará cuando se refresque la página.
Nota: Este refresco ocurrirá porque el commandButton suele tener este efecto a menos que pongamos un partialSubmit.

Mostraremos el valor del processScope, simplemente escribiendo en el atributo value #{processScope.valorGuardado}


vista resultado
vista resultado

vista resultado
vista resultado




Conclusión:
Como hemos visto, el processScope es un mecanismo sencillo para guardar valores que queramos utilizar en otras páginas, sin tener que recurrir a un bean. De hecho en este ejemplo, no hemos tenido que utilizar código para poder guardar el valor o mostrarlo.



jueves, 7 de agosto de 2014

Introducción al ProcessScope




Descripción: En este artículo veremos una herramienta propia del Oracle ADF 10g, que es el processScope.

El processScope es un ámbito o un espacio en el cual se puede guardar información que queramos mantener entre páginas.

Si lo miramos con una variable declarada en un bean de session, sabemos que ésta comenzará a existir en el momento en que se "crea" o se llama al constructor del bean. Hasta ese momento no existe.

Sin embargo el processScope, no necesita ser declarado para comenzar a usarse. No necesita tampoco indicar qué variables va a contener antes de utilizarse.
Se puede ver el processScope como un Array que está disponible en cualquier momento y en el cual podemos depositar datos.

Los datos que se suelen depositar, suelen contener información que se pasa de una página a otra, o de una ventana modal a la página que la llamó.
El tipo de datos que se suele pasar es de tipo String, aunque también podemos pasar en otros formatos. Internamente, el tipo de datos que guarda es de tipo Object.

Advertencia

Al utilizar un processScope, tenemos que andar con cuidado pues al ser un objeto que no desaparece tras su uso, mantendrá información hasta que alguien decida borrarla o cierre la sesión.
Puede ocurrir que estemos en un escenario y guardemos un dato en un processScope, y en otro escenario utilicemos el mismo nombre para una funcionalidad distinta. Si no hemos borrado la información que contenía, nos podemos encontrar que la aplicación no va por el camino esperado o que presenta unos datos erróneos que puede costarnos detectar.

Por eso recomendaría, que su uso esté limitado a ciertas páginas, y que antes de utilizarlo, "limpiar" las variables que participan. Otra forma de resolver este problema sería el utilizar nombres únicos relacionados con el pantalla o escenario en donde estamos trabajando, con la idea de reducir el riesgo de utilizar un dato inesperado.

En siguientes articulos veremos cómo pasar información de una página jspx al processScope, del processScope al bean o viceversa.
La idea es poder familiarizarnos con esta útil herramienta.



martes, 5 de agosto de 2014

Refrescar componente con PartialSubmit y PartialTriggers

Descripción: En este artículo se va a explicar cómo realizar el refresco de un componente sin necesidad de refrescar toda la página, con el atributo partialSubmit y PartialTriggers.

Nota: Puedes descargar el ejemplo para hacer tus propias pruebas.Dentro del proyecto "PaginaBuscador.jspx" Descargar Ejemplo

Para realizar este refresco ADF incluye en sus componente AJAX que permite enviar datos al servidor y recibirlos sin la necesidad de refrescar una pantalla completa.

Utilizaremos para explicarlo un ejemplo en el que tenemos, una tabla (aftable), en el que actualmente disponemos un botón que realiza un refresco.






En este proceso de uso de partialTriggers, se hace referencia al atributo id del componente que genera el cambio.
Por ejemplo, queremos que cuando se seleccione un elemento en la tabla, se cambia el valor que tiene el OutputText, y muestre el valor de la columna LastName de la fila seleccionada.

En los siguientes pasos vamos a ir viendo los elementos que se van nombrando:
Ponemos en el campo Id de la tabla (aftable) el valor idTable. Así cuando queramos referirnos a la tabla como "disparador" del cambio, utilizaremos el Id que le hemos dado.



Si queremos también que el botón seleccionar pueda ser "disparador", haríamos lo mismo, pondríamos un valor en el atributo Id.
Nota: En 11g, no es necesario este paso, porque ya pone un valor por defecto a este atributo. De hecho todos los elementos de la página suelen tener un id asignado. Se recomienda eso sí, personalizarlo para que sea más fácil programarlo.


En esta imagen, hemos indicado que el botonSeleccionar sea el disparador del outputText. Si queremos que sea la tabla, podemos añadir el id de la tabla.
Nota: partialTriggers permite más de un disparador.

Al botón Seleccionar le podemos indicar que cuando sea pulsado, no haga un submit en el que refresque toda la página sino que lo haga parcialmente. Para ello usamos el atributo partialSubmit.



Con esto, el botón que se encuentra en la tabla, actualizaría el OutputText con el valor que tuviera la tabla en ese momento.

Si queremos que el cambio se haga sin necesidad de pulsar el botón, sino simplemente con la selección de un elemento de la tabla, utilizaremos el atributo autosubmit, que se encuentra dentro del facet Selection, en el elemento af:tableSelectOne.







No olvidar, que si hacemos esto del autosubmit, debemos indicar en el campo partialTriggers del botón, el valor "idTable", si no, no hará caso al cambio que se ha producido en la tabla.

lunes, 4 de agosto de 2014

Mostrar el valor seleccionado en un aftable

Descripción: En este artículo veremos cómo tomar el valor seleccionado en una tabla (aftable) y mostrarlo en pantalla. Para ello usaremos bindings.

Partimos de una página donde hay un buscador, y un aftable que muestra los resultados de la búsqueda.





Para mostrar el elemento seleccionado utilizaremos un OutputText.

incluir outputText para mostrar valor seleccionado
incluir outputText para mostrar valor seleccionado


Pero claro para poder mostrar el valor seleccionado en una tabla, no podemos tomar el valor directamente de ésta, sino a través del binding.
Para ello, debemos ir a la página de definición y crear un atributeValue.

crear attributeValue en pagina definicion
se crea un attributeValue




Dentro del bloque bindings, se selecciona con el botón derecho y en el menú contextual seleccionamos Insert inside bindings, y luego atributeValues.

Al hacerlo se nos muestra la siguiente ventana.

attribute binding editor
attribute binding editor



Seleccionamos el campo que queremos mostrar. En este caso el apellido (LastName).

En el outputText, solo tenemos que indicar que en el atribute Value, vamos a tomar el valor del binding.
#{bindings.LastName}

Lo podemos hacer pulsando la opción "bind to data" que está justo encima, y que nos abrirá un cuadro para crear la expresión del lenguaje que irá.

asistente expresiones para tomar el valor del binding
asistente Expresiones


Nota: Es posible que en la parte izquierda no aparezca el valor que hemos creado con el atributeValue. En ese caso puedes probar a guardarlo todo, comprobar que se ha creado el atributeValue correctamente. Si está creado y no aparece en el cuadro, bastará con cerrar la página y volverla a abrir.

Podemos añadir, si queremos, un texto que acompañe al valor que seleccionamos.

atributo value
añadimos un texto en el atributo Value



Ya podemos ejecutar la página y ver el resultado:



vista resultado



Como comprobamos, podemos seleccionar varios elementos, y no cambiar el texto inferior. Sólo cuando se pulsa el botón "Seleccionar", se produce el refresco de la pantalla, y en ese momento, también se refresca con el valor que ha pasado al binding.

En el próximo artículo veremos cómo refrescar el valor, sin necesidad de estar pulsando el botón seleccionar, a través del atributo autosubmit, partialsubmit y con el atributo Partialtriggers.


Artículos relacionados:
- Añadir una tabla (listado)
- Mostrar todos los elementos de una tabla (aftable)
- Refrescar componente con PartialSubmit y PartialTriggers 

viernes, 1 de agosto de 2014

Ejemplo de Maquetación. Parte 3

Descripción: En este artículo vamos a centrar un aftable, utilizando el componente tableLayout.También veremos cómo presentar los resultados con colores alternados en el aftable con el atributo banding.

Nota: Puedes descargar el ejemplo completo en este enlace: Descargar Ejemplo


En el artículo anterior nos habíamos quedado la página tenía el siguiente aspecto:

vista de la página resultado



Si nos ponemos a jugar con el porcentaje del ancho de la tabla (width), vemos que ésta se encuentra alineada en el lado izquierdo de la página.

Si queremos centrarla podemos utilizar el componente afh:tableLayout.
El componente tableLayout, recuerda mucho al elemento Table del HTML, en el que el contenido se coloca dentro de elementos <TD>, que su vez estaban dentro de elementos <TR>.
En este caso utiliza otros componentes afh:rowLayout y afh:cellFormat. 

vista estructura página



Como podemos observar hemos añadido los elementos afh:tableLayout, afh:rowLayout y afh:cellFormat, y también se ha colocado dentro de este último elemento nuestra tabla.
Si observamos el resultado, la página se nos queda como sigue:


vista página resultado



A primera vista parece que hemos salido perdiendo con el cambio.
Para empezar tenemos que el ancho de la tabla (af:table) ya no ocupa todo el ancho de la página, sino que ha encogido.
La razón es que habíamos definido el ancho (width) de la tabla con el 100%. En la estructura anterior significaba ocupar el 100% del elemento que lo contiene, en ese caso el elemento era el af:panelGroup.
Si éste, hubiera tenido el ancho definido al 50%, nuestra tabla (af:table) hubiera ocupado la mitad del ancho de la pantalla (el 100% ancho definido por el elemento contenedor).

Entonces si queremos ampliar el ancho del elemento contenedor (afh:tableLayout), lo haremos a través de sus propiedades, y cambiando el atributo width.

selecionamos el elemento contenedor afh:tablelayout


En el Inspector Properties cambiamos el ancho (width) a 70%, y también alineamos la tabla, al centro (Halign = center). 


atributos halign y width


Con estos cambios el aspecto de la página es el siguiente:


aspecto de la página



Como podemos observar ya se parece bastante al aspecto que queríamos tener.

Para terminar, vamos a hacer que los resultados de la tabla aparezcan de forma alternada (banding).
Para ello, seleccionamos el af:table que contiene los resultados.

selección af:table en la estructura

Y cambiamos el atributo banding en el inspector properties.

atrubto banding

Como podemos observar, banding, nos permite varias opciones, y eligiremos que los colores alternados se muestren a nivel de filas (row).

También vamos a cambiar el ancho de una de las columnas, para que no aparezcan ambas columnas con el mismo tamaño.
Vamos a poner la columna del FirstName, algo más corta que las del LastName.

cambio ancho columna FirtsName (af:column)


cambio del ancho de la columna

El resultado que nos queda es el siguiente

vista resultado



Con esto termina este ejepmlo de maquetar/perder el miedo a mover objetos, dentro de una página en Oracle ADF. 

Artículos relacionados:
- Ejemplo de maquetación de una página (Parte 1)
- Ejemplo de maquetación. Parte 2