ActionScript: Correctly casting a bitmap to a class - actionscript

I have tree instance calling an iconFunction "getIconFromItem".
<mx:Tree dataProvider="{collection}" iconFunction="getIconFromItem" />
The getIconFromItem function is returning null even though the bitmap is not null.
public function getIconFromItem(item:Object):Class {
var result:Class = item.icon as Class ;
return result ;
}
Setting a break point on the return result line reveals that item.icon is a bitmap and result is null.
Any ideas or pointers on how to successfully cast a bitmap as class so that the bitmap is returned as an icon?
Cheers
Keith

The problem here is that item.icon is of type Bitmap, which is not extended from the type Class, but from Object. Whenever you cast to a type that is not in the object's type hierarchy, null is returned.
You want to get the class of the icon, which will be instantiated by the tree control, not the icon itself, so you should change your function to
public function getIconFromItem(item:Object):Class {
return item.icon.constructor as Class;
}

The issue was iconFunction expects a class. Each embedded image has a subclass automatically generated by the compiler. Thanks to #weltraumpirat for pointing me in the right direction :-)
The goal was to dynamically display icons in a tree class. It is possible to modify the class created by Ben Stucki (http://blog.benstucki.net/?p=42) to work with the TreeItemRenderer.data object but this failed when I created a custom MXTreeItemRenderer.
Ended up creating a BitmapImage and a custom TreeItemRenderer which used a prefined iconBitmap attribute within a class to dynamically load icons.
package components
{
import flash.display.BitmapData;
import mx.core.mx_internal;
import spark.core.IContentLoader;
import spark.primitives.BitmapImage;
public class RuntimeBitmapImage extends BitmapImage
{
public function RuntimeBitmapImage()
{
super();
}
public function set bitmapData(bitmapData:BitmapData):void
{
super.setBitmapData(bitmapData, false);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:MXTreeItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" >
<fx:Script>
<![CDATA[
override public function set data(value:Object):void {
super.data = value;
if ( value != null ) {
if ( value.iconBitmap != null ) {
runtimeBitmapImage.bitmapData = value.iconBitmap.bitmapData ;
}
}
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:HGroup left="0" right="0" top="0" bottom="0" paddingTop="2" verticalAlign="middle">
<s:Rect id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" alpha="0">
<s:fill>
<s:SolidColor color="0xFFFFFF" />
</s:fill>
</s:Rect>
<potentiate:RuntimeBitmapImage id="runtimeBitmapImage" left="2" width="18" />
<s:Label id="labelField" text="{treeListData.label}" paddingTop="2"/>
</s:HGroup>
</s:MXTreeItemRenderer>

Related

Binding in a Style Setter in WinUI 3

Does WinUI 3 support binding in a Style Setter? I've defined a Style for a NavigationView and the third line is:
<Setter Property="CompactPaneLength" Value="{Binding CurrentCompactPaneLength}" />
This produces a Specified cast is not valid. exception at run time. The DataContext for the page containing the NavigationView is the ViewModel for the page. Both NavigationView.CompactPaneLength and CurrentCompactPaneLength are double and public and CurrentCompactPaneLength is an ObservableObject (from CommunityToolkit.Mvvm.ComponentModel).
The source code for the WinUI 3 (SDK 1.1.2) includes various Setters, such as
<Setter Target="PaneContentGrid.Width" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CompactPaneLength}" />
Doing the bindings in code works, if that's what's necessary. But shouldn't the XAML work, too?
Apparently, general bindings in Setters are not supported yet in WinUI 3, although it is a much-requested feature. A workaround is to create a helper class with a DependencyProperty in it that calls a change handler whenever the property is changed/set. The change handler can then create the required binding in code. Kudos to clemens who suggested something like this ages ago for UWP. Here is an example helper class:
internal class BindingHelper
{
#region CompactPaneLengthBindingPath
public static readonly DependencyProperty CompactPaneLengthBindingPathProperty = DependencyProperty.RegisterAttached(
"CompactPaneLengthBindingPath", typeof(string), typeof(BindingHelper), new PropertyMetadata(null, BindingPathChanged));
public static string GetCompactPaneLengthBindingPath(DependencyObject obj)
{
return (string)obj.GetValue(CompactPaneLengthBindingPathProperty);
}
public static void SetCompactPaneLengthBindingPath(DependencyObject obj, string value)
{
obj.SetValue(CompactPaneLengthBindingPathProperty, value);
}
#endregion
#region HeightBindingPath
// another DP is defined here (all of them are strings)
#region ForegroundBindingPath
// and a third one, etc.
// ===================== Change Handler: Creates the actual binding
private static void BindingPathChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is string source) // source property (could add DataContext by setting Value="source#datacontext" for example)
{
DependencyProperty target; // which property is the target of the binding?
if (e.Property == CompactPaneLengthBindingPathProperty) target = NavigationView.CompactPaneLengthProperty;
else if (e.Property == HeightBindingPathProperty) target = FrameworkElement.HeightProperty;
else if (e.Property == ForegroundBindingPathProperty) target = Control.ForegroundProperty;
else throw new System.Exception($"BindingHelper: Unknown target ({nameof(e.Property)}"); // don't know this property
obj.ClearValue(target); // clear previous bindings (and value)
BindingOperations.SetBinding(obj, target, // set new binding (and value)
new Binding { Path = new PropertyPath(source), Mode = BindingMode.OneWay });
}
}
Note that all of the DependencyProperties are of type string and that the target type can be any ancestor type of the control you are working with. For example, the HeightBindingPathProperty binding can be used with any FrameworkElement.
Use the helper in a Style just as you would any Setter, like this:
<Style x:Key="MyNavigationView" TargetType="controls:NavigationView" >
<Setter Property="local:BindingHelper.CompactPaneLengthBindingPath" Value="CurrentCompactPaneLength" />
</Style>
I hope this helps.

Polymer custom element property not accessible in nested template

I have a custom element like below:
<polymer-element>
<template if="{{primaryLoaded}}">
<template repeat="{{pData in primaryData}}">
<p>{{pData.propertyOne}}</p>
<p>{{someClass.someOperation()}}</p>
<template if="{{secodaryLoaded}}">
<p>{{secondaryData.someProperty}}</p>
<p>{{someClass.someOperation()}}</p>
</template>
</template>
</template>
</polymer-element>
and a corresponding dart file:
class CustomElement extends PolymerElement with ObservableMixin
{
#observable bool primaryLoaded = false;
#observable bool secondaryLoaded = false;
#observable var primaryData;
#observable var secondaryData;
#observable var someClass;
void created()
{
primaryData = toObservable(new List<var>());
secondaryData = toObservable(new List<var>());
}
void inserted()
{
someClass = new SomeClass();
loadPrimaryData().then((pData) {
primaryData = pData;
primaryLoaded = true;
loadSecondaryData().then((sData) {
secondaryData = sData;
secondaryLoaded = true;
});
});
}
}
Everything works fine for the primaryData. Its properties get printed and the call to someOperation() on someClass prints its data correctly.
The problem is in the nested template. Nothing under the <template if="{{secondaryLoaded}}"> gets displayed. Even the call to someClass.someOperation() fails to display anything.
Is there a problem with scope here? It looks like the outer template can reference the properties defined in the dart file without problem but the nested template can't.
I read about setting variables as globals in the template by setting a custom binding delegate here. However, I can't set the bindingDelegate in my custom element as isTemplate returns false.
Is there any other way of setting a global variable in a custom template? Or am I going about this all wrong?
It's a bug. You can star this issue to be notified of changes:
https://code.google.com/p/dart/issues/detail?id=12742
The only thing you can do for now is to turn nested templates into other polymer elements or figure out a way so the template isn't nested.
In your case, instead of using if="primaryLoaded" you could just set primaryData = null and the template shoud not display anything until primaryData is set, assuming primaryData is #observable.

JSF 2.0 Required Field Label Decorator for properties with #NotNull Constraint

I have a JSF 2.0 application which also uses Primefaces 3.3. Currently there is a nice feature where a label is decorated with an asterisk if the related <p:inputText> uses a required="true" attribute.
This field is bound to a bean property which is annotated with #NotNull validation constraint. It seems redundant and error prone to have to also add required="true" in the XHTML when the bean property is already annotated with #NotNull.
Is there a hook or some way to automatically decorate labels for components that are bound to properties with #NotNull?
Any thoughts or suggestions are greatly appreciated.
Note: This is a hack. It may have performance implications due to it's use of introspection
At a basic level, what you need to know if the field is annotated with #NotNull. Perform this check in a sensible place like #PostConstruct for a view scoped bean. Declare a global variable to determine the required attribute
boolean requiredAttribute;
#PostConstruct
public void init{
Field theField = this.getClass().getField("theField");
NotNull theAnnotation = theField.getAnnotation(NotNull.class);
if(theAnnotation != null){
requiredAttribute = true;
}
}
Bind the required attribute to the variable in the backing bean
<p:inputText id="inputit" required="#{myBean.requiredAttribute}"/>
This solution is based on PF 6.0, I don't remember if BeanValidationMetadataExtractor is available in previous versions. Anyway, creating a DIY extractor is a simple task.
I had a similar problem. In my specific case:
User should be informed that a certain field (read UIInput) is required
I don't want to repeat required="true" on the comp since it's already bound to a #NotNull/#NotBlank property/field
In my case, a label component may not be present (and I don't like asterisked-labels)
So, here is what I have done:
import java.util.Set;
import javax.el.ValueExpression;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PreRenderComponentEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
import javax.validation.constraints.NotNull;
import javax.validation.metadata.ConstraintDescriptor;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import org.omnifaces.util.Faces;
import org.primefaces.context.RequestContext;
import org.primefaces.metadata.BeanValidationMetadataExtractor;
public class InputValidatorConstraintListener implements SystemEventListener
{
#Override
public boolean isListenerForSource(Object source)
{
return source instanceof UIInput;
}
#Override
public void processEvent(SystemEvent event) throws AbortProcessingException
{
if(event instanceof PreRenderComponentEvent)
{
UIInput component = (UIInput) event.getSource();
component.getPassThroughAttributes().computeIfAbsent("data-required", k ->
{
ValueExpression requiredExpression = component.getValueExpression("required");
if(requiredExpression != null || !component.isRequired())
{
FacesContext context = Faces.getContext();
ValueExpression valueExpression = component.getValueExpression("value");
RequestContext requestContext = RequestContext.getCurrentInstance();
try
{
Set<ConstraintDescriptor<?>> constraints = BeanValidationMetadataExtractor.extractAllConstraintDescriptors(context, requestContext, valueExpression);
if(constraints != null && !constraints.isEmpty())
{
return constraints.stream()
.map(ConstraintDescriptor::getAnnotation)
.anyMatch(x -> x instanceof NotNull || x instanceof NotBlank || x instanceof NotEmpty);
}
}
catch(Exception e)
{
return false;
}
}
return false;
});
}
}
}
and declare it in faces-config.xml:
<?xml version="1.0" encoding="utf-8"?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<system-event-listener>
<system-event-listener-class>it.shape.core.jsf.listener.InputValidatorConstraintListener</system-event-listener-class>
<system-event-class>javax.faces.event.PreRenderComponentEvent</system-event-class>
</system-event-listener>
</application>
</faces-config>
With this listener UIInputs are rendered with a data-required passthrough attribute:
<input
id="form:editPanelMain:j_idt253"
name="form:editPanelMain:j_idt253"
type="text"
value="Rack Assemply"
size="80"
data-required="true" <============================ NOTE THIS!!
data-widget="widget_form_editPanelMain_j_idt253"
class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all"
role="textbox"
aria-disabled="false"
aria-readonly="false">
Now, I use a css rule to highlight these fields:
input[data-required='true'],
.ui-inputfield[data-required='true'],
*[data-required='true'] .ui-inputfield {
box-shadow: inset 0px 2px 2px #bf8f8f;
}
You can adapt this listener to either set the component as required or use another approach that suits your specific needs.
Another approach could be:
listen for UILabels instead of UIInputs
get the UIInput associated with the for/forValue ValueExpression of the label
check the UIInput for validation constraint
eventually invoke UIInput.setRequired(true)
The performance impact is negligible, as I have tested complex pages with ~3000 components.

how to bind an image src to resource drawable image with Mvvmcross?

I'm trying to bind an image's src.
I have tried using MvxHttpImageView like this
<Mvx.MvxHttpImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/iconeView"
local:MvxBind="{'ImageUrl':{'Path':'ImgSrc'}}" />
with
public string ImgSrc
{
get {return "#res/drawable/icon.png"; }
}
I have tried several other ImgSrc and still don't have any result.
icon.png is in my Resources/Drawable directory and is an AndroidResource
any help will be great !
Thanks
Newer versions of MvvmCross support binding to a drawable resources. Using the DrawableName binding you can bind an ImageView to a property on your viewmodel that contains a drawable name.
using System;
using Cirrious.MvvmCross.ViewModels;
namespace MyApp.ViewModels
{
public class UserProfileViewModel : MvxViewModel
{
// set this to the name of one of the files
// in your Resources/drawable/drawable-xxxx folders
private MyDrawable _myDrawable;
public string MyDrawable {
get { return _myDrawable; }
set {
_myDrawable = value;
RaisePropertyChanged (() => MyDrawable);
}
}
}
}
And in your layout
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
local:MvxBind="DrawableName MyDrawable"/>
Alternatively, you could use the Drawable binding if your VM property is an int
The mvxhttpimageview knows how to load images from http and from 'disk'
Sadly, it doesn't know how to load from resources
However, there are ways to get an image to load static content.
You can write you own custom binding
You can use the standard imageview, images stored in android assets and the 'AssetImagePath' binding built into mvx.
To try the first, take a look at the conference sample - at how the favorite button background is bound to IsFavorite
To do the second:
include the icons in the asset folder - e.g. /assets/icon1.png
make sure the build action is set to AndroidAsset
in the XML use a standard ImageView and binding text like {'AssetImagePath':{'Path':'WhichAsset'}}
In real use, I generally also use a converter - something that maps a viewmodel property like State with a value of LoadingState.Loading to an asset image path like '/loadingimages/loading.png'
You can see the code for the asset binding in https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Binding/Android/Target/MvxImageViewDrawableTargetBinding.cs
Sorry answer doesn't include more code - answering on mobile
I built a converter, which converts a drawable name to a Bitmap and bound the Bitmap to the ImageView.
The converter:
public class ImageNameToBitmapConverter : MvxValueConverter<string, Bitmap>
{
protected override Bitmap Convert(string value, Type targetType, object parameter, CultureInfo culture)
{
var topActivity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>();
var bm = BitmapFactory.DecodeResource(topActivity.Activity.Resources, GetResourceId(value, "drawable", topActivity));
return bm;
}
private static int GetResourceId(string variableName, string resourceName, IMvxAndroidCurrentTopActivity topActivity)
{
try
{
return topActivity.Activity.Resources.GetIdentifier(variableName, resourceName, topActivity.Activity.PackageName);
}
catch (Exception)
{
return -1;
}
}
}
The XML view:
<ImageView
local:MvxBind="Bitmap Icon, Converter=ImageNameToBitmap"
android:layout_width="100dp"
android:layout_height="100dp" />
The Icon property I'm binding is a string like: "icon_name" where I put the image icon_name.png in the Android project's Resources/drawable
For latest MvvmCross next solution is actual:
In markup:
<ImageView
android:id="#+id/iconImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_centerVertical="true"
local:MvxBind="DrawableName Type, Converter=TypeToImageStringConverter" />
In converter:
public class TypeToImageStringConverter : MvxValueConverter<VacationType, int>
{
protected override int Convert(VacationType value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
switch (value)
{
case VacationType.RegularVacation:
return Resource.Drawable.Icon_Request_Green;
case VacationType.SickLeave:
return Resource.Drawable.Icon_Request_Blue;
case VacationType.LeaveWithoutPay:
return Resource.Drawable.Icon_Request_Dark;
case VacationType.OvertimeVacation:
return Resource.Drawable.Icon_Request_Gray;
case VacationType.ExceptionalLeave:
return Resource.Drawable.Icon_Request_Plum;
default:
return Resource.Drawable.Icon_Request_Gray;
}
}
}
All sense is that you just must give out a drawable resource id.

Localizing enum values in resource bundle

I have a problem with i18n enums in my JSF application. When I started, I had enums with the text defined inside. But now, I have keys tied to message bundles in the enum.
Example one of my enums:
public enum OrderStatus implements CustomEnum {
PENDING("enum.orderstatus.pending"),
CANCELED("enum.orderstatus.canceled");
/**
* key in message bundle
*/
private String name;
OrderStatus(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
In the view layer, I use something like:
<!-- input -->
<h:selectOneMenu value="#{order.status}">
<f:selectItems value="#{flowUtils.orderStatuses}"/>
</h:selectOneMenu>
<!-- output -->
<h:outputText value="#{order.status}"/>
and in Java:
public class FlowUtils {
public List<SelectItem> getOrderStatuses() {
ArrayList<SelectItem> l = new ArrayList<SelectItem>();
for(OrderStatus c: OrderStatus.values()) {
// before i18n
// l.add(new SelectItem(c, c.getName()));
// after i18n
l.add(new SelectItem(c, FacesUtil.getMessageValue(c.getName())));
}
return l;
}
}
public class FacesUtil {
public static String getMessageValue(String name) {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().getResourceBundle(context, "m").getString(name);
}
}
It worked well, but when I needed to output #{order.status}, I needed to convert it.
So I implemented a converter, but got in trouble with conversion of String to Object in the getAsObject() method.
web.xml:
<converter>
<converter-for-class>model.helpers.OrderStatus</converter-for-class>
<converter-class>model.helpers.EnumTypeConverter</converter-class>
</converter>
Java:
public class EnumTypeConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent comp,
String value) throws ConverterException {
// value = localized value :(
Class enumType = comp.getValueBinding("value").getType(context);
return Enum.valueOf(enumType, value);
}
#Override
public String getAsString(FacesContext context, UIComponent component,
Object object) throws ConverterException {
if (object == null) {
return null;
}
CustomEnum type = (CustomEnum) object;
ResourceBundle messages = context.getApplication().getResourceBundle(context, "m");
String text = messages.getString(type.getName());
return text;
}
}
I'm entangled now with that. Anybody know how to internationalize multiple Enums efficiently?
The value which is passed through the converter is not the option label as you seem to expect, but the option value. The best practice is to not do this in the model side, but in the view side, because the model shouldn't need to be i18n aware.
As to the approach, you're basically unnecessarily overcomplicating things. Since JSF 1.2 there's a builtin EnumConverter which will kick in automatically and since JSF 2.0 you can iterate over a generic array or List in f:selectItems by the new var attribute without the need to duplicate the values over a List<SelectItem> in the model.
Here's how the bean can look like:
public class Bean {
private OrderStatus orderStatus;
private OrderStatus[] orderStatuses = OrderStatus.values();
// ...
}
And here's how the view can look like (assuming that msg refers to the <var> as you've definied in <resource-bundle> in faces-config.xml):
<h:selectOneMenu value="#{bean.orderStatus}">
<f:selectItems value="#{bean.orderStatuses}" var="orderStatus"
itemValue="#{orderStatus}" itemLabel="#{msg[orderStatus.name]}" />
</h:selectOneMenu>
That's all.
Unrelated to the problem, you've typos in the enum name and message keys, it should be:
PENDING("enum.orderstatus.pending"),
CANCELLED("enum.orderstatus.cancelled");
And, more clean would be to keep the bundle keys out the enum and use enum itself as part of bundle key. E.g.
PENDING,
CANCELLED;
<h:selectOneMenu value="#{bean.orderStatus}">
<f:selectItems value="#{bean.orderStatuses}" var="orderStatus"
itemValue="#{orderStatus}" itemLabel="#{msg['enum.orderstatus.' += orderStatus]}" />
</h:selectOneMenu>
enum.orderstatus.PENDING = Pending
enum.orderstatus.CANCELLED = Cancelled
I have posted my solution here: Internationalization of multiple enums (translation of enum values) - but still hoping for further enhancement.
EDIT: with the help of #Joop Eggen, we have come up with a really cool solution:
EDIT again: complete and ready-to-use solution:
Make a class
public final class EnumTranslator {
public static String getMessageKey(Enum<?> e) {
return e.getClass().getSimpleName() + '.' + e.name();
}
}
Make it a custom EL function
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://example.com/enumi18n</namespace>
<function>
<function-name>xlate</function-name>
<function-class>your.package.EnumTranslator</function-class>
<function-signature>String getMessageKey(java.lang.Enum)</function-signature>
</function>
</facelet-taglib>
Add the taglib to your web.xml
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/enumi18n.taglib.xml</param-value>
</context-param>
Have properties files enum_en.properties and enum_yourlanguage.properties like this
TransferStatus.NOT_TRANSFERRED = Not transferred
TransferStatus.TRANSFERRED = Transferred
Add the properties files as resource bundles to your faces-config.xml
<resource-bundle>
<base-name>kk.os.obj.jsf.i18n.enum</base-name>
<var>enum</var>
</resource-bundle>
Add the custom taglib to your xhtml files
<html ... xmlns:l="http://example.com/enumi18n">
And - voilĂ  - you can now access the translated enum values in jsf:
<h:outputText value="#{enum[l:xlate(order.transferStatus)]}" />
Well, enum is just another class. There is nothing stopping you from adding parsing and to-string conversion methods that will parse and output locale-sensitive messages.
Maybe it violates Single Responsible Principle (does it?), but I believe making enum responsible for parsing and returning locale-aware values is the right thing to do.
Just add two methods like this:
public String toString(FacesContext context) {
// need to modify the method
FacesUtil.getMessageValue(context, name);
}
public OrderStatus parse(FacesContext context, String theName) {
for (OrderStatus value : values()) {
if (value.toString(context).equals(theName) {
return value;
}
}
// think of something better
return null;
}
I hope I got the code right, as I am not checking it with IDE now... Is this what you were looking for?
I calculate the message key in the enum like as shown below; so no need to maintain the keys with additional attributes on the enum
public String getMessageKey() {
return String.format("enum_%s_%s", this.getClass().getSimpleName(),
this.name());
}
Then I use it like this
<p:selectOneMenu id="type"
value="#{xyzBean.type}" required="true">
<f:selectItems
value="#{xyzBean.possibleTypes}"
var="type" itemLabel="#{msg[type.messageKey]}">
</f:selectItems>
</p:selectOneMenu>
with having configured a org.springframework.context.support.ReloadableResourceBundleMessageSource in the app context
<bean id="msg"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/resources/locale/messages" />
<property name="useCodeAsDefaultMessage" value="true" />
<property name="cacheSeconds" value="1" />
</bean>
In case anyone is looking for a simple utility library to handle enum internationalization, please take a look at https://github.com/thiagowolff/litefaces-enum-i18n
The artifact is also available in Maven Central:
<dependency>
<groupId>br.com.litecode</groupId>
<artifactId>litefaces-enum-i18n</artifactId>
<version>1.0.1</version>
</dependency>
Basically, you just need to add the artifact to your project and define the enum respective keys following the described enum naming conventions. The translations (and also CSS class names) can be retrieved using the provided EL functions.

Resources