Path: blob/master/src/demo/share/jfc/SwingSet2/TextAndMnemonicUtils.java
41149 views
/*1*2* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions are met:6*7* - Redistributions of source code must retain the above copyright notice, this8* list of conditions and the following disclaimer.9*10* - Redistributions in binary form must reproduce the above copyright notice,11* this list of conditions and the following disclaimer in the documentation12* and/or other materials provided with the distribution.13*14* - Neither the name of Oracle nor the names of its contributors may be used to15* endorse or promote products derived from this software without specific prior16* written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"19* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE22* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR23* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF24* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS25* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN26* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)27* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE28* POSSIBILITY OF SUCH DAMAGE.29*/3031import java.io.IOException;32import java.util.Properties;33import java.util.ResourceBundle;3435/**36* <code>TextAndMnemonicUtils</code> allows to extract text and mnemonic values37* from the unified text & mnemonic strings. For example:38* LafMenu.laf.labelAndMnemonic=&Look && Feel39* The extracted text is "Look & Feel" and the extracted mnemonic mnemonic is "L".40*41* There are several patterns for the text and mnemonic suffixes which are used42* in the resource file. The patterns format is:43* (resource key -> unified text & mnemonic resource key).44*45* Keys that have label suffixes:46* (xxx_label -> xxx.labelAndMnemonic)47*48* Keys that have mnemonic suffixes:49* (xxx_mnemonic -> xxx.labelAndMnemonic)50*51* Keys that do not have definite suffixes:52* (xxx -> xxx.labelAndMnemonic)53*54* @author Alexander Scherbatiy55*/56public class TextAndMnemonicUtils {5758// Label suffix for the text & mnemonic resource59private static final String LABEL_SUFFIX = ".labelAndMnemonic";6061// Resource bundle for internationalized and accessible text62private static ResourceBundle bundle = null;6364// Resource properties for the mnemonic key defenition65private static Properties properties = null;6667static {68bundle = ResourceBundle.getBundle("resources.swingset");69properties = new Properties();70try {71properties.load(TextAndMnemonicUtils.class.getResourceAsStream("resources/swingset.properties"));72} catch (IOException ex) {73System.out.println("java.io.IOException: Couldn't load properties from: resources/swingset.properties");74}75}7677/**78* Returns accessible and internationalized strings or mnemonics from the79* resource bundle. The key is converted to the text & mnemonic key.80*81* The following patterns are checked:82* Keys that have label suffixes:83* (xxx_label -> xxx.labelAndMnemonic)84*85* Keys that have mnemonic suffixes:86* (xxx_mnemonic -> xxx.labelAndMnemonic)87*88* Keys that do not have definite suffixes:89* (xxx -> xxx.labelAndMnemonic)90*91* Properties class is used to check if a key created for mnemonic exists.92*/93public static String getTextAndMnemonicString(String key) {9495if (key.endsWith("_label")) {96String compositeKey = composeKey(key, 6, LABEL_SUFFIX);97String textAndMnemonic = bundle.getString(compositeKey);98return getTextFromTextAndMnemonic(textAndMnemonic);99}100101if (key.endsWith("_mnemonic")) {102103String compositeKey = composeKey(key, 9, LABEL_SUFFIX);104Object value = properties.getProperty(compositeKey);105106if (value != null) {107String textAndMnemonic = bundle.getString(compositeKey);108return getMnemonicFromTextAndMnemonic(textAndMnemonic);109}110111}112113String compositeKey = composeKey(key, 0, LABEL_SUFFIX);114Object value = properties.getProperty(compositeKey);115116if (value != null) {117String textAndMnemonic = bundle.getString(compositeKey);118return getTextFromTextAndMnemonic(textAndMnemonic);119}120121String textAndMnemonic = bundle.getString(key);122return getTextFromTextAndMnemonic(textAndMnemonic);123}124125/**126* Convert the text & mnemonic string to text string127*128* The '&' symbol is treated as the mnemonic pointer129* The double "&&" symbols are treated as the single '&'130*131* For example the string "&Look && Feel" is converted to "Look & Feel"132*/133public static String getTextFromTextAndMnemonic(String text) {134135StringBuilder sb = new StringBuilder();136137int prevIndex = 0;138int nextIndex = text.indexOf('&');139int len = text.length();140141while (nextIndex != -1) {142143String s = text.substring(prevIndex, nextIndex);144sb.append(s);145146nextIndex++;147148if (nextIndex != len && text.charAt(nextIndex) == '&') {149sb.append('&');150nextIndex++;151}152153prevIndex = nextIndex;154nextIndex = text.indexOf('&', nextIndex + 1);155}156157sb.append(text.substring(prevIndex, text.length()));158return sb.toString();159}160161/**162* Convert the text & mnemonic string to mnemonic163*164* The '&' symbol is treated the mnemonic pointer165* The double "&&" symbols are treated as the single '&'166*167* For example the string "&Look && Feel" is converted to "L"168*/169public static String getMnemonicFromTextAndMnemonic(String text) {170int len = text.length();171int index = text.indexOf('&');172173while (0 <= index && index < text.length() - 1) {174index++;175if (text.charAt(index) == '&') {176index = text.indexOf('&', index + 1);177} else {178char c = text.charAt(index);179return String.valueOf(Character.toUpperCase(c));180}181}182183return null;184}185186/**187* Removes the last n characters and adds the suffix188*/189private static String composeKey(String key, int reduce, String sufix) {190return key.substring(0, key.length() - reduce) + sufix;191}192}193194195