Resource Bundles in Depth

Resource Bundles的 奧妙

Resource bundles are implemented in the JDK class java.util.ResourceBundle. The Javadoc for ResourceBundle provides a wealth of information regarding the usage of resource bundles. This document will repeat some of the information in the Javadoc, then explain the text2gui library's own system for creating resouce bundles which provides additional capabilities.

Resource bundles是被實施 於 JDK class java.util.ResourceBundle  。關於resource bundles的用法, Javadoc 為ResourceBundle 提供了豐富的資訊。
在Javadoc裏, 此文件將重覆一些資訊, 為創 造resource bundles提供另外的能力, 然後詳述text2gui library 的自有系統.。


Resource Bundles as Implemented by java.util.ResourceBundle
Resource Bundles 的 實 施 java.util.ResourceBundle

What Resource Bundles Do
Resource Bundles 能 做什麼 ?

Basically, resource bundles are used to provide a map from string keys to values that depend on the desired locale.
基本上, resource bundles 是使用於提供一張圖表, 從詞句得到依照你所想要的地點的價值,.


Resource bundles are usually read in from properties files that look like this:
Resource bundles 通常是從properties的 文件中讀入, 就像下列 如此 ;


key1=value1

key2=value2
# .... '#' starts a comment -- more key / value pairs follow

Assuming the above file backs the resource bundle bundle, a call to bundle.getObject("key1") would return the string "value1".
假 設是 以上的 文件供應resource bundle bundle,程式員召喚 bundle.getObject("key1"), resource bundle bundle 將會送回 詞句 "value1".

Where to Put Resource Bundles

在那裡存放 Resource Bundles ? 

Let's say that the bundle is to be named com.acme.junk.MyResourceBundle. Commonly, the name of the resource bundle has the same name qualifier (com.acme.junk. in this example) as the code that uses it. So presumably, the bundle is going to be used by some class in the package com.acme.junk. Resource bundles are searched by changing all the dots to slashes, then appending the changed name to each path in the class path. Since the path containing the com.acme.junk package is going to be in the classpath when a class in the package is executed, the resource bundle should be saved in the same directory as the class that uses it. Because the file above is a properties file, it should be given the name "MyResourceBundle.properties".

讓我們將 bundle命名為com.acme.junk.MyResourceBundle 。通常的 resource bundles的名字有同樣的命名合格者(在這個例子是com.acme.junk. ).
我們就使用它做為電碼。那麼據推測,  這個bundle將被包裹com.acme.junk裡的一些類型使用。Resource bundles被搜尋,以改變所有小點成叉, 然後在classpath的每個path中添附被更改的名字。因為path包含com.acme.junk 包裹是在classpath 當同類的在包裹被執行, resource bundles應該被保存在用它的類型的目錄。由於文件上面是properties文件, 它應該被命名為"MyResourceBundle.properties" 。

Class Resource Bundles

類型 Resource Bundles
Another way that resource bundles can be created is by compiling a Java class that extends java.util.ResourceBundle. The fully qualified class name must be exactly the same as the name of the resource bundle. For example, we could compile a class named OtherResourceBundle in the package foo.bar. Then we could retrieve the bundle by the name "foo.bar.OtherResourceBundle". The advantage of resource bundles implemented by class files is that they can vend non-string objects for values. The disadvantage is that they must be recompiled whenever changed. For this reason, code that uses the text2gui library will almost always backs resource bundles with properties files.
以其它方式, resource bundles可能被創造是由編輯延伸java.util.ResourceBundle 的Java class。這完全合格類型的名稱必須與resource bundles的名稱是如出一轍。例如, 我們能編輯此類型被命名為OtherResourceBundle 在包裹foo.bar 。然後我們能以"foo.bar.OtherResourceBundle"的名稱來尋回bundle 。以類型實施的resource bundle的好處是 所以它們能提供 非字句的對象為價值。缺點是, 每次改變時它們必得再次編輯 。因此使用text2gui library的電 碼 總是以properties 文件支持 resource bundles。

Retrieving Resource Bundles
尋回 Resource Bundles

How exactly do we retrieve a bundle by name? Using the java.util package, we can call ResourceBundle.getBundle(String name, Locale locale), or simply ResourceBundle.getBundle(String name) if we want to use the default locale. In our above example, the line
我們如何正確的以名稱尋回 bundle ? 以 java.util 的 包裹 , 我們 可以召喚  ResourceBundle.getBundle(String name, Locale locale),
或是假如我們想用原有的地點,可以簡 單的用  ResourceBundle.getBundle(String name).
 

bundle = ResourceBundle.getBundle("com.acme.junk.MyResourceBundle");

will do the trick.
它將會如計而行.

Value Inheritance / Overriding Mechanism
價值繼承/ 凌駕的機制

How does a resource bundle vend different values depending on the locale? It's a bit complicated, but basically, the locale passed to ResouceBundle.getBundle(String name, Locale locale) determines what other bundles to look for. If say, the locale was for Japan, the additional bundles com.acme.junk.MyResourceBundle_ja and com.acme.junk.MyResourceBundle_ja_JP would be also be loaded if present. ("ja" is the language code for Japanese, and "JP" is the country code for Japan). Now a inheritance hierarchy is created:

Resource Bundle怎麼根據地點提供 不同的價值? 它有點複雜, 但基本上, 地點經過ResouceBundle.getBundle(String name, Locale locale)決定在什麼其他的bundles裡尋找。假如說, 地點是為日本, 另外的bundle com.acme.junk.MyResourceBundle_ja 和com.acme.junk.MyResourceBundle_ja_JP 並且會是被裝載,如果它存在("ja" 是語言電碼為日語, 和"JP" 是國家號碼為日本) 。現在是會創造繼承階層:

com.acme.junk.MyResourceBundle_ja_JP
com.acme.junk.MyResourceBundle_ja
com.acme.junk.MyResourceBundle

(Actually this is only a subset of the inheritance hierarchy -- see java.util.ResourceBundle for the real details).
(實際上這只是繼承階層的子集--請看 java.util.ResourceBundle 的 細節)

When a key is looked up with a call to bundle.getObject(), the most specific bundle is checked first. In this case we would check com.acme.junk.MyResourceBundle_ja_JP. If the key is defined, it is returned. Otherwise, it checks the next most specific bundle, com.acme.junk.MyResourceBundle_ja. This procedure is repeated until all the bundles are searched. The general idea is that keys defined in more specific bundles override those defined in less specific bundles. This is a powerful mechanism because it allows locale-specific keys to be overridden while locale-independent keys are inherited.
當我們來以一個召喚  bundle.getObject() 並依據詞句查找, 最特殊的bundle首先被檢查。我們在這種情況下會檢查com.acme.junk.MyResourceBundle_ja_JP 。如果詞句查找被定義了, 它返回。否則, 它檢查下個最特別的bundle, com.acme.junk.MyResourceBundle_ja 。這個做法被重覆直到所有bundle被搜尋過。基本的想法是,詞句被定義在更加特別的bundle, 凌駕那些被定義在較不特別的bundle。這是一個強有力的機制因為它允許當獨立地點的詞句被繼承時,特定地點的詞句 就被凌駕,。


An Example
舉個例子
As an example, we put 3 files in the same directory, which is in our classpath.
我們將三個文件放在同一目錄,它是在我們的類型的路線裡
HelloResourceBundle_ja.properties:

language=Nihongo
hello=Konnichi wa!

HelloResourceBundle.properties:

language=English
hello=Hello!
email=loser@msn.com

Hello.java:

import java.util.ResourceBundle;

public class Hello {
  public Hello() {
      bundle = ResourceBundle.getBundle(getClass().getName() + "ResourceBundle");
  }

  public void sayIt() {
     System.out.println(bundle.getString("language"));
     System.out.println(bundle.getString("hello"));
     System.out.println("from " + bundle.getString("email"));
  }

  public static void main(String[] args) {
     Hello h = new Hello();
     h.sayIt();
  }

  ResourceBundle bundle;
}

Running "java Hello" on a computer in America produces:
使用美國產品的電腦 執行 "java Hello"

ENGLISH
Hello!
from loser@msn.com

This is because no resource bundle are available for "Hello_en" or "Hello_en_US". ("en" is the language code for English). Only the base resource bundle is available, so all values come from there.
這是因為沒有resource bundle是可用的 "Hello_en" 或"Hello_en_US" 。("en" 是語言代碼為英語) 。唯一基本的resource bundle是可用的, 因此所有價值來自那裡。

Running "java Hello" on a computer in Japan produces:
使用日本產品的電腦 執行 "java Hello"

Nihongo
Konnichi wa!
from loser@msn.com

since "Hello_ja.properties" is searched before "Hello.properties". The last line is the same because the email key was not overridden.
從"Hello_ja.properties" 被搜尋在"Hello.properties" 之前; 。最後線是相同的因為電子郵件的詞句並未凌駕。
To get the same effect on any computer in the world, we need to specify that we want the locale for Japan instead of the default locale:
在世界上, 想在任何一台電腦上,得到同樣效果, 我們需要指定, 我們想要的地點為日本代替原地點:


bundle = ResourceBundle.getBundle(getClass().getName() + "ResourceBundle",
  Locale.JAPAN);


Also, notice how the name of the bundle was constructed. We use the fully qualified class name, followed by "ResourceBundle". In this example, this would resolve to "HelloResourceBundle", since the class is in the anonymous package. If we changed the package to com.acme.junk, and assuming we move the  to the corresponding directory, the above line would use the name "com.acme.junk.HelloResourceBundle", as desired. So getting resource bundles like this protects the code from requiring additional changes if you decide to change packages.
並且, 注意怎麼bundle的名稱被建立了.我們使用完全合格的分類名, 被"ResourceBundle" 接著; 。在這個例子, 這會解決"HelloResourceBundle",
 因為類型是在匿名包裝裏。如果我們改變了包裹到com.acme.junk, 和假設我們移動resource bundles向對應的目錄, 上述的線會使用正如你想要的名字"com.acme.junk.HelloResourceBundle", 。如果您決定改變包裹, 如此得到resource bundles像這樣保護代碼免受要求另外的變動。

properties syntax
properties句法
We already created and used resource bundles based on properties files, but actually the syntax is a bit more complicated than just plain text. So that properties files can support text in multiple languages, the properties file is encoded in a special format which allows for escape sequences that describe Unicode characters. In this format, the characters '\', ':', '=', '!'  and '#' must be escaped with a backslash. Also, properties files can contain comments -- lines beginning with an unescaped '#' or '!' are ignored. Here is a snippet that demonstrates the syntax:
我們創造了和已經使用 了resource bundles根據properties 文 件, 但實際上句法比普通的文句更複雜。以便properties文 件可能支持文句在多種語言, properties文件 被輸入在考慮到逃脫序列描述Unicode 字符的一個特別格式。在這個格式, 字符'\', ':', '=', '!' 並且'#' 必須逃脫以斜線。並且, properties文件可能包含評論-- 線開始從unescaped '#' 或'!' 被凌駕。在此這展示句法的小片斷:


# This is a comment. Everything on this line will be thrown away!
truism=2 + 3 \= 5\!

If the above file is used to back are resource bundle, the key "truism" will map to the string "2 + 3 = 5!".
如果上述文件被使用支持resource bundle,  這詞句"truism" 將以"2 + 3 = 5!"表述 。
請看Javadoc 為java.util.Properties 對於更多資訊關於properties句法-- 但注意text2gui 使用輕微地修改過的句法叫的多行的properties, 以後再在來描述。

Here's a hint for i18n developers on Windows systems. It's easiest to enter in foreign text with an Input Method Editor (IME) installed in Windows. A properties file that provides text for a foreign language can initially be edited with Notepad. When saving the file, save using the Unicode (NOT Unicode big endian) encoding. Let's assume you give the file the name "infile.props". Then use the native2ascii utility supplied with the Java Development Kit like this:
在此為i18n 開發者在視窗系統 一個提示。它 最容易進入在外國文本裡與輸入方法編輯(IME) 被安裝在視窗裏。一個properties 文 件為一種外語提供文本可以最初的被用Notepad編輯。當保存文件, 保存使用Unicode (不是Unicode big endian) 內碼。
讓我們假設您授予文件名稱"infile.props" 。然後使用native2.ascii 公用軟體,它是由Java 發展組所提供的,就像這樣:

native2ascii -encoding "UnicodeLittle" infile.props MyResourceBundle.properties

This will output the file "MyResourceBundle.properties" that has the characters in "infile.props", but properly encoded for use by the Java library classes.
這將輸出文件"MyResourceBundle.properties" 那兒有字符在"infile.props", 但是Java library classes 適當的加碼以供使用。

text2gui Extensions to Resource Bundles

Resource bundles are a great idea, but their implementation as is leaves some features to be desired. These features, described below, have been implemented in the text2gui library.
Resource bundles是一個好主意,但他們的實施, 就像葉子的一些特點被渴望, 。在以下描述,這些特點, , 被實施在text2gui library裡。

Extension of the Inheritance Hierarchy
Inheritance Hierarchy的延伸

First of all, the inheritance hierarchy as implemented by ResourceBundle.getBundle() only includes resource bundles with the same base name (HelloResourceBundle in the above example). However, we might want to inherit key / values from a resource bundle with a different name. Such a bundle might contain strings used in a variety of applications, such as "OK", "Cancel", "Yes", "No". Of course, these strings would change depending on the locale passed to the bundle creation method. Let's call this bundle foo.bar.CommonResourceBundle and define it as:
首先繼承階層依照由ResourceBundle.getBundle() 實施,只有包含resource bundles用同樣基本的名字(HelloResourceBundle 在上述例子) 。但是, 我們也許想要繼承詞句/價值從resource resource bundle以一個另外的名字。這樣resource bundle也許包含字句被使用在各種各樣的應用, 譬如"OK", "Cancel", "Yes", "No" 。當然, 這些字句會改變根據地點通過對 bundle創作方法。Let's 叫這bundle foo.bar.CommonResourceBundle把它定義為
:
ok=OK
cancel=Cancel
yes=Yes
no=No

We also have a Spanish version with simple name "CommonResourceBundle_es":
我們也有西班牙版的用簡名"CommonResourceBundle_es":

ok=Acepta
cancel=Cancele
yes=Sí

We need a way for a bundle such as AudioPlayerResourceBundle to inherit the keys of foo.bar.CommonResourceBundle. To do this we set the parentBundle property in AudioPlayerResourceBundle:
我們需要一個方式為bundle譬如AudioPlayerResourceBundle 繼承詞句foo.bar.CommonResourceBundle 。為了做這我們設置parentBundle property在AudioPlayerResourceBundle:

parentBundle=foo.bar.CommonResourceBundle

play.text=Play
# ... more properties here

There is also a Spanish version in "AudioPlayerResourceBundle_es":
我們也有西班牙版的在"AudioPlayerResourceBundle_es":

play.text=Toca
# ... más properties aquí

Now we just need a way to get a resource bundle object that recognizes the parentBundle property and constructs an inheritance hierarchy like this, assuming the desired locale is for Argentina:
我們現在需要一種方式得到認可parentBundle 物產和修建繼承階層像這樣的resource bundle對象, 假設渴望的地點是為阿根廷:

AudioPlayerResourceBundle_es_AR
AudioPlayerResourceBundle_es
AudioPlayerResourceBundle
foo.bar.CommonResourceBundle_es_AR
foo.bar.CommonResourceBundle_es
foo.bar.CommonResourceBundle

com.taco.util.ChainedResourceBundleFactory does just this, so a bundle with this hierarchy can be retrieved by calling
com.taco.util.ChainedResourceBundleFactory 就像這樣做, 因此bundle以這個階層可以召喚招來

bundle = ChainedResourceBundleFactory.DEFAULT_INSTANCE.getBundle("AudioPlayerResourceBundle",
  new Locale("es", "AR"));

Now bundle.getObject("Play") returns "Toca", while  retbundle.getObject("yes")returns "Sí".
現在bundle.getObject("Play")帶回"Toca",retbundle.getObject("yes")帶回 "Sí".

com.taco.util.ChainedResourceBundleFactory also has the ability to create a bundle with a hierarchy specified by string.  The string is composed of bundle names, separated by semicolons. Bundles names occuring earlier in the string have their corresponding bundles checked before bundles specified later in the string. For example,
com.taco.util.ChainedResourceBundleFactory 並且有能力創造bundle,以階層由詞句指定。詞句由bundle名字組成, 以分號分離。
Bundle名字發生早於詞句有他們對應的bundle被檢查在bundle之前,而後bundle詞句被指定。例如,

bundle = ChainedResourceBundleFactory.DEFAULT_INSTANCE.getBundle(
  "AudioPlayerResourceBundle;OtherResourceBundle;com.acme.junk.WastedResourceBundle",

  Locale.TAIWAN);

creates a hierarchy like this:
創造一個階層像這樣:
AudioPlayerResourceBundle_zh_TW
AudioPlayerResourceBundle_zh
AudioPlayerResourceBundle
foo.bar.CommonResourceBundle_zh_TW
foo.bar.CommonResourceBundle_zh
foo.bar.CommonResourceBundle
OtherResourceBundle_zh_TW
OtherResourceBundle_zh
OtherResourceBundle
com.acme.junk.WastedResourceBundle_zh_TW
com.acme.junk.WastedResourceBundle_zh
com.acme.junk.WastedResourceBundle

Note the appearance of foo.bar.CommonResourceBundle even though it wasn't specified in the string. The parentBundle property is still respected. foo.bar.CommonResourceBundle and its locale-specific friends are considered part of AudioPlayerResourceBundle so it is checked before bundles later in the string. 
注意foo.bar.CommonResourceBundle 出現即使它不是 被指定在詞句裏。parentBundle 物產仍然是受尊敬的foo.bar.CommonResourceBundle 並且它的地點具體朋友們被認為是一部分的AudioPlayerResourceBundle 因此它被檢查在bundle之前而在詞句之後。

The parentBundle property also may be set to a ';' separated list of resource bundles, to get multiple inheritence. If multiple resource bundles inherit from a common resource bundle, each common resource bundle will only be searched once. Also there is no danger of infinite recursion if a bundle inherits from itself, directly or indirectly.
parentBundle property 也許還被設置對';' resource bundles被分離的名單, 得到多繼承 。如果多種resource bundles繼承從普遍的resource bundle, 各個普遍的resource bundle只將被搜尋一次。並且如果是bundle繼承從本身,沒有直接地或間接地無限遞歸的危險 。

Support for Different Implementations of ResourceBundle
對於不同的ResourceBundle實施的維護
Another limitation of ResourceBundle.getBundle() is that there are only two ways that a resource bundle can be loaded
其它ResourceBundle.getBundle() 局限是, 只有二種方式resource bundle可能被裝載::
  1. By finding a properties file
  2. By finding a Java class
   1.以找尋properties文 件
   2. 以找尋Java 類型
Furthermore, the syntax for a properties file is not ideal for code segments. In the syntax, every property value that takes multiple lines needs to use a line continuation marker '\' as the very last character on each line before the last one. Because the text2gui library relies heavily on BeanShell scripts and many other long strings as property values, the ordinary properties file syntax would be overly burdensome to the programmer. A modification of the properties file syntax was created, called multi-line properties. The multi-line properties syntax is different from the properties syntax in two ways:
此外, 句法為properties文件不是理想的為代碼部分。在 句法, 採取多行需要使用一行繼續標誌 '\'  的每個物產價值; 作為最後字符在各行在最後一個之前。由於text2gui library沉重依靠BeanShell 腳本和許多其它長的字句當物產價值, 普通的 properties文件句法對程式員是沉重的負擔。 properties文件句法的修改被創造了, 叫多行的物產。多行的properties句法是與properties句法不同於二種方式:

  1. If a property value ends the line within a Java braced context (inside an unclosed ", ', (, {, or [), the next line is automatically concatenated with the last line. This process continues until all Java punctuation has been closed. Of course, brace characters that occur in a quoted or commented context are not treated as changing the brace level. Also, a brace character can be escaped with a backslash ('\') to indicate that it does not start a braced context .
  2. If a non-escaped backslash ('\') is detected, and only whitespace follows it, it will be treated as a line continuation marker. This alleviates the frustration of ensuring the backslash is the very last character of a line that is followed by another one.
  1. 如果物產價值結束這行在Java 支撐上下文之內(裡面unclosed ", ', (, {, 或[), 下一行自動地以最後行被連擊。這個過程繼續直到所有Java 標點被結束 了。當然, 發生在被引述的或被評論的上下文的括號字符不以改變括號標準。並且, 括號字符可能以斜線('\') 表明免除, 它不開始支撐上下文。
  2. 如果一條非逃脫的斜線('\') 被查出, 並且唯一空白 跟隨它, 它將視為一行繼續標誌。這緩和保證斜線的無效是最後一行的字符那是 跟隨在另外一行。
These two modifications make writing multi-line property values considerably easier. Now we can write:
這兩種修改使文字多行的物產價值可觀地更加容易。現在我們能寫道:

okButton.actionListeners.0={

  return new ActionListener() {
    public void actionPerfomed(ActionEvent event) {
      // Assume the dialog that this button belongs to is in the global "dialog".
     
getGlobal("dialog", argMap).dispose();
    }
  };
}

which would use the entired contents of the braces, including the braces themselves, as the property value for the okButton.action key, because the string remains in a braced context until the last line.

By default, com.taco.util.ChainedResourceBundleFactory interprets properties files it finds using com.taco.util.MultiLineProperties, which supports the multi-line syntax described above.
那些會使用括號的整體內容, 包括括號, 做為物產價值為okButton.action 主體, 因為詞句保留在支撐上下文直到最後一行。
依常規, com.taco.util.ChainedResourceBundleFactory 闡釋properties文件,它發現是使 用com.taco.util.MultiLineProperties,
上面被描述過它 支持多行的句法,.

If you have existing properties files, the vast majority of them will be interpreted in the same way using the multi-line syntax. The only problem to watch out for is lines containing unclosed opening brace characters, which will make the lines after them all be part of the same property value, until a closing brace character is found. To work around this, escape brace characters with a backslash ('\') if you don't want them to start a braced context.
如果您有現有的properties文件, 大多數他們將被解釋相似使用多行的句法。唯一的問題提防是包含沒關閉的 開頭括號字符, 將做在他們以後全部是同樣物產價值的一部分的一行, 直到一個關閉的括號字符被發現。想避開這問題, 以斜線('\') 逃脫括號字符,如果您不 要他們開始括號的內文。

The resource bundle factory classes in the text2gui also provide support for an additional implementation of ResourceBundle: one based on javax.swing.UIManager, which holds icons, borders, etc. for the current UI. This resource bundle contains all key / value pairs in UIManager, for which the key is a string. To retrieve this bundle, use "UIManager" as the bundle name.
這個resource bundle工廠類型在text2gui 並且為ResourceBundle提供支持另外的應用: 你根據了javax.swing.UIManager, 它持有小圖像、邊線等 等,
為當前的UI 。這resource bundle包含所有詞句或是/價值成 對的在UIManager中, 詞句是詞句。在此詞句就是詞句.想要檢索這bundle,使用"UIManager" 作為bundle的名稱.

Finally, through subclassing, it is possible to provide your own implementation of ResourceBundle based on a name. One application of this ability might be to provide an implementation of ResourceBundle based on key / values defined in an XML file, if the properties syntax does not suit you. See the Javadoc for com.taco.util.ResourceBundleFactory._loadOrphanBundle() for details on how to do this.
終於, 通過次類型, 它是可能提供您自己 以名稱為根據,ResourceBundle的應用。這能力的一種應用也許將提供ResourceBundle 的實施根據詞句或/價值被定義在XML 文件, 如果properties句法不適合您。關於怎樣對做這, 請看Javadoc 為com.taco.util.ResourceBundleFactory._loadOrphanBundle() 的細節。

Bundle Cache Invalidation

Bundle Cache 的失效
A feature built into java.util.ResourceBundle.getBundle() is resource bundle caching. That is, if a bundle name is requested more than once, the same bundle is returned. This avoids the expensive process of reloading the bundle, which may involving parsing a file or loading a class. This is normally a good thing, but consider an application whose GUI is defined by a resource bundle. While it's running, once it loads the bundle, that bundle cannot change. If the application allowed the user to upgrade its interface by specifying overwriting the file backing the bundle, or if a programmer edited the file backing the bundle, those changes cannot take effect until the application was restarted.
一些功能被建立入java.util.ResourceBundle.getBundle() 是resource bundle caching。那是如果bundle名字被請用多於一次, 同樣的bundle返回。這樣避免再裝bundle的昂貴的過程, 它可以介入解析文件或裝載類型。這通常是一件好事, 但考慮GUI 由resource bundle定義的應用。當它在執行時, 一旦它裝載bundle, bundle無法改變。如果應用允許用戶升級它的交接,由指定重寫文件以支持bundle, 或如果程式員編輯了這文件以支持bundle, 那些變動就無法採取作用直到應用被重新開始了。

The text2gui library's resource bundle factories also cache resource bundles, but they allow the bundle cache to be invalidated, so that the next load of a bundle re-reads the file backing the bundle. This can be done by calling ChainedResourceBundleFactory.invalidateBundles(). Now that bundles can replaced at run-time, applications can upgrade themselves without restarting.
這個 text2gui library 的 resource bundle工廠並且貯藏resource bundle, 但他們允許 bundle貯藏所失效, 以便下個裝載的 bundle再讀文件以支持 bundle。這可以召喚 ChainedResourceBundleFactory.invalidateBundles()做到 。現在 bundle能替換在執行時間, 應用可能自己升級不必重新開始。

Summary
結論
Resource bundles are a powerful way of providing values at runtime. Values can easily be overridden depending on the locale, so resource bundles are an ideal solution to internationalization problems. With the extensions in the text2gui library, several bundles can be combined in a structured way and alternate syntaxes for describing bundles can be supported. One extremely useful alternate syntax, multi-line properties, is already built into the text2gui system for loading bundles. com.taco.util.ChainedResourceBundleFactory is the only class that most programmers will need to access these features.

Resource bundles是在運行時間時以一種強有力的方式提供價值。價值能很容易的因地點而被凌駕, 因此 resource bundles 是一種理想的解決國際化問題的答案.在於擴展在text2gui  library裡, 幾種bundles可能被結合用在一個構造的方式和選擇句法為描述bundles是可以被支持的。有個很有用的選擇句法, 多行的properties, 已經被建立入text2gui 系統為com.taco.util.ChainedResourceBundleFactory 是唯一的類型. 多數程式員將需要使用這些功能的裝載bundles。