You are currently browsing the tag archive for the ‘adf’ tag.

The following link shows a helpful article comparing alternate ways of using Java to programmatically retrieve an ADF Faces or JSF managed bean.  In other words, this is how to evaluate EL in Java code.

http://java.sys-con.com/node/1984284

If you are using iOS 6 and Safari 6, you can inspect web pages shown in Mobile Safari or in WebViews of applications like those created with ADF Mobile. This can either be in the iOS Simulator or on a device (iPhone, iPad, iPod touch) connected over USB.

In Safari 6, enable the “Develop” menu:

Enable Safari Develop menu

From that menu, your connected devices and iOS Simulator will display as submenus. Each submenu will list all of the WebViews that you are able to inspect (if you are not sure which one you want, a highlight will appear on your device or in the simulator as you hover over each menu item):

Open a WebView inspector

A web inspector window will open:

Safari web inspector

In the first column, the panel with a document icon (1) is where you can browse the DOM, look at scripts, style sheets, etc.  When the HTML page is selected, the middle panel will show you the DOM tree (3) which you can manually browse for an element. Alternatively, you can use the hand tool (2) to click on the screen (of the actual device or the simulator) to pick an element that you want to inspect.

Simulator with element selected

With an element selected, you can then use the “{}” icon (4) of the right panel to view the element’s style properties.  This will show you the exact selectors that are providing each style to the element (5). This is incredibly valuable, particularly when multiple selectors are competing (a line will strike out any styles that lose due to some other more specific selector). You can also edit those values directly or add additional properties and see the change immediately take effect on the screen. Unfortunately, there’s no way to save off any changes you’ve made. If you are trying to create a custom style sheet, you’ll need to jot down elsewhere the changes you’ve made; if you leave the page or close the app, you’ll lose your changes.

It may be tempting to go crazy with panelGroupLayout components in ADF Faces and ADF Mobile. The panelGroupLayout is not the universal hammer. In many cases, you will have a simpler structure (easier to maintain, more predictable, faster performing, more flexible) if you build your structure using a panelGridLayout or tableLayout instead.

structure

When you are given a mock-up of what the application should look like, you may not know how to break it down into something simple. Either print out the design on a piece of paper or open it up in a graphics program where you can draw some lines.

  1. Draw vertical lines representing potential column divisions (red)
  2. Draw horizontal lines for potential row divisions (green)
  3. Now that you have a basic grid structure, use a different color (yellow) to draw x marks where you see cells that need to span multiple columns or rows:
    Initial set of lines
  4. You may find that your column lines really don’t make sense (in this case, the 2 middle columns had no cells in them that didn’t need to span into a nearby column. This is an indication that there probably ought to be 2 separate grids or tables.  Use a new color (magenta) to draw a line where the division makes sense and repeat the process again:
    Refined lines

Now you can go back to coding your gridRow/gridCell or rowLayout/cellFormat components because you can visually see where the content goes and where you need to use a special columnSpan or rowSpan. As an added bonus, you now have the ability to specify the sizes for your cells as well as the horizontal and vertical alignments of your cells–something panelGroupLayout would not allow you to control.

Final structure

Notice that the labels and fields of grid 2 (columns 1 and 2) are showing separate components. This is done so that there can be matching horizontal alignment among the fields of the two rows. If these were input or select components, you would need to use simple=”true” (to hide the built-in label) and then use separate outputLabel components that reference them.

While we are only using consecutive grids in the example discussed in this article. You might come across a need to nest a grid inside of another grid. Do not excessively nest panelGridLayout nor tableLayout components (if you have 3 or more deep, consider a re-evaluation of your structure). You may find it helpful if someone else reviews your structure. Your goal should be to create something simple.

Whether you are developing an ADF Mobile application or a classic ADF Server application, it is becoming more and more important to support HiDPI screens (high resolution or “retina” displays). There is no easier way to make your application look out-dated than to use grainy, unprofessional image assets or use them improperly.

In HTML, the “px” unit corresponds to the same amount of space regardless of the DPI of your device (however, the number of device pixels may vary). The original iPhone models did not have HiDPI displays. Each point of color on those screens corresponds to one HTML CSS “px” unit. Newer iPhone models introduced a HiDPI (or “retina”) display that has 4 device pixels in the same amount of space that 1 device pixel used to take up (2 device pixels wide by 2 device pixels tall); on these new devices, the width and height “px” values use twice the amount of device pixels.

Why is this a common problem? Since ADF Mobile uses HTML, displaying an image is not as simple as just specifying the source path and magically hoping the browser will know that you are using a high resolution image. You must specify dimensions to go along with the source path.

Let’s work with an example. You have an image named “image-64.png”. This image has a size of 64 by 64 individual dots of color (individual points of color information). If you coded your page like the following, the image will be shown with a width of 64px and a height of 64px (one color dot per “px”):

<amx:image id="i1" source="images/image-64.png"/>

This would look just fine on a classic low-DPI display. However, on a HiDPI display, it still takes up the same space but since there are more device pixels, the image will look very grainy.

In order to look crisp and professional, you need to set a size so that each dot of color corresponds to at least one device pixel. For a HiDPI display, this means your image needs a width and a height specified such that you use 2 dots of image color information per HTML CSS “px” unit (e.g. a 64 by 64 sized image should be specified to use a width of 32px and a height of 32px. In code, your page should look like this:

<amx:image id="i1" inlineStyle="width:32px;height:32px" source="images/image-64.png"/>

Even if you still want to support legacy devices for your application, this same image (with the same specified width and height) will look beautiful on low-DPI screens because of how images are processed modern browsers.

If for some reason you really needed or wanted to specify alternate images for each kind of device, you have the option to use a device properties EL variable to toggle the rendered state of alternate amx:image components or simply use that EL to alter the inlineStyle and the source path as desired.

Demo running in mobile Safari

In the past I posted a link to the Oracle ADF Faces Rich Client demos (server-based web applications). Now that the Oracle ADF Mobile framework for native iOS and Android applications has been released, a similar demo is now available: the Oracle ADF Mobile mock component gallery.

This mock component gallery is based on the real component gallery application bundled with the ADF Mobile JDeveloper extension. The recommended best place to view this demo is using the mobile Safari or Chrome browsers on your iOS and Android devices. Doing that will give you the closest experience to how the components will appear and behave in real ADF Mobile applications. However, you can also view the demo using desktop Safari and Chrome for an approximate experience when access to a mobile device is not available.

If you are noticing client-side performance issues in your ADF Faces application and must support legacy browsers like Internet Explorer 7 and Internet Explorer 8, there are many techniques available to help optimize your application for these browsers:

  1. If you use af:region and the jsff page fragment files have more than 1 root component, optimize it by arranging these components with a single root component. For example, if you want your region contents to stretch, you might have one visible content component and a series of popup components, put the visible content component inside of a “center” facet of an af:panelStretchLayout and put all of those popups in the “bottom” facet but also make sure to assign bottomHeight=”0px”. If you don’t want the contents to stretch, simply wrap these components with an af:panelGroupLayout layout=”vertical”.
  2. Avoid using a af:panelStretchLayout where topHeight, bottomHeight, startWidth, or endWidth is set to “auto”.
  3. Minimize uses of af:panelAccordion in discloseMany=”true” mode if possible.
  4. Minimize use of components that provide overflow popups, e.g. af:panelAccordion, af:panelTabbed, af:toolbar, af:breadCrumbs, af:menuBar. If you have to use these components, make sure that your target screen size can accommodate the content without having to invoke overflow.
  5. Minimize use of components that provide custom title text truncation, e.g. af:panelHeader and af:showDetailHeader. If you have to use these components, make sure that your target screen size can accommodate the title text without having to truncate.
  6. Minimize use of af:carousel, af:table, af:tree, af:treeTable.
  7. Avoid complex user interfaces. Users will struggle to process complex application structures. Legacy browsers will struggle with processing of complex content. Keep the number of tabs simple (use less than 10). Keep the number of columns in a table small (use less than 10).
  8. Finally, don’t ignore the warnings that JDeveloper gives you.

At some point, you may have an inlineStyle whose value is BIDI sensitive; in LTR (left-to-right) mode, you may want a “left” style but in RTL (right-to-left) mode, you may want a “right” style.  You don’t have to write a managed bean to give you the corresponding style, you can use EL (expression language).

Here’s an example assigning a padding for the “start” side of 10px:

inlineStyle="padding-#{adfFacesContext.rightToLeft?'right':'left'}:10px;"
See oracle.adf.view.rich.context.AdfFacesContext for other properties.

When defining the attributes for an ADF Faces af:pageTemplate or af:declarativeComponent inside of an af:xmlContent, you need to provide an attribute-class definition. This looks something like:

<attribute-class>java.lang.String</attribute-class>

but what if you needed an array of Strings? That has a bit stranger syntax:

<attribute-class>[[Ljava.lang.String;</attribute-class>

Why is this not just "java.lang.String[]"? These attribute-class entries are the result of calling Class.forName.  The Class.forName on an array of objects looks like "[[Lsome.package.SomeClass;".

Have you ever wanted to make an ADF Faces Rich Client component have a unique appearance but not change all other instances of that component? You can as long as the things you want to change are not skin properties or skin icons (server-side aspects like properties and icons are not part of the client-side generated style sheet so this client-side solution will not allow you to change them).

Let’s start with an interactive example; the skinning demo pages for the ADF Faces Rich Client:
http://jdevadf.oracle.com/adf-richclient-demo/components/skinningKeys/inputText.jspx

On this page, there is a right-hand side where you can see some example inputText components.  When you click on the checkboxes on the left-hand side of this page, the appearance of those start to change.  However, the inputText for the find field at the top of the page does not change.  This is because of some containment selector definitions in the skin used on this page that confines the custom styling to instances of the inputText that are contained in another component that has a particular style class.  Since the find field is not inside of that container, these custom styles do not apply to that field.

Let’s say your page has a structure like this:

<af:panelGroupLayout id="pgl1" layout="scroll" styleClass="SpecialMarker">
  <af:inputText id="it1" label="Name"/>
</af:panelGroupLayout>

To style that inputText specially in this container, you would create skinning definitions like this:

.SpecialMarker af|inputText {background-color:pink}
.SpecialMarker af|inputText::access-key {color: aqua;}
.SpecialMarker af|inputText::content {background-color:red}
.SpecialMarker af|inputText::label {font-weight: bold}

Alternatively, you could put your marker directly on the inputText like this:

<af:inputText id="it1" label="Name" styleClass="SpecialMarker"/>

and have skinning definitions like this:

af|inputText.SpecialMarker {background-color:pink}
af|inputText.SpecialMarker af|inputText::access-key {color: aqua;}
af|inputText.SpecialMarker af|inputText::content {background-color:red}
af|inputText.SpecialMarker af|inputText::label {font-weight: bold}

You can make a JDeveloper model View Object (VO) use a data query that has a custom variable accessor in Java.  This is useful for cases where you want your where clause to select based on the current user name from the ADF Security context.

Go to the “Query” tab of your view object:


Add a new Bind Variable and make sure to specify “Expression” and give the value the Groovy expression “adf.object.viewObject.yourPropertyName”.  The “adf.object.viewObject” portion is essentially like saying “this object” and then it will call getYourPropertyName() to fetch the value:


Back in your query expression, refer to this new bind variable by its name but prepend “:” to indicate that it is a bind variable as shown above.

Select the “Java” tab of your view object and then click the pencil icon to edit the settings:


Select the “Generate View Object Class” and “Include bind variable accessors” options:


This will generate a new “.java” entry under your view object in the JDeveloper application navigator:


Finally, open that Java file and change the implementation of your get accessor as you wish.  In my case, I am simply returning the user name property from the ADF security context.  I also changed my set accessor to do nothing:

Follow

Get every new post delivered to your Inbox.