English French

Creating international applications

Allowing to a application to be easly used by a foreigner, to cross the language border might seem to be hard to do. But java provide some help in this task. To have an international graphical application we need to modify all buttons and labels, and also menus...

This could be done either :

In both case we will use a ResourceBundle that could be loaded in the following way :

ResourceBundle myResources =
ResourceBundle.getBundle("MyResources", currentLocale);

Once we have this new object, we need to apply the getString(String ) method to get the required translation. By changing the local of the system we could get different languages. But to do this we need to reload the whole application. This might not satisfy the end user. So we have to change the title of all component when the application is running. This could be done by registring all component. This might seem to be difficult, but it's not that's much. In fact the graphical component are organized like a tree, so we have only to run over this tree in order to register all component one after the other automatically.

Swing component could contain some other components, because the component are themself also Containers. We are going to concidere that the application was develloped so that only JFrame and JPanel contain other graphical component ( but this is not a requirement ).

In order to run over the whole tree of graphical component we have to use two very useful methods of the Containers :

The JFrame has two groups of components, the normal one : a JFrame is also a Container, but also one that could be obtained with the getContentPane() call. The kind of the objects are indentified with the instanceof instruction. The build method use a java.awt.Component as argument, so all graphical component could go in this method, but only the one that the method knows will be treated : we are testing the kind of the objects.

Storing the objects is done in a associative array, the key is the string that is contained in the component like we declare it. We use recursif call to build in order to detect all components : when we detect a component that contain other component we call on each of this sub component the build method. The component that could have a title are only ( up to now ) JLabel and JButton. We add them the the array that is contained in the associative array. We do so because several component could have the same name ( and so also the same translation ).

Once the component are registred, the reload method will run over all keys of the associative arrays, and then to run over the array to which the key are associated. For each element we meet we update the title, getting the new title from the language bundle.

File to download

LangChanger.java : java class to make a demonstration of what I told
LangChanger_fr.properties : French messages
LangChanger_en.properties : English messages

To conclude

We could be intersted in some extra features, for instance also updating the tool tip box, the menu items from the JFrame. We need to attache the component to the structure using the build method on each of the extra component that are not attached to the main component. This could cause some problems because we need also to unregister them once we don't use them anymore. This could be quite problematic because if we keep the element in the associatif array, we will not allow the graphical component to be fully removed from the memory. So we have also to find out a way to unregister components, that are no longer in use.