001 /* 002 * Created on Mar 26, 2008 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 005 * the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 011 * specific language governing permissions and limitations under the License. 012 * 013 * Copyright @2008-2010 the original author or authors. 014 */ 015 package org.fest.swing.keystroke; 016 017 import static java.awt.event.InputEvent.SHIFT_MASK; 018 import static java.awt.event.KeyEvent.CHAR_UNDEFINED; 019 import static org.fest.swing.util.Platform.osFamily; 020 021 import java.util.Locale; 022 023 import javax.swing.KeyStroke; 024 025 import org.fest.util.VisibleForTesting; 026 027 /** 028 * Understands a collection of <code>{@link KeyStrokeMapping}</code>. 029 * 030 * @author Yvonne Wang 031 * @author Alex Ruiz 032 */ 033 public class KeyStrokeMap { 034 035 private static KeyStrokeMapCollection maps = new KeyStrokeMapCollection(); 036 037 static { 038 reloadFromSystemSettings(); 039 } 040 041 /** 042 * Reloads the key stroke mappings for the language from the default locale. 043 * @deprecated use <code>{@link #reloadFromSystemSettings()}</code> instead. 044 */ 045 @Deprecated 046 public static void reloadFromLocale() { 047 reloadFromSystemSettings(); 048 } 049 050 /** 051 * Reloads the key stroke mappings for the language using the current system settings. 052 * @since 1.2 053 */ 054 public static void reloadFromSystemSettings() { 055 KeyStrokeMappingProviderPicker picker = new KeyStrokeMappingProviderPicker(); 056 maps.clear(); 057 addKeyStrokesFrom(picker.providerFor(osFamily(), Locale.getDefault())); 058 } 059 060 @VisibleForTesting 061 static void updateKeyStrokeMapCollection(KeyStrokeMapCollection c) { 062 maps = c; 063 } 064 065 /** 066 * Adds the collection of <code>{@link KeyStrokeMapping}</code>s from the given 067 * <code>{@link KeyStrokeMappingProvider}</code> to this map. 068 * @param provider the given <code>KeyStrokeMappingProvider</code>. 069 */ 070 public static void addKeyStrokesFrom(KeyStrokeMappingProvider provider) { 071 for (KeyStrokeMapping entry : provider.keyStrokeMappings()) 072 add(entry.character(), entry.keyStroke()); 073 } 074 075 private static void add(Character character, KeyStroke keyStroke) { 076 maps.add(character, keyStroke); 077 } 078 079 /** 080 * Removes all the character-<code>{@link KeyStroke}</code> mappings. 081 */ 082 public static void clearKeyStrokes() { 083 maps.clear(); 084 } 085 086 /** 087 * Indicates whether <code>{@link KeyStrokeMap}</code> has mappings or not. 088 * @return <code>true</code> if it has mappings, <code>false</code> otherwise. 089 */ 090 public static boolean hasKeyStrokes() { 091 return !maps.isEmpty(); 092 } 093 094 /** 095 * Returns the <code>{@link KeyStroke}</code> corresponding to the given character, as best we can guess it, or 096 * <code>null</code> if we don't know how to generate it. 097 * @param character the given character. 098 * @return the key code-based <code>KeyStroke</code> corresponding to the given character, or <code>null</code> if 099 * we cannot generate it. 100 */ 101 public static KeyStroke keyStrokeFor(char character) { 102 return maps.keyStrokeFor(character); 103 } 104 105 /** 106 * Given a <code>{@link KeyStroke}</code>, returns the equivalent character. Key strokes are defined properly for 107 * US keyboards only. To contribute your own, please add them using the method 108 * <code>{@link #addKeyStrokesFrom(KeyStrokeMappingProvider)}</code>. 109 * @param keyStroke the given <code>KeyStroke</code>. 110 * @return KeyEvent.VK_UNDEFINED if the result is unknown. 111 */ 112 public static char charFor(KeyStroke keyStroke) { 113 Character character = maps.charFor(keyStroke); 114 // Try again, but strip all modifiers but shift 115 if (character == null) character = charWithoutModifiersButShift(keyStroke); 116 if (character == null) return CHAR_UNDEFINED; 117 return character.charValue(); 118 } 119 120 private static Character charWithoutModifiersButShift(KeyStroke keyStroke) { 121 int mask = keyStroke.getModifiers() & ~SHIFT_MASK; 122 return maps.charFor(KeyStroke.getKeyStroke(keyStroke.getKeyCode(), mask)); 123 } 124 125 private KeyStrokeMap() {} 126 }