Blog Archives

September 23rd, 2011
3:17 pm
Preventing Overflow with long strings in table cells

Posted under JSF
Tags , , , , , , ,

I hit this issue when displaying email addresses in a p:dataTable.

The problem is that for long strings without spaces, the browser tries to enlarge the table cell width, causing the table to stretch beyond the correct bounds and messing up the layout. A column will wrap and enlarge vertically, but this will only be done when it can break on a space. Setting the widths for the columns is technically just advisory on the browser and may be overriden if needed.

There are various solutions to this, and this post here in Stack Overflow discusses them.

My chosen solution in this case was the following:-

  • Place the text in the cells in <spans>, to allow them to be styled with CSS. You could also style the column <td> cells by applying style/styleClass attributes to the p:column tag, but this will limit your flexibility – for example if you do this p:column does not expose the title attribute on the <td> (see below)
  • Style the <spans>  with display:inline-block;overflow:hidden. This allows a width to be set for the span (I used the same width as set for the column), and hides any overflow (which would otherwise bleed into the next column).
  • Text will still wrap on spaces if they are present, but long strings without spaces, such as email addresses or file paths, do not cause a problem, but they will truncate and so will not be fully visible by default.
  • I include a title attribute on the span to include the full text. This allows the full text to be displayed on hover for any long strings that are truncated in the cell.

This neatly solves the problem, and prevents the table layout messing up.

No Comments »

September 23rd, 2011
2:12 pm
Using Non-blocking spaces in xhtml

Posted under HTML
Tags , , ,

Occasionally this is useful – I had to do this when I wanted to adjust the spacing in a Primefaces p:dialog header. The header text can only be set via an attribute which does not allow any markup to be used (a header facet is not currently available for a p:dialog).

The old &nbsp; entity does not work in xhtml as it is deprecated.

The solution is to use the Unicode equivalent directly, which is &#160;

My previous related post about using Unicode characters in HTML may be found here.

No Comments »

September 23rd, 2011
12:18 pm
Re-queuing JSF Events

Posted under JSF
Tags , , , ,

This is a very simple and powerful technique which can provide an easy solution to a number of event issues.

The case in point was where I wanted a value change event on an input component (a check box) to behave like an action event.

The value change event will normally fire after validation (after the Process validations phase). In my case, I wanted the event to be fired at the Invoke Application phase, as would happen with a button click. In other words, I wanted my checkbox to behave more like a button.

Whilst there are other ways around this  kind of issue, they often involve messing with the JSF life cycle by using immediate components/calling render response early etc. and typically have other side effects. For example, in a Value change event you will not see the results of the bean setters being called as this has not happened yet, so you end up having to make JSF calls to manually update values early etc.

Instead, a value change event can easily be re-queued to occur in the Invoke Application phase. The beauty of this is that you are relocating the event rather than messing with the JSF lifecycle, which means that the event happens in the context you want it to, and everything is set up correctly.

To requeue an event, you must detect when it fires the first time, and then requeue it. When it fires the second time, you detect this again and perform the action that you desire.

Here is a code sample which does this:-

    public void showInheritedListener(ValueChangeEvent event) {

        /*
         * Requeue this event to the Invoke Application phase so it behaves like an action
         * This ensures that all the model values have been updated.
         */
        if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
               log.fine(this+":showInheritedListener: oldValue="+event.getOldValue()+", newvalue="+event.getNewValue());       
            boolean newValue = (Boolean)event.getNewValue();
            changeInherited(newValue);
        }
        else {
            event.setPhaseId(PhaseId.INVOKE_APPLICATION);
            event.queue();
        }       
    }   

An important point to note is the use of event.getPhaseId() to detect which phase the event is currently being called in. In particular, when it is first called after the Process Validations phase, it is important to note that event.getPhaseId() will return PhaseId.ANY_PHASE, which is not expected or intuitive. You will see from the above code that by handling the first call to the event in the else clause of the if, we only have to test for the second call, when event.getPhaseId() will return PhaseId.INVOKE_APPLICATION as you would expect.

This technique is clean and simple to use, and does not suffer from unwanted side effects that other solutions have. It is well worth taking note of.

No Comments »

July 27th, 2011
9:05 am
f:selectItem error – java.lang.String cannot be cast to javax.faces.model.SelectItem

Posted under JSF
Tags , ,

I received this error when using <f: selectItem> on a prototype of a page:-

java.lang.ClassCastException: java.lang.String cannot be cast to javax.faces.model.SelectItem

It turns out that the error was trivial, but easy to miss at first glance.

My initial code was as follows:-

<f:selectItem value=”1″ itemLabel=”&lt;default&gt;”/>

The mistake was to use the value attribute instead of the itemValue  attribute. The following is the corrected code:-

<f:selectItem itemValue=”1″ itemLabel=”&lt;default&gt;”/>

 This solves the problem.

No Comments »

July 27th, 2011
7:34 am
Primefaces p:panel–main panel bar/title bar does not render at all

Posted under JSF
Tags , , , ,

This issue was encountered under Primefaces 2.2.1 – other versions have not been tested for this. In certain cases it is possible for the panel component to not render the title bar at all.

When this happens, the content is rendered assuming the panel is expanded, but the panel bar itself does not render, and crucially, there is therefore no access to the expand/collapse icon as it is not rendered. Other components can expand/collapse the panel via its widget however.

This is caused when there is neither a header attribute present nor a header facet present. If one or other (or both) are present, the panel title bar does render. Note that the behaviour occurs even if toggleable is set to true.

This behaviour is undocumented and is rather a gotcha when you hit it, as it seems indicative of something more serious.

The solution is straightforward however – you must provide either the header attribute or a header facet in order for the panel component itself to render correctly.

No Comments »

July 26th, 2011
10:31 am
Extra unwanted margin around an HTML textarea in Google Chrome

Posted under CSS
Tags , , , , , ,

Chrome places an unwanted 4px bottom margin on a textarea, which is impossible to elminate purely by the margin settings.

In addition, the other browsers sometimes have related issues.

This post on StackOverflow discusses the issue, and the Chrome bug issue may be found here.

Issues like this can be caused in inline and inline-block elements, due to side effects of the line height/vertical alignment of textual elements. They can be hard issues to diagnose as the cause of the extra margin is not readily visible in tools like Firebug or Chrome’s developer tools/debugger. In order to see it, I added an extra div with a border around the element, and the margin was then clearly visible, but of course it was still not reported as a margin on the textarea element, which steadfastly maintained its story that no margin was present!

As per the StackOverflow article, there are 2 ways around this issue:-

  • If the textarea is set to have vertical-align:top then this eliminates the problem. It also has the advantage of maintaining the element as inline-block – in Chrome’s case this is the default, and with other browsers this will often be used in order to allow margins etc. which an inline element will not allow.
  • Another fix for the problem is to set the textarea to display:block, i.e. to make it a block element. This is fine, but it should be noted that as the element is not natively a block type element, IE7 and earlier IE versions will not handle this. IE8 and IE9 will allow an inline element to be redesignated as a block one. Therefore, the first method has better browser compatibility.

No Comments »

July 21st, 2011
10:58 am
More useful Posts about inline-block and alignment

Posted under CSS
Tags , , , , ,

Update 18/1/2012

I was having trouble getting cross theme and cross browser consistency in aligning text adjacent to an icon in a series of IconTextButtons of mine, inside a toolbar.

Both the icon and the text were in spans set to display:inline-block and the spans were inside a div. I found the following useful in solving the issue :-

  1. The key issue turned out to be that the line-height was very different across Primefaces themes. The font size was constant at about (effectively) 11.5px, but the effective line-height varied with the them between 12px and 16px. This was the main cause of the issue in getting good alignment.
  2. I just set a fixed line-height of 14px for all the buttons in the toolbar, and this solved the cross theme (and cross browser) issues.
  3. The text was to the right of the icon, and found that tweaking the top margin for the icon set the position of both it and the text vertically, due to the adjacency-relative way in which vertical-align works.
  4. In order to adjust the vertical alignment of the text slightly relative to the icon, I found that setting a small bottom margin on the text achieved this, so one to bear in mind when experimenting.
  5. I had also tried padding changes as well as margin, but the effects (or lack of them) were similar to tweaking the margins.

 

Original Post

This post gives a good description of the effect on margins and padding for inline vs. block elements elements.

This StackOverflow post point out the effect of adjacent inline elements on the vertical alignment of an element – in this case an element was pushed down a few pixels due to the prescence of adjacent inline elements.

I was trying to align text and buttons in a narrow vertical toolbar, and as I have found previously, different browsers render differently.

The best consistency across browsers was obtained as follows :-

  1. Use display:inline-block to allow vertical margins to be obeyed on the elements. They can then be precisely adjusted (but may still behave differently depending on the adjacent elements). inline-block has decent cross browser support. IE6 and IE7 only support it on elements with a native type of ‘inline’ – see this post for cross browser support details.
  2. Using vertical-align:bottom seems to give the best cross browser consistency.
  3. Top and/or bottom margins generally need to be tweaked for each individual case depending on element adjacency. (Depending on the case you may need to set a top or a bottom margin to have the desired effect consistently across browsers.) For example, I had to treat a text only span differently to a text span adjacent to a couple of buttons on the bar.

No Comments »

July 19th, 2011
8:54 pm
JPA – Accessing the primary key ID allocated during a persist operation on a new entity

Posted under JPA
Tags , , , ,

I wanted to do this in order to use the ID as part of the creation of a Base64 encoded tree path in another column in the same row, as I was using path enumeration as my tree algorithm (see here on slideshare.net for an excellent article on database tree algorithms).

The simple answer is – you can’t do this reliably, unless you allocate IDs yourself in some way.

  1. The ID is not available before a persist. I could call flush and then read it back, create the TreePath and then persist again – this is safe. This is discussed here on Stack Overflow.
  2. The JPA Lifecycle callback @PrePersist does not guarantee that the ID is visible. The net is rather quiet on this but this post here about hibernate says it cannot be relied upon  (@PostPersist would of course be different). There are strong limits on what you can do in such a callback or entity listener. For example, you can’t do entity manager operations, persist entities, or refer to other entities etc.
  3. Triggers would be another way to avoid the double update. I could set the rest of my TreePath prior to the first persist, and then retrieve the actual ID in a before insert trigger using the new.TreePathID syntax (MySQL and Oracle use similar syntax in this respect). I could then encode it in Base64 using a stored procedure, and append it to the treepath. Oracle has a built in package with Base64 encoding and decoding available (the utl_encode package). For MySql there is an open source example on the internet here. From posts on the net, e.g. here, triggers do work in MySQL via JPA.

The best solution looks like using triggers on the database server, as this avoids the double update. I have yet to investigate/try this.

No Comments »

July 19th, 2011
5:35 pm
Calling a utility POJO from a Session Bean

Posted under EJB
Tags , , , ,

Update 17/10/2013

This StackOverflow Post here is by David Blevins, EJB 3.1 expert group member among many other things. It confirms my original post below that plain CDI beans can be freely mixed with EJBs etc. and that you use what you need based on the features offered. It confirms that an @ApplicationScoped bean is pretty much an @Singleton but does not have the @Startup capability to run a method when the application starts. There is a javax.inject.Singleton as well as a javax.ejb.Singleton, however this post here points out that javax.inject.Singleton is not part of the official CDI spec. Therefore, it suggests (as does David Blevins in the above post) that you use @ApplicationScoped if you don’t need the special transactional/locking features of @Singleton (javax.ejb.Singleton that is), as it can be a lot faster.

In my case, there are a number of places where I may now end up replacing intermediate @Stateless beans with @Application scoped ones for simplicity and performance.

Original Post

A number of blog posts on this maintain that you need to create an EJB singleton for this, and set it to readonly, perhaps with Transactionattribute  set to unsupported to suspend the transaction whilst in the utility POJO/EJB.

Assuming the utility POJO did no database access and had no transaction involvement, I could see no reason for this. After all, an EJB can create and use an ArrayList for example without having to take any special actions. Why should my utility POJO be any different? In my case, the POJO was using the Apache Base64 encoder to encode an ID in Base64. When I subsequently read the CDI spec for info on this, it came to the rescue. CDI states that you can pretty much inject anything into anything else.

In particular, on P13 of the weld spec, Section 2.2.2 “SessionBeans” it states :-

“You can inject one session bean into another session bean, a managed bean into a session bean, a session bean into a managed bean, have a managed bean observe an event raised by a sessionbean, and so on.”

Therefore, if I just have a plain utility class which has nothing to do with session beans, the DB, or transactions, I can just inject it with CDI and call it from a session bean. I do not have to make it a singleton session bean/with readonly locking/transactions not supported etc.

The restriction would be that unlike session beans it could not be called remotely with all the clever EJB remote stuff, however this is absolutely not required in cases like this, I would just deploy it as a utility library in the local container along with the rest of the application. Each application server would therefore have its own copy.

This finally makes sense. In my case, it also works perfectly well when I inject an application scoped POJO into a stateless session bean.

No Comments »

July 19th, 2011
5:00 pm
Sync issues between TyTn II and Windows 7/Windows Mobile Device Center

Posted under 64 Bit
Tags , , , , ,

My old TyTn II has had sync issues over the last few weeks, sometimes needing several attempts to sync.

A few days ago it failed completely with sync errors part way through.

I have tried a number of things to resolve the issue, with only partial success.

1/ WMDC 6.1 did not sync at all. I tried turning ‘advanced network functionality’ both on and off on the TyTn II (under settings/connections/USB to PC), and neither worked. The advanced setting is apparently what allows the device to share the PCs internet connection, and is not available with this turned off, although I have not investigated this.

2/ I tried removing WMDC 6.1 and installing WMDC6.0 for Windows 7/Vista 64 bit, but it always installed 6.1 as part of the install, and so was very tricky to roll back.

3/ This procedure worked in the end and allowed 6.0 to install (as per this forum post here):-

Note that as part of this procedure, when deleting the WindowsMobile folder, renaming it first then allows all the contents to be deleted (possibly rebooting after the rename but this was not always required). Note also that I turned windows update automatic mode off so that it would always ask about any update first, in case it was responsible for the ‘invisible’ update to 6.1

Here are the steps that I performed during this cycle of events that has got
my Dopod phone with WM6 sync’ing again with WMDC 6.0:
— Uninstalled the two Windows Mobile Device Center 6.1 items from the
Control Panel > Programs and Features list
— Manually deleted the contents of the C:\Windows\WindowsMobile folder.
Initially I could not delete some DLLs but once the two “Windows Mobile
device connectivity” services were stopped from the Task Manager, I was able
to delete the rest of the files in the WindowsMobile folder, except for the
en-US folder containing the *.MUI files. I could not delete them and so
decided to leave them.
— Using Regedit, I deleted all entries from the following two keys that
related to my two devices:
* HKCU\Software\Microsoft\Windows CE Services\Partners
* HKLM\Software\Microsoft\Windows Portable Devices\Devices (I left
in the entry for my memory card)
— Using Windows Explorer, I deleted all files in the following folder:
* C:\Users\<username>\AppData\Roaming\Microsoft\Acti veSync\Profiles
— With my two Pocket PCs disconnected, I tapped on Start > Programs >
ActiveSync > Menu > Options, highlighted the Windows PC and tapped on and
the Delete button. Both of my PPCs had two entries in here so there could
have been some confusion on the desktop at some point, so I deleted both of
them. They do not sync with any other computer.
— Rebooted (Restarted) my Windows Vista computer
— Reinstalled WMDC 6.0 from the Microsoft Download website.
— Recreated the two relationships from my two devices, and they each did
the initial long sync
— I then tested each device that it could perform a sync not long after it
was reconnected, and they both now sync perfectly. I also tested that making
any changes to some contact details in Outlook 2007 would update the devices
after a sync. and it did.

4/ When using WMDC 6.0, I had to disable the Advanced Networking Functionality on the device, as WMDC was unable to install the correct driver for it when I tried.

4/ This now allowed the TyTn II to sync contacts, calendar and tasks. However, annoyingly, it does not sync the textual content of calendar appointments or tasks – only the headers are synced. This is the ‘partial’ solution that I am having to live with. The good point is that at least contacts are synced properly, and at least with the appointments I will get reminders on the phone plus the title details, which is enough for most of them.

5/ I retried the different versions a number of times but this behaviour was consistent. In the end I had to use system restore to remove 6.1 as the driver update would not remove. It may have done so in safe mode but I did not try this. The behaviour was consistent with both USB and bluetooth syncing.

6/ I also tried syncing with a laptop running Windows XP, but interestingly this also failed to sync, which perhaps points the finger at the TyTn II as this used to work.

7/ I tried running SCANPST.EXE (in the C:\Program Files (x86)\Microsoft Office\Office12 folder) to check for PST corruption as a possible issue. Interestingly it did find a number of issues. It fixed most, if not all of them ( I reran the check again after it had done the fix and some errors remained). However, these errors have not caused any issues when using Outlook and did not allow the TyTn II to sync with WMDC 6.1

It is not clear what the actual issue is, but it is interesting that WMDC 6.0 at least completes a full sync consistently (albeit without calendar/task text). There are any number of posts on the internet complaining about this issue, and I must say I agree with them. It is hugely ironic that an iPhone can sync with Outlook but in many cases a Windows Mobile cannot.

No Comments »