| Author |
Message |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 27/09/2006 00:00:00
|
kamran
Joined: 27/09/2006 00:00:00
Messages: 1
Offline
|
Hi,
I have a very small application in which I can switch between french and english.
This worked well until I add IceFaces to my project.
when I click on english or frenche, my methode :
SessionBean.setLanguage is asked
and I perform the folowing :
FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
But nothing change in my page on the browser !
Does someone have an idea ?
best regards,
Kamran
| Filename |
SessionBean.java |
Download
|
| Description |
No description given |
| Filesize |
1 Kbytes
|
| Downloaded: |
267 time(s) |
| Filename |
accueil.xhtml |
Download
|
| Description |
No description given |
| Filesize |
1 Kbytes
|
| Downloaded: |
256 time(s) |
| Filename |
faces-config.xml |
Download
|
| Description |
No description given |
| Filesize |
2 Kbytes
|
| Downloaded: |
284 time(s) |
| Filename |
web.xml |
Download
|
| Description |
No description given |
| Filesize |
4 Kbytes
|
| Downloaded: |
212 time(s) |
|
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 04/10/2006 00:00:00
|
philip.breau

Joined: 08/05/2006 00:00:00
Messages: 2701
Offline
|
Hi,
Yes, any programmatic changes to the locale will not take effect until the next page load. An easy workaround for this, if you would like instant dynamic locale changes, is to hold all of your messages in a HashMap, and then reference the map instead of the ResourceBundle directly. On a locale change, just unload the existing HashMap, programmatically change the locale and reload the ResourceBundle, then reload your HashMap. All of the fields will then be instantly updated.
Thanks,
Philip
In your JSF pages reference the HashMap for localized strings:
<h:outputText value="#{bean.messages['welcome']}"/>
In your bean:
private ResourceBundle resourceBundle; //getter,setter
private HashMap messages; //getter,setter
public Bean(){
setLanguage( FacesContext.getCurrentInstance().getViewRoot().getLocale() );
public void setLanguage(String lang){
Iterator iter = FacesContext.getCurrentInstance().getApplication().getSupportedLocales();
Locale supportedLocale;
while( iter.hasNext() ){
supportedLocale = (Locale)iter.next();
if( supportedLocale.toString().equals( locale.toString() ) ){
FacesContext.getCurrentInstance.getViewRoot().setLocale(locale);
resourceBundle = ResourceBundle.getBundle("messages",locale);
initializeMessages();
break;
}
}
}
private void initializeMessages(){
this.messages = new HashMap();
Enumeration enumer = resourceBundle.getKeys();
while( enumer.hasMoreElements() ){
String key = (String)enumer.nextElement();
messages.put(key,resourceBundle.getString(key));
}
}
|
. |
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 17/11/2006 11:48:34
|
pedrong

Joined: 16/10/2006 00:00:00
Messages: 20
Offline
|
Hi Philip,
I did that.
On a session bean's constructor another method is called. The last sets the HashMap with the messages of the user's locale to another bean (named "msg").
But when the user enters for the first time at my site none message is showed.
When I change the drop-down with the languages, which uses the same method called by the constructor I said above, it works and the messages come.
So, the problem is that at the first time, looks the page is rendered before the messages map is referenced by the "msg" bean.
I am using JBoss and Facelets.
Thanks in advance!!
|
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 17/11/2006 12:22:45
|
philip.breau

Joined: 08/05/2006 00:00:00
Messages: 2701
Offline
|
Hi Pedrong,
It might just be that no default locale is being set on your application startup. Try setting the default locale and message bundle in your faces.config:
Code:
<application>
<locale-config>
<default-locale>fr_FR</default-locale>
<supported-locale>en</supported-locale>
<supported-locale>fr</supported-locale>
<supported-locale>en_US</supported-locale>
</locale-config>
<message-bundle>
test.messages
</message-bundle>
</application>
...then in your constructor, feed in the default locale to the change locale method, make sure that you've alway got an actual locale
Code:
public Bean() {
setLocale( FacesContext.getCurrentInstance().getViewRoot().getLocale());
}
public void setLocale(Locale locale) {
System.out.println("new locale: " + locale.toString());
if( this.locale == null || ! locale.toString().equals( this.locale.toString() ) ){
Iterator iter = FacesContext.getCurrentInstance().getApplication().getSupportedLocales();
Locale supportedLocale = null;
while( iter.hasNext() ){
supportedLocale = (Locale)iter.next();
System.out.println("supported locale: " + supportedLocale.toString());
if( locale.toString().equals( supportedLocale.toString() )){
this.locale = locale;
FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
resourceBundle = ResourceBundle.getBundle("test.messages", locale);
initializeResourceBundleMap();
System.out.println("changed locale");
return;
}
}
if( supportedLocale == null ){
System.out.println("could not initialize locale!!!");
}
}
}
Thanks,
Philip
|
. |
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 17/11/2006 15:53:06
|
pedrong

Joined: 16/10/2006 00:00:00
Messages: 20
Offline
|
Hi Philip,
Unfortunelly it did not work.
The code it's almost exactly as yours example.
And with a F5/refresh the messages are showed.
Any ideas?
Thanks!
|
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 17/11/2006 17:12:44
|
philip.breau

Joined: 08/05/2006 00:00:00
Messages: 2701
Offline
|
Hi Pedrong,
Sorry, no other ideas right now. Do you want to post or send in your relevant code to product.support@icesoft.com?
Thanks,
Philip
|
. |
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 20/11/2006 11:26:52
|
pedrong

Joined: 16/10/2006 00:00:00
Messages: 20
Offline
|
Hi Philip,
Here is my code...
There is another problem I found that I will describe.
Configuration at faces-config:
Code:
<managed-bean>
<managed-bean-name>msg</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
An application scoped bean (actualy the only one):
Code:
public class AdCommerceBean {
...
private Map<Locale, HashMap<String, String>> messagesBundle;
...
public Map<String, String> getMessages(Locale locale) {
return messagesBundle.get(locale);
}
...
private void loadMessages() {
FacesContext facesContext = FacesContext.getCurrentInstance();
// MessageBundle configured at faces-config.xml
String messageBundle = getFacesContext().getApplication().getMessageBundle();
if (messageBundle == null) {
return;
}
// A Map which the keys are Locales and the values another HashMap of messages
messagesBundle = new HashMap<Locale, HashMap<String, String>>();
// Gets a list with the supported locales. Configured at faces-config.xml
Iterator<Locale> i = facesContext.getApplication().getSupportedLocales();
while (i.hasNext()) {
Locale locale = i.next();
ResourceBundle resourceBundle;
try {
resourceBundle = ResourceBundle.getBundle(messageBundle, locale);
} catch (MissingResourceException e) {
return;
}
HashMap<String, String> messages = new HashMap<String, String>();
for (Enumeration<String> messagesKeys = resourceBundle.getKeys(); messagesKeys.hasMoreElements();) {
String key = messagesKeys.nextElement();
messages.put(key, resourceBundle.getString(key));
}
messagesBundle.put(locale, messages);
}
}
...
}
The session scoped bean, where the locale is changed:
Code:
...
// constructor
public UserBean() {
setLocale(null);
}
...
private Locale locale;
...
public void setLocale(Locale locale) {
FacesContext facesContext = FacesContext.getCurrentInstance();
Locale newLocale = locale;
if (locale == null) {
logger.debug("Change locale. Null locale informed.");
newLocale = facesContext.getViewRoot().getLocale();
}
facesContext.getViewRoot().setLocale(newLocale);
this.locale = newLocale;
// Gets the messages previously loaded by AdCommerceBean
// the getManagedObject method basicaly returns another bean
AdCommerceBean adCommerceBean = (AdCommerceBean) getManagedObject(ADCOMMERCE);
Map messages = adCommerceBean.getMessages(newLocale);
// Sets the messages to the bean called "msg". It is a handmade i18n
getFacesContext().getApplication().createValueBinding("#{msg}").setValue(facesContext, messages);
}
...
In my page:
the adCommerceBean.supportedLocales is a List<SelectItem> which keys are locale.toString().
Code:
<ice:selectOneListbox value="#{userBean.locale}" size="1" partialSubmit="true">
<f:selectItems value="#{adCommerceBean.supportedLocales}" />
</ice:selectOneListbox>
Before, I had a valueChangeListener and the property was String and not Locale. Now I left only the value property binding and changed the property in the bean to Locale. By doing that, with a converter, everything works fine, but without it, nothing happens... this is a problem, isn't?
So, the real problems are:
This way, the chose locale is not selected on the ice:selectOneListbox. I don't know why, but I debug the converter and its getAsString method is never called (it should be called for the comparision, didn't?)
Well, the main problem here is that the messages are not rendered at the very first time in the site, i.e., when the session is created. But with a F5 they are showed.
|
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 20/11/2006 16:55:32
|
philip.breau

Joined: 08/05/2006 00:00:00
Messages: 2701
Offline
|
Hi Pedrong,
It works if you wrap the HashMap in a session-scoped bean, rather than exposing it directly as a managed bean. I've attached a working example.
Thanks,
Philip
| Filename |
forum-2381.zip |
Download
|
| Description |
Example app for dynamically switching locales |
| Filesize |
8 Kbytes
|
| Downloaded: |
410 time(s) |
|
. |
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 21/11/2006 07:15:11
|
pedrong

Joined: 16/10/2006 00:00:00
Messages: 20
Offline
|
Thank you Philip,
You are really helping a lot!
It worked, although would be much more "elegant" and easer to me use the HashMap directly as a managed-bean, cause before I implemented the i18n using our old buddy loadBundle doing:
Code:
<f:loadBundle basename="messages" var="msg">
Well, but I still have the problem with the converter...
I have a List<SelectItem>:
Code:
private List<SelectItem> supportedLocales;
...
protected void loadSupportedLocales() {
supportedLocales = new ArrayList<SelectItem>();
FacesContext facesContext = FacesContext.getCurrentInstance();
Iterator i = facesContext.getApplication().getSupportedLocales();
while (i.hasNext()) {
Locale locale = (Locale) i.next();
SelectItem selectItem = new SelectItem(locale.toString(), locale.getDisplayName());
supportedLocales.add(selectItem);
}
}
and my SelectOneListBox:
Code:
<ice:selectOneListbox value="#{myBean.locale}" size="1">
<f:selectItems value="#{myBean.supportedLocales}" />
</ice:selectOneListbox>
and my locale converter:
Code:
public class LocaleConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) throws ConverterException {
if (s != null) {
String[] aux = s.split("_");
switch (aux.length) {
case 1:
return new Locale(aux[0]);
case 2:
return new Locale(aux[0], aux[1]);
default:
return null;
}
}
return null;
}
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) throws ConverterException {
if (o instanceof Locale) {
return ((Locale) o).toString();
} else {
return null;
}
}
}
The problem is that although the locale is changed and with it all the messages, the chosen locale is not kept selected.
Debuging the converter I notice that the getAsString method is never called and I believe it should while comparing the values isn't?
Thank you again!!
|
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 21/11/2006 11:57:38
|
philip.breau

Joined: 08/05/2006 00:00:00
Messages: 2701
Offline
|
Hi Pedrong,
How are you hooking up your converter? Have you tried something like:
JSF
Code:
<ice:selectOneListbox value="#{myBean.locale}" size="1" converter="locale-converter">
<f:selectItems value="#{myBean.supportedLocales}" />
</ice:selectOneListbox>
faces-config.xml
Code:
<converter>
<converter-id>locale-converter</converter-id>
<converter-class>LocaleConverter</converter-class>
</converter>
Thanks,
Philip
|
. |
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 21/11/2006 12:03:32
|
pedrong

Joined: 16/10/2006 00:00:00
Messages: 20
Offline
|
Yes i did:
Code:
<converter>
<converter-for-class>java.util.Locale</converter-for-class>
<converter-class>my.LocaleConverter</converter-class>
</converter>
|
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 21/11/2006 12:05:45
|
philip.breau

Joined: 08/05/2006 00:00:00
Messages: 2701
Offline
|
And you're using the converter attribute on the <ice:selectOneListbox>?
|
. |
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 21/11/2006 12:28:59
|
pedrong

Joined: 16/10/2006 00:00:00
Messages: 20
Offline
|
I wasn't... Was leaving only the configuration per class handle it. Now I used the id and the converter attribute and still did not work.
Debugging, only the getAsObject is called...
:(
Thanks
|
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 21/11/2006 14:13:11
|
philip.breau

Joined: 08/05/2006 00:00:00
Messages: 2701
Offline
|
Hi Pedrong,
Perhaps you were still specifying <converter-for-class>, instead of <converter-id>? I've added in your converter and it's working nicely.
Thanks,
Philip
| Filename |
forum-2381.zip |
Download
|
| Description |
Example showing dynamically changing locales with a selection drop down and converter. |
| Filesize |
9 Kbytes
|
| Downloaded: |
282 time(s) |
|
. |
|
|
 |
![[Post New]](/JForum/templates/default/images/icon_minipost_new.gif) 27/11/2006 12:19:52
|
pedrong

Joined: 16/10/2006 00:00:00
Messages: 20
Offline
|
Thank you Philip, but did not worked here.
Using converter-id or converter-for-lass didnt made difference.
The problem may be with the facelets integration... I dont know... The listener is successfully called but the chose locale is not kept selected.
And as I told before, only the getAsObject method in my converter.
I also tried with versions 1.0.1 and 1.5.
Code:
private Locale locale;
public Locale getLocale() {return locale;}
public void setLocale(Locale locale) {this.locale = locale;}
Code:
<ice:selectOneListbox value="#{myBean.locale}" valueChangeListener="#{userBean.changeLocaleListener}" size="1">
<f:selectItems value="#{myAppBean.supportedLocales}" />
</ice:selectOneListbox>
To make my life easer, now I'm using directly the #{view.locale}:
Code:
<ice:selectOneListbox value="#{view.locale}" valueChangeListener="#{userBean.changeLocaleListener}" size="1">
<f:selectItems value="#{myAppBean.supportedLocales}" />
</ice:selectOneListbox>
just for the record... no changes as expected.
I dont know if I doing something wrong or it is actually a bug.
Thank you again!
|
|
|
 |
|
|