| /* |
| * |
| * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * - Redistributions of source code must retain the above copyright notice, this |
| * list of conditions and the following disclaimer. |
| * |
| * - Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * - Neither the name of Oracle nor the names of its contributors may be used to |
| * endorse or promote products derived from this software without specific prior |
| * written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| import java.io.IOException; |
| import java.util.Properties; |
| import java.util.ResourceBundle; |
| |
| /** |
| * <code>TextAndMnemonicUtils</code> allows to extract text and mnemonic values |
| * from the unified text & mnemonic strings. For example: |
| * LafMenu.laf.labelAndMnemonic=&Look && Feel |
| * The extracted text is "Look & Feel" and the extracted mnemonic mnemonic is "L". |
| * |
| * There are several patterns for the text and mnemonic suffixes which are used |
| * in the resource file. The patterns format is: |
| * (resource key -> unified text & mnemonic resource key). |
| * |
| * Keys that have label suffixes: |
| * (xxx_label -> xxx.labelAndMnemonic) |
| * |
| * Keys that have mnemonic suffixes: |
| * (xxx_mnemonic -> xxx.labelAndMnemonic) |
| * |
| * Keys that do not have definite suffixes: |
| * (xxx -> xxx.labelAndMnemonic) |
| * |
| * @author Alexander Scherbatiy |
| */ |
| public class TextAndMnemonicUtils { |
| |
| // Label suffix for the text & mnemonic resource |
| private static final String LABEL_SUFFIX = ".labelAndMnemonic"; |
| |
| // Resource bundle for internationalized and accessible text |
| private static ResourceBundle bundle = null; |
| |
| // Resource properties for the mnemonic key defenition |
| private static Properties properties = null; |
| |
| static { |
| bundle = ResourceBundle.getBundle("resources.swingset"); |
| properties = new Properties(); |
| try { |
| properties.load(TextAndMnemonicUtils.class.getResourceAsStream("resources/swingset.properties")); |
| } catch (IOException ex) { |
| System.out.println("java.io.IOException: Couldn't load properties from: resources/swingset.properties"); |
| } |
| } |
| |
| /** |
| * Returns accessible and internationalized strings or mnemonics from the |
| * resource bundle. The key is converted to the text & mnemonic key. |
| * |
| * The following patterns are checked: |
| * Keys that have label suffixes: |
| * (xxx_label -> xxx.labelAndMnemonic) |
| * |
| * Keys that have mnemonic suffixes: |
| * (xxx_mnemonic -> xxx.labelAndMnemonic) |
| * |
| * Keys that do not have definite suffixes: |
| * (xxx -> xxx.labelAndMnemonic) |
| * |
| * Properties class is used to check if a key created for mnemonic exists. |
| */ |
| public static String getTextAndMnemonicString(String key) { |
| |
| if (key.endsWith("_label")) { |
| String compositeKey = composeKey(key, 6, LABEL_SUFFIX); |
| String textAndMnemonic = bundle.getString(compositeKey); |
| return getTextFromTextAndMnemonic(textAndMnemonic); |
| } |
| |
| if (key.endsWith("_mnemonic")) { |
| |
| String compositeKey = composeKey(key, 9, LABEL_SUFFIX); |
| Object value = properties.getProperty(compositeKey); |
| |
| if (value != null) { |
| String textAndMnemonic = bundle.getString(compositeKey); |
| return getMnemonicFromTextAndMnemonic(textAndMnemonic); |
| } |
| |
| } |
| |
| String compositeKey = composeKey(key, 0, LABEL_SUFFIX); |
| Object value = properties.getProperty(compositeKey); |
| |
| if (value != null) { |
| String textAndMnemonic = bundle.getString(compositeKey); |
| return getTextFromTextAndMnemonic(textAndMnemonic); |
| } |
| |
| String textAndMnemonic = bundle.getString(key); |
| return getTextFromTextAndMnemonic(textAndMnemonic); |
| } |
| |
| /** |
| * Convert the text & mnemonic string to text string |
| * |
| * The '&' symbol is treated as the mnemonic pointer |
| * The double "&&" symbols are treated as the single '&' |
| * |
| * For example the string "&Look && Feel" is converted to "Look & Feel" |
| */ |
| public static String getTextFromTextAndMnemonic(String text) { |
| |
| StringBuilder sb = new StringBuilder(); |
| |
| int prevIndex = 0; |
| int nextIndex = text.indexOf('&'); |
| int len = text.length(); |
| |
| while (nextIndex != -1) { |
| |
| String s = text.substring(prevIndex, nextIndex); |
| sb.append(s); |
| |
| nextIndex++; |
| |
| if (nextIndex != len && text.charAt(nextIndex) == '&') { |
| sb.append('&'); |
| nextIndex++; |
| } |
| |
| prevIndex = nextIndex; |
| nextIndex = text.indexOf('&', nextIndex + 1); |
| } |
| |
| sb.append(text.substring(prevIndex, text.length())); |
| return sb.toString(); |
| } |
| |
| /** |
| * Convert the text & mnemonic string to mnemonic |
| * |
| * The '&' symbol is treated the mnemonic pointer |
| * The double "&&" symbols are treated as the single '&' |
| * |
| * For example the string "&Look && Feel" is converted to "L" |
| */ |
| public static String getMnemonicFromTextAndMnemonic(String text) { |
| int len = text.length(); |
| int index = text.indexOf('&'); |
| |
| while (0 <= index && index < text.length() - 1) { |
| index++; |
| if (text.charAt(index) == '&') { |
| index = text.indexOf('&', index + 1); |
| } else { |
| char c = text.charAt(index); |
| return String.valueOf(Character.toUpperCase(c)); |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Removes the last n characters and adds the suffix |
| */ |
| private static String composeKey(String key, int reduce, String sufix) { |
| return key.substring(0, key.length() - reduce) + sufix; |
| } |
| } |