1 /* 2 * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.awt.im; 27 28 import java.awt.AWTException; 29 import java.awt.CheckboxMenuItem; 30 import java.awt.Component; 31 import java.awt.Dialog; 32 import java.awt.EventQueue; 33 import java.awt.Frame; 34 import java.awt.PopupMenu; 35 import java.awt.Menu; 36 import java.awt.MenuItem; 37 import java.awt.Toolkit; 38 import sun.awt.AppContext; 39 import java.awt.event.ActionEvent; 40 import java.awt.event.ActionListener; 41 import java.awt.event.InvocationEvent; 42 import java.awt.im.spi.InputMethodDescriptor; 43 import java.lang.reflect.InvocationTargetException; 44 import java.security.AccessController; 45 import java.security.PrivilegedAction; 46 import java.security.PrivilegedActionException; 47 import java.security.PrivilegedExceptionAction; 48 import java.util.Hashtable; 49 import java.util.Iterator; 50 import java.util.Locale; 51 import java.util.ServiceLoader; 52 import java.util.Vector; 53 import java.util.Set; 54 import java.util.prefs.BackingStoreException; 55 import java.util.prefs.Preferences; 56 import sun.awt.InputMethodSupport; 57 import sun.awt.SunToolkit; 58 import sun.misc.InnocuousThread; 59 import sun.misc.ManagedLocalsThread; 60 61 /** 62 * {@code InputMethodManager} is an abstract class that manages the input 63 * method environment of JVM. There is only one {@code InputMethodManager} 64 * instance in JVM that is executed under a separate daemon thread. 65 * {@code InputMethodManager} performs the following: 66 * <UL> 67 * <LI> 68 * Keeps track of the current input context.</LI> 69 * 70 * <LI> 71 * Provides a user interface to switch input methods and notifies the current 72 * input context about changes made from the user interface.</LI> 73 * </UL> 74 * 75 * The mechanism for supporting input method switch is as follows. (Note that 76 * this may change in future releases.) 77 * 78 * <UL> 79 * <LI> 80 * One way is to use platform-dependent window manager's menu (known as the <I>Window 81 * menu </I>in Motif and the <I>System menu</I> or <I>Control menu</I> in 82 * Win32) on each window which is popped up by clicking the left top box of 83 * a window (known as <I>Window menu button</I> in Motif and <I>System menu 84 * button</I> in Win32). This happens to be common in both Motif and Win32.</LI> 85 * 86 * <LI> 87 * When more than one input method descriptor can be found or the only input 88 * method descriptor found supports multiple locales, a menu item 89 * is added to the window (manager) menu. This item label is obtained invoking 90 * {@code getTriggerMenuString()}. If null is returned by this method, it 91 * means that there is only input method or none in the environment. Frame and Dialog 92 * invoke this method.</LI> 93 * 94 * <LI> 95 * This menu item means a trigger switch to the user to pop up a selection 96 * menu.</LI> 97 * 98 * <LI> 99 * When the menu item of the window (manager) menu has been selected by the 100 * user, Frame/Dialog invokes {@code notifyChangeRequest()} to notify 101 * {@code InputMethodManager} that the user wants to switch input methods.</LI> 102 * 103 * <LI> 104 * {@code InputMethodManager} displays a pop-up menu to choose an input method.</LI> 105 * 106 * <LI> 107 * {@code InputMethodManager} notifies the current {@code InputContext} of 108 * the selected {@code InputMethod}.</LI> 109 * </UL> 110 * 111 * <UL> 112 * <LI> 113 * The other way is to use user-defined hot key combination to show the pop-up menu to 114 * choose an input method. This is useful for the platforms which do not provide a 115 * way to add a menu item in the window (manager) menu.</LI> 116 * 117 * <LI> 118 * When the hot key combination is typed by the user, the component which has the input 119 * focus invokes {@code notifyChangeRequestByHotKey()} to notify 120 * {@code InputMethodManager} that the user wants to switch input methods.</LI> 121 * 122 * <LI> 123 * This results in a popup menu and notification to the current input context, 124 * as above.</LI> 125 * </UL> 126 * 127 * @see java.awt.im.spi.InputMethod 128 * @see sun.awt.im.InputContext 129 * @see sun.awt.im.InputMethodAdapter 130 * @author JavaSoft International 131 */ 132 133 public abstract class InputMethodManager { 134 135 /** 136 * InputMethodManager thread name 137 */ 138 private static final String threadName = "AWT-InputMethodManager"; 139 140 /** 141 * Object for global locking 142 */ 143 private static final Object LOCK = new Object(); 144 145 /** 146 * The InputMethodManager instance 147 */ 148 private static InputMethodManager inputMethodManager; 149 150 /** 151 * Returns the instance of InputMethodManager. This method creates 152 * the instance that is unique in the Java VM if it has not been 153 * created yet. 154 * 155 * @return the InputMethodManager instance 156 */ 157 public static final InputMethodManager getInstance() { 158 if (inputMethodManager != null) { 159 return inputMethodManager; 160 } 161 synchronized(LOCK) { 162 if (inputMethodManager == null) { 163 ExecutableInputMethodManager imm = new ExecutableInputMethodManager(); 164 165 // Initialize the input method manager and start a 166 // daemon thread if the user has multiple input methods 167 // to choose from. Otherwise, just keep the instance. 168 if (imm.hasMultipleInputMethods()) { 169 imm.initialize(); 170 Thread immThread = new ManagedLocalsThread(imm, threadName); 171 immThread.setDaemon(true); 172 immThread.setPriority(Thread.NORM_PRIORITY + 1); 173 immThread.start(); 174 } 175 inputMethodManager = imm; 176 } 177 } 178 return inputMethodManager; 179 } 180 181 /** 182 * Gets a string for the trigger menu item that should be added to 183 * the window manager menu. If no need to display the trigger menu 184 * item, null is returned. 185 */ 186 public abstract String getTriggerMenuString(); 187 188 /** 189 * Notifies InputMethodManager that input method change has been 190 * requested by the user. This notification triggers a popup menu 191 * for user selection. 192 * 193 * @param comp Component that has accepted the change 194 * request. This component has to be a Frame or Dialog. 195 */ 196 public abstract void notifyChangeRequest(Component comp); 197 198 /** 199 * Notifies InputMethodManager that input method change has been 200 * requested by the user using the hot key combination. This 201 * notification triggers a popup menu for user selection. 202 * 203 * @param comp Component that has accepted the change 204 * request. This component has the input focus. 205 */ 206 public abstract void notifyChangeRequestByHotKey(Component comp); 207 208 /** 209 * Sets the current input context so that it will be notified 210 * of input method changes initiated from the user interface. 211 * Set to real input context when activating; to null when 212 * deactivating. 213 */ 214 abstract void setInputContext(InputContext inputContext); 215 216 /** 217 * Tries to find an input method locator for the given locale. 218 * Returns null if no available input method locator supports 219 * the locale. 220 */ 221 abstract InputMethodLocator findInputMethod(Locale forLocale); 222 223 /** 224 * Gets the default keyboard locale of the underlying operating system. 225 */ 226 abstract Locale getDefaultKeyboardLocale(); 227 228 /** 229 * Returns whether multiple input methods are available or not 230 */ 231 abstract boolean hasMultipleInputMethods(); 232 233 } --- EOF ---