2010-07-23 54 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緩存下控制

相關問題