How to implement multilingualism in Java / Swing applications?

What are the different ways to implement multilingual support in Swing applications?

Do you use a ResourceBundle with a properties file and implement it in every frame? Does this work well for you? What if you use some kind of graphic editor? Is there another way?

At work, we use Matisse4MyEclipse, and the code is restored every time we save the screen, so we won’t just use Externalize Strings here. One way is to define it as a custom property for each component, which is very annoying. Another way is to list the multilingual components and their properties again after generating the code with matisse, which is also a pain.

+5
source share
4 answers

Well, you should have used ResourceBundle with. But if you set the component text property, instead of readable text, use the text for RB.getString() . Then, if Matisse is restored from the form, the package key will remain, and localization will work. Example:

I will use this image from the Matisse pages:
Illustration
(source: myeclipseide.com ) .

there you can see the text property. There is a value of "My new tag." Instead, you can use rb.getString("myNewLabel.my.message") , where rb is a ResourceBundle . The only problem should be an overly intelligent property editor that goes against you. I never work with any wysiwyg editor (personal preferences, I always do the interface design manually).

+7
source

Here's how I implemented internationalization:

  • provide a name for each component that has internationalized text
  • at runtime, grab a container (frame, dialog, applet), iterate over all components, and build the i18n key for each component using its name and all parent names.
  • for each type of component (JTextField, JLable, etc.), some keys are defined for each internationalization field (text, label, tooltip, etc.).
  • take this i18n key and request your ResourceBundle, take the results and fill in the component fields.

It works with generated code or with manually generated code.

Edit: Here it is:

 public void buildIds() { buildId(true); int count = getComponentCount(); if (count == 0) { return; } for (int i = 0; i < count; i++) { Component component = getComponent(i); if (component instanceof AbstractComponent) { ((AbstractComponent) component).buildIds(); } } } protected void buildId(boolean fireChange) { String prevId = this.id; String computedId; if (getName() == null) { computedId = ClassUtilities.shortClassName(getClass()).toLowerCase() + "_" + Long.toHexString(ID_GENERATOR.getAndIncrement()); } else { java.util.List<Component> parents = null; Component parent = getParent(); if (parent != null) { StringBuilder buider = new StringBuilder(80); parents = new ArrayList<Component>(); while (parent != null) { if (parent.getName() != null) { parents.add(parent); } parent = parent.getParent(); } Collections.reverse(parents); if (parents.size() > 0) { for (Component component : parents) { if (buider.length() > 0) { buider.append('.'); } buider.append(component.getName()); } buider.append('.'); } buider.append(name); computedId = buider.toString().toLowerCase(); } else { computedId = name; } } this.id = computedId; if (fireChange && prevId != null && !prevId.equals(computedId)) { componentIdChanged(this, prevId); } } 
+3
source

I do not know of any other way than ResourceBundle.

Why are you continuing to recover the code? I would suggest that it would be nice if you start the page, but after that it would be pretty much unnecessary. Code generation seems to be your real problem. It does not save anything.

Are you trying to compose pages from multiple components? I can imagine a common header, footer, and menu that shouldn't have changed all the time. This may be a design issue.

Spring has very good support for I18N. Maybe this can help you here.

0
source

Use the ResourceBundle class and set the locale language:

Below is the code in Java

 private static Map<String, ResourceBundle> resourceBundles; private static ResourceBundle loadBundle(String language) { if (resourceBundles == null) { resourceBundles = new HashMap<String, ResourceBundle>(); } ResourceBundle currentBundle = resourceBundles.get(language); if (currentBundle == null) { Locale locale = new Locale(language); currentBundle = ResourceBundle.getBundle("i18n.Messages", locale); resourceBundles.put(language, currentBundle); } return currentBundle; } public static String messageForKey(String key, String language) { ResourceBundle currentBundle = loadBundle(language); return currentBundle.getString(key); } 
0
source

All Articles