2010-07-23 164 views
6

我确定有很多方法,但是对于对代码影响最小的推荐方法是什么?国际化Java Swing桌面应用程序的最佳做法是什么?

显而易见的是您创建属性文件,但如何交换渲染中的值?在J2EE中,您总是重新渲染整个页面,所以很容易。但是在Swing应用程序中,是否只需在paintComponent(Graphics g)方法中添加.getProperty()的代码?

如果是这样的话,不就显得沉重,因为现在你将不得不到处覆盖这个方法,其中之前,你并不需要...

附加:你如何设置一个通知系统来重新渲染所有当前可见的组件而不强制某种注册模式?

我想,如果我覆盖的paintComponent(图形g)所有我需要做的就是触发事件的东西已经改变和的paintComponent(图形G)方法将被称为...

+1

最简单的方法:让用户重新启动程序,以使更改生效。 – Untitled 2012-11-26 06:41:53

回答

1

我想出的唯一解决方案是创建一个将需要重新绘制所有组件的大规模注册表。然后,如果拨打电话切换区域设置,您可以调用注册表,它将通过所有注册的组件并调整它们的值。因此,例如对所有注册的JLabel它会做一些沿着将区域设置密钥存储在组件ActionCommand的

for(JLabel specificJLabel : REGISTRY.registeredJLabels) 
{ 
    String localeKey = specificJLabel.getActionCommand(); 
    specificJLabel.setText(ResourceBundle.getString(localeKey)); 
} 

线。然后,无论当前正在呈现哪个屏幕,主父面板都负责重新呈现它。另外这种方式注册表不必管理Locale密钥,这些都与注册表完全分离。每个组件负责管理它自己的ResourceBundle的区域设置密钥。

0

你需要的是一个ResourceBundle,允许您拥有基于Locale的属性文件,您只需像属性文件那样访问它。

Here is a sample on how to do it

+1

我明白,这不是真正的问题。问题是你在哪里调用组件中的ResourceBundle,以便在需要时呈现(或重新呈现)它。是否有另一种方法,而不是覆盖每个JComponent上的paintComponent(Graphics g)? – 2010-07-23 20:50:26

+0

@Stephane Grenier - 通常用户在不同的国家启动一个程序,并且需要基于他所在语言环境的不同语言。因为在示例中您正在添加I18的东西,所以它将会很难。您需要更改语言环境,并至少关闭窗口并重新创建它,或者根据窗口小部件调用setText()或其他。 – 2010-07-23 21:06:26

+0

不幸的是,我需要能够做到这一点,这是为我正在工作的自助服务终端应用程序。我想我可以通过重写paintComponent方法并仔细考虑来做到这一点。我只是希望有一个更简单的方法。 – 2010-07-25 15:30:41

1

支持动态语言的变化是一个棘手的问题。最简单的解决方案是组织您的用户界面,以便您可以重新创建任何可见的面板。这避免了需要注册或更新组件,当语言改变时,您只需重新创建视图。

显然你失去了所有可见组件的状态,这可能是一个问题 - 但是在页面刷新时,这通常与Web应用程序中的相同。

3

据我所知,一些应用程序使用布局/组件建设者(由卡斯滕Lentzsch共同领导建议,并JGoodies API的一部分)。这些构建者包括用于本地化组件的代码(使用引擎盖下的ResourceBundle)。

其他人(包括我在内)更愿意注资;这通常是最不具侵入性的方法。这是Swing Application Framework(JSR-296)和其他GUI框架如Guts-GUI所选择的方式。

您可能还想看看this question,它与您的非常相似。我认为在使用资源注入时实现起来比较容易(我已经在Guts-GUI中实现了它,Swing应用程序框架也可能拥有它,但是我也可以使用它)但是,我不确定)。

Java没有办法倾听Locale的变化,因此您必须创建您自己的“语言环境服务”(任何语言环境变更请求应该针对的地方)。在此服务中,您必须枚举所有可见的窗口(这可以通过Window.getWindows()进行,无需在之前注册可见组件),然后再次注入资源。

如果你想要一个例子,看看在resourceGuts-GUI source code

  • ResourceInjector显示资源注入和方法来改变Locale,它发送一个通知事件(使用一个事件总线为,但简单的听众将被罚款太)这个变化
  • WindowController听的语言环境变化事件

更新所有可见的窗口有趣的代码复制以下简称:

for (Window window: Window.getWindows()) 
{ 
    if (window.isVisible()) 
    { 
     injectResources(window); 
     window.repaint(); 
     if (window instanceof RootPaneContainer) 
     { 
      ((RootPaneContainer) window).getRootPane().revalidate(); 
     } 
    } 
} 
1

的Java SE 6可以让你重新加载在飞行资源包。 只需拨打ResourceBundle类的clearCache()静态函数即可。 然后再拨打getBundle()

this article缓存下控制

相关问题