I've created an app in two languages. The second one (english), is used when user's default system language is english. If it's not, then the first one is used.
I want to set the second language (that's english) as a DEFAULT language,
which means that when user opens my app and his system language is not the first one, nor English, the English language will appear as a default one.
I tried:
Locale locale = new Locale("en_US");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getApplicationContext.getResources().updateConfiguration(config, null);
But got "context cannot be resolved" error everytime.. Is this piece of code right or..?
Okay,
to make everything clear,
I realized res/values is a DEFAULT directory and the others are just "in case of language". So everything I had to do was to switch the english to /res/values and the other language goes to res/values-es
You should define all languages you support using res folders, i.e res/values, res/values-en, res/values-fr. The system will take care of everything else, you don't need any code.
If you are in an activity you can do:
this.getApplicationContext().getResources().updateConfiguration(config, null);
...to fix your error.
Otherwise you need to pass in the context.
Make sure you add the parenthesis at the end of getApplicationContext(). You didn't do so in your code.
I've been in the same situation, my app was first created in portuguese (BR) so we went global and I had as second language En-Us, so my solution was creating a new language ( clicking in translation Editor + Brazil )... so I have my default language (Portuguese) second (English) third (Portuguese)
then I replaced the resource/ values to the english strings setting as default...
Related
I've created a I18NBundle and some .properties files containing the strings. To create the bundle i wrote this:
baseFileHandle = Gdx.files.internal("Language/Lang");
da_DK = new Locale("da", "DK");
en_GB = new Locale("en", "GB");
Lang = I18NBundle.createBundle(baseFileHandle, en_GB);
This works perfectly well, and I can extract the values from the bundle to get my strings, and it also works by using da_DK instead of en_GB when i initialize the bundle.
My proplem is that I want to be able to change the language in game by pressing a button, but I have no idea how to do that.
I've googled the problem, but cant seem to find an answer.
I hope that you understood my problem, and that you can help me :)
If you have a look at the code (I18NBundle.setLocale(...), which is a private method) you will see this JavaDoc:
Sets the bundle locale. This method is private because a bundle can't change the locale during its life.
That means, what you want to do is not possible. What you can do of course, is creating a new I18NBundle supplying another Locale to the constructor and basically just replacing the current one. In case you are using an AssetManager to load it, this is also possible, you would just need to unload it and then load it once more with different parameters.
I have a Java Desktop App, the users of the application have the availability to set the aplications language.
By now i manage it in the database, i call the value of a field called - userLanguage - which is an Integer, and when the user has logged in depending on this value i set the corresponding text to each element on the app by using a switch ( case 1: set labels text ENGLISH, case 2: set labels text SPANISH ... etc)
But i've heard that control the language from the database is an insult, and i would like to know which's a nice way to do it, or what's the best way to do so, it doesn't matter how difficult it would be but the efficence of the method to internationallize an app is what metters for me.
I would actually handle this problem using the Java Preferences. It keeps the preferences for each user separately in a system independent way (for you at least). If you use XML you need to create a SAX/DOM parser or if you use a DB you need to use jdbc. Neither XML or the DB is a bad or a tough solution, I just think the preferences are the easiest.
For internationalization, I would use a ResourceBundle that localized for different Locales. It is a pretty big topic see The Java internationalization (I18n) tutorial
Java Preferences is what you are looking for then.
Or, instead of using XML file you can use Properties.
...i've heard that control the language from the database is an insult...
I do not agree with that. I think it is scenario dependent, and in your case I think you should keep it the way it is to avoid unnecessary work, unless there is an absolute need for keeping the preferred idiom outside your DB.
You've received two answers, both of which are plainly wrong. If you have Java Desktop Application, you should this code:
Locale locale = Locale.getDefault(Locale.Category.DISPLAY);
This will give you valid User Interface language for your application - the one user set in his OS preferences. If you want to keep the language in a database or in some kind of preferences, you'll be forcing users to chose language. What for? I've already set what language I want. If you don't have it, let Java fall back to your application's default.
In case you wonder, if you use ResourceBundle, the default would be the one without a Locale in its name. That is unless you override this process by using custom ResourceBundle.Control.
I got one application that can switch language between English and Germany. When in Germany language i want the currency display will auto convert into German format. Therefore in my program i have to do checking for the locale then convert the currency based on the language selected. I choose to use locale.setDefault() but i not sure whether this will has any risk or not based on below statement which i found. Can somebody advise for this?
Statement:
"Since changing the default locale may affect many different areas of functionality, this method should only be used if the caller is prepared to reinitialize locale-sensitive code running within the same Java Virtual Machine."
Thanks.
That warning means that if you've already had code that initialized based on a different locale, then it won't magically hear about the locale change and update. For example, if you already set up your title bar and menus and button labels in English and then call setDefault(Locale.GERMANY), all of the text will still be in English. Your example sounds like you won't be changing the locale after startup, so just make sure that you call setDefault early, before you do anything that depends on the locale.
In my application, I'm using java resource bundle for the translation of its labels.
I currently have two files:
resources.properties with labels in English (default language)
resources_fr.properties with labels in French
Then, I load the bundle properties with the following command:
ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME, locale);
... where locale is the user's locale.
When I'm working with a French web browser, that's ok, I'm getting all my messages in French, as my locale is correctly set to fr.
But when I switch my browser to English US, they're still in French!
The locale variable is correctly set with the en_US locale, but the getBundle method returns me a bundle with the fr locale instead of just returning the default bundle...
Is it a normal behaviour? I'm very surprised, as I was expecting the English values of resources.properties to be used when the locale has no specific resource bundle attached to it (like French)...
It is the normal result, which is nevertheless quite surprising if you haven't read the (rather lengthy) description of getBundle carefully. The important part is:
If no matching resource bundle is found, the default control's getFallbackLocale method is called, which returns the current default locale. A new sequence of candidate locale names is generated using this locale and and searched again, as above.
This is a bit unexpected. Only after having tried with the default locale in addition to the specified locale, the method does what you would expect:
If still no result bundle is found, the base name alone is looked up.
This is a reasonable behavior for a desktop application. After all, if you have succeeded in starting a Java application given the machine's default locale, you should know how to handle the application if it comes up using the default locale instead of the one that you have specified. But if your application is a web server and the server's locale is used instead of the preferences that you have specified in your browser, the resulting page can be quite a puzzle.
The proper way to handle this is to suppress the usage of the fallback locale. You could do this in your code by specifying the additional argument ResourceBundle.Control.getNoFallbackControl(ResourceBundle.Control.FORMAT_DEFAULT), resulting in
ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME, locale,
ResourceBundle.Control.getNoFallbackControl(
ResourceBundle.Control.FORMAT_DEFAULT));
(I usually define a constant for the additional argument somewhere when I need this more than once.) This results in the behavior that you were expecting.
This might help to clarify your question:
http://docs.oracle.com/javase/tutorial/i18n/resbundle/propfile.html
These Locale objects should match the properties files created in the
previous two steps. For example, the Locale.FRENCH object corresponds
to the LabelsBundle_fr.properties file. The Locale.ENGLISH has no
matching LabelsBundle_en.properties file, so the default file will be
used.
I am automating test cases for a web application using selenium 2.0 and Java. My application supports multiple languages. Some of the test cases require me to validate the text that appears in the UI like success/error messages etc.I am using a properties file to store whatever text I am referring in my tests from the UI, currently only english. For example there is locale_english.properties(see below) that contains all references in english. I am going to have multiple properties files like this for different locales like locale_chinese.properties,locale_french.properties and so on. For locales other than english, their corresponding properties file would have UTF-8 characters (e.g \u30ed) representing the native characters(see below). So If I want to test say Chinese UI, I would load "locale_chinese.properties" instead of "locale_english.properties". I am going to convert the native characters for non-english locale using perhaps native2ascii from JDK or some other way.I tested that Selenium API works well with UTF-8 characters for non-english locales
---locale_english.properties------
user.login.error= Please verify username/password
---locale_chinese.properties------
user.login.error= \u30ed\u30ef\u30eg\u30eh\u30ed
and so on.
The problem is that my locale_english.properties is growing and going out of control. It is becoming hard to manage a single properties file for one locale let alone for multiple locales. Is there a better way of handling localization in Java, particularly in situations like I am in?
Thanks!
You're right that there is a problem managing the files, but you're also right that this is the best approach. Some things are just hard :-(
Selenium (at least the Selenium RC API) does indeed support Unicode input and output, we have lots of tests that enter and confirm Cyrillic and Simple Chinese characters from C#. Since Java strings are Unicode at the core (just like C#), I expect you could simply create the file in a UTF-8-friendly editor like Notepad++ and read them straight into strings and use them directly in the Selenium API.
This is how I solved the issue for those who are interested.
a database would work better for many reasons, like growth, central location, kept outside of app and can be edited and maintained outside of app. We used a table with columns:
id (int) auto increment
id_text -- this and other columns are varchar ... except for date time for last 2
lang
translation
created_by
updated_by
created_date
updated_date
An id is a short english description of the text - like 'hello' or 'error1msg', the key in your map.
In java had a function to get the text for a particular text ... and a app level property - default language (usually en but good to keep it configurable)
Function would scan already loaded hashmap for language asked for - say "ch"
If corresponding translation was not found for this language we would return the default language translation and if that was not founf then we would return "[" + id "]" so the tester knows something is missing in data base - can go to web screen to edit translation table and add it.