Runtime Swedish/English Language Switching (Part 1)

At this year's Jfokus in Stockholm I met lots of nice programmers interested in doing enterprise development on the Java desktop with the NetBeans Platform. So, for them, I've been investigating how to create support for runtime switching of locales from/to Swedish/English.

There are a lot of resources on-line to help (such as this entry in Toni's blog), though there isn't one generic way to switch all different UI elements. Each area needs to be investigated and solved in its own way, in some cases you need to create your own special hacks. That's the bad news, but the good news is that ultimately everything should be switchable, I believe.

Ultimately, what I've achieved is shown below, i.e., a drop-down box enabling the user to switch from Swedish to English and back... without requiring a restart of any kind.

The constructor of the JPanel that you see above is as follows:

public LocalizerPanel() {
    initComponents();
    //Set the initial text in the label:
    jLabel1.setText(NbBundle.getMessage(LocalizerPanel.class, "languageText"));
    //Create a hashmap with the language options:
    final HashMap hashMap = new HashMap();
    hashMap.put("English", Locale.ENGLISH);
    hashMap.put("Swedish", new Locale("sv", "SE"));
    MouseListener mouseListener = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
                //Get the currently selected language, on the double-click:
                String selectedlanguage = (String) jList1.getSelectedValue();
                //Set the new language:
                Locale selectedLocale = (Locale) hashMap.get(selectedlanguage);
                Locale.setDefault(selectedLocale);
                //Reset the JLabel, using the new locale:
                jLabel1.setText(NbBundle.getMessage(LocalizerPanel.class, "languageText"));
                //Refresh the menubar, which sets the new language's display texts in the menus:
                Frame main = WindowManager.getDefault().getMainWindow();
                Component[] cs = ((JFrame) main).getJMenuBar().getComponents();
                for (Component c : cs) {
                    Runnable menu = (Runnable) c;
                    menu.run();
                }
                //Set the app's titlebar using the new language:
                main.setTitle(NbBundle.getMessage(LocalizerPanel.class, "appTitle"));
            }
        }
    };
    jList1.addMouseListener(mouseListener);
}

The JPanel is put into the toolbar as follows:

import java.awt.Component;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import org.openide.awt.ActionRegistration;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.awt.ActionID;
import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.Presenter;

@ActionID(category = "Edit",
id = "org.language.switcher.LocaleSwitcherAction")
@ActionRegistration(iconBase = "org/language/switcher/organismIcon.gif",
displayName = "#CTL_LocaleSwitcherAction")
@ActionReferences({
    @ActionReference(path = "Toolbars/File", position = 300)
})
@Messages("CTL_LocaleSwitcherAction=Locale Switcher")
public final class LocaleSwitcherAction extends AbstractAction implements Presenter.Toolbar {

    @Override
    public void actionPerformed(ActionEvent e) {
        //empty, not needed
    }

    @Override
    public Component getToolbarPresenter() {
       return new LocalizerPanel();
    }
    
}

And I have a Bundle.properties file with this content:

OpenIDE-Module-Name=LanguageSwitcher
languageText=Language:
appTitle=Small Program

...while my "Bundle_sv_SE.properties" file is like this:

languageText=Språk: 
appTitle=Lilla Programmet

Both the above are in the main package of the module.

Finally, make sure to download the NetBeans distro relevant to your language. I.e., I discovered a Swedish version of NetBeans IDE, which is the download I used as the basis of the NetBeans Platform application shown above.

Comments:

Nice article. More programmers need to understand how to write translatable programs, which isn't that hard. Programmers needs to externalize strings so we can translate without the need to recompile programs.

This has been done for a long time, about 20-30 years, in Unix/Linux environments. But programmers has just started to be aware of this in MS Windows. So there are a loot of educations needed in this (in both environments).

So it's really good that you publish this.

By the way, propper swedish translation of "Small Program" is "Litet program", without the second capital "P". :)

Posted by A. Jackson on April 22, 2011 at 11:12 AM PDT #

This works only in the special case where I start with --locale sv:SE. If, however, I start with --locale en:GB or whatever invokes the platform's default locale, then switching the menus this way doesn't work.

Posted by ulim on May 17, 2011 at 07:18 AM PDT #

Thank you, however , what if you have a jpanle and some other comonents not in the menu bar??
I have tried this but the error
javax.swing.JLabel cannot be cast to java.lang.Runnable
was thrown.
Would you please make the sample project downloadable.

Posted by guest on May 18, 2013 at 09:33 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today