jdk/src/share/classes/sun/awt/im/InputContext.java
author mchung
Tue, 29 Sep 2009 16:03:03 -0700
changeset 3938 ef327bd847c0
parent 1311 2b1552286d23
child 5506 202f599c92aa
permissions -rw-r--r--
6879044: Eliminate the dependency on logging from the AWT/2D/Swing classes Summary: Replace calls to Logger with sun.util.logging.PlatformLogger Reviewed-by: prr, art, alexp, dcherepanov, igor, dav, anthony
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 438
diff changeset
     2
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.awt.im;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.AWTEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.AWTKeyStroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.Component;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.awt.EventQueue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.awt.Frame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.awt.Rectangle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.awt.Toolkit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.awt.Window;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.awt.event.ComponentEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.awt.event.ComponentListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.awt.event.FocusEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.awt.event.InputEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.awt.event.InputMethodEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.awt.event.KeyEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.awt.event.WindowEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.awt.event.WindowListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.awt.im.InputMethodRequests;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.awt.im.spi.InputMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.lang.Character.Subset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.security.AccessController;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import java.security.PrivilegedAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import java.text.MessageFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
import java.util.HashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import java.util.Iterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import java.util.Locale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import java.util.prefs.BackingStoreException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import java.util.prefs.Preferences;
3938
ef327bd847c0 6879044: Eliminate the dependency on logging from the AWT/2D/Swing classes
mchung
parents: 1311
diff changeset
    55
import sun.util.logging.PlatformLogger;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import sun.awt.SunToolkit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * This InputContext class contains parts of the implementation of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * java.text.im.InputContext. These parts have been moved
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * here to avoid exposing protected members that are needed by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * subclass InputMethodContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * @see java.awt.im.InputContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * @author JavaSoft Asia/Pacific
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
public class InputContext extends java.awt.im.InputContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
                          implements ComponentListener, WindowListener {
3938
ef327bd847c0 6879044: Eliminate the dependency on logging from the AWT/2D/Swing classes
mchung
parents: 1311
diff changeset
    70
    private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.im.InputContext");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    // The current input method is represented by two objects:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    // a locator is used to keep information about the selected
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    // input method and locale until we actually need a real input
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    // method; only then the input method itself is created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    // Once there is an input method, the input method's locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    // takes precedence over locale information in the locator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    private InputMethodLocator inputMethodLocator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private InputMethod inputMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    private boolean inputMethodCreationFailed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    // holding bin for previously used input method instances, but not the current one
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private HashMap usedInputMethods;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    // the current client component is kept until the user focusses on a different
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    // client component served by the same input context. When that happens, we call
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    // endComposition so that text doesn't jump from one component to another.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    private Component currentClientComponent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    private Component awtFocussedComponent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    private boolean   isInputMethodActive;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    private Subset[]  characterSubsets = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    // true if composition area has been set to invisible when focus was lost
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    private boolean compositionAreaHidden = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    // The input context for whose input method we may have to call hideWindows
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    private static InputContext inputMethodWindowContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    // Previously active input method to decide whether we need to call
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    // InputMethodAdapter.stopListening() on activateInputMethod()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    private static InputMethod previousInputMethod = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    // true if the current input method requires client window change notification
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private boolean clientWindowNotificationEnabled = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    // client window to which this input context is listening
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    private Window clientWindowListened;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    // cache location notification
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    private Rectangle clientWindowLocation = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    // holding the state of clientWindowNotificationEnabled of only non-current input methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    private HashMap perInputMethodState;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // Input Method selection hot key stuff
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    private static AWTKeyStroke inputMethodSelectionKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    private static boolean inputMethodSelectionKeyInitialized = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    private static final String inputMethodSelectionKeyPath = "/java/awt/im/selectionKey";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    private static final String inputMethodSelectionKeyCodeName = "keyCode";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    private static final String inputMethodSelectionKeyModifiersName = "modifiers";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * Constructs an InputContext.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    protected InputContext() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        InputMethodManager imm = InputMethodManager.getInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        synchronized (InputContext.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            if (!inputMethodSelectionKeyInitialized) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                inputMethodSelectionKeyInitialized = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                if (imm.hasMultipleInputMethods()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                    initializeInputMethodSelectionKey();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        selectInputMethod(imm.getDefaultKeyboardLocale());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * @see java.awt.im.InputContext#selectInputMethod
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * @exception NullPointerException when the locale is null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    public synchronized boolean selectInputMethod(Locale locale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        if (locale == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        // see whether the current input method supports the locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            if (inputMethod.setLocale(locale)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        } else if (inputMethodLocator != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            // This is not 100% correct, since the input method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            // may support the locale without advertising it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            // But before we try instantiations and setLocale,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            // we look for an input method that's more confident.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            if (inputMethodLocator.isLocaleAvailable(locale)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                inputMethodLocator = inputMethodLocator.deriveLocator(locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        // see whether there's some other input method that supports the locale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        InputMethodLocator newLocator = InputMethodManager.getInstance().findInputMethod(locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        if (newLocator != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            changeInputMethod(newLocator);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        // make one last desperate effort with the current input method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        // ??? is this good? This is pretty high cost for something that's likely to fail.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        if (inputMethod == null && inputMethodLocator != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                return inputMethod.setLocale(locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     * @see java.awt.im.InputContext#getLocale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    public Locale getLocale() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            return inputMethod.getLocale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        } else if (inputMethodLocator != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            return inputMethodLocator.getLocale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * @see java.awt.im.InputContext#setCharacterSubsets
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    public void setCharacterSubsets(Subset[] subsets) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        if (subsets == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            characterSubsets = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            characterSubsets = new Subset[subsets.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            System.arraycopy(subsets, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                             characterSubsets, 0, characterSubsets.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            inputMethod.setCharacterSubsets(subsets);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * @see java.awt.im.InputContext#reconvert
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     * @since 1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * @exception UnsupportedOperationException when input method is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    public synchronized void reconvert() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        InputMethod inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        if (inputMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            throw new UnsupportedOperationException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        inputMethod.reconvert();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     * @see java.awt.im.InputContext#dispatchEvent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    public void dispatchEvent(AWTEvent event) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        if (event instanceof InputMethodEvent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        // Ignore focus events that relate to the InputMethodWindow of this context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        // This is a workaround.  Should be removed after 4452384 is fixed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        if (event instanceof FocusEvent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            Component opposite = ((FocusEvent)event).getOppositeComponent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            if ((opposite != null) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                (getComponentWindow(opposite) instanceof InputMethodWindow) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                (opposite.getInputContext() == this)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        InputMethod inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        int id = event.getID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        switch (id) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        case FocusEvent.FOCUS_GAINED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
            focusGained((Component) event.getSource());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        case FocusEvent.FOCUS_LOST:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            focusLost((Component) event.getSource(), ((FocusEvent) event).isTemporary());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        case KeyEvent.KEY_PRESSED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            if (checkInputMethodSelectionKey((KeyEvent)event)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                // pop up the input method selection menu
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                InputMethodManager.getInstance().notifyChangeRequestByHotKey((Component)event.getSource());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            // fall through
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            if ((inputMethod != null) && (event instanceof InputEvent)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                inputMethod.dispatchEvent(event);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * Handles focus gained events for any component that's using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * this input context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     * These events are generated by AWT when the keyboard focus
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * moves to a component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * Besides actual client components, the source components
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * may also be the composition area or any component in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * input method window.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * When handling the focus event for a client component, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * method checks whether the input context was previously
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * active for a different client component, and if so, calls
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     * endComposition for the previous client component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     * @param source the component gaining the focus
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    private void focusGained(Component source) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
         * NOTE: When a Container is removing its Component which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
         * invokes this.removeNotify(), the Container has the global
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
         * Component lock. It is possible to happen that an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
         * application thread is calling this.removeNotify() while an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
         * AWT event queue thread is dispatching a focus event via
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
         * this.dispatchEvent(). If an input method uses AWT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
         * components (e.g., IIIMP status window), it causes deadlock,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
         * for example, Component.show()/hide() in this situation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
         * because hide/show tried to obtain the lock.  Therefore,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
         * it's necessary to obtain the global Component lock before
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
         * activating or deactivating an input method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        synchronized (source.getTreeLock()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            synchronized (this) {
1311
2b1552286d23 6607310: InputContext may cause loading of swing classes even for non-Swing applets
peytoia
parents: 715
diff changeset
   300
                if ("sun.awt.im.CompositionArea".equals(source.getClass().getName())) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                    // no special handling for this one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                } else if (getComponentWindow(source) instanceof InputMethodWindow) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                    // no special handling for this one either
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                    if (!source.isDisplayable()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                        // Component is being disposed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                    // Focus went to a real client component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                    // Check whether we're switching between client components
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                    // that share an input context. We can't do that earlier
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                    // than here because we don't want to end composition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                    // until we really know we're switching to a different component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                    if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                        if (currentClientComponent != null && currentClientComponent != source) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                            if (!isInputMethodActive) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                                activateInputMethod(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                            endComposition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                            deactivateInputMethod(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                    currentClientComponent = source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                awtFocussedComponent = source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                if (inputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                    ((InputMethodAdapter) inputMethod).setAWTFocussedComponent(source);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                // it's possible that the input method is still active because
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                // we suppressed a deactivate cause by an input method window
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                // coming up
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                if (!isInputMethodActive) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                    activateInputMethod(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                // If the client component is an active client with the below-the-spot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                // input style, then make the composition window undecorated without a title bar.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                InputMethodContext inputContext = ((InputMethodContext)this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                if (!inputContext.isCompositionAreaVisible()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                      InputMethodRequests req = source.getInputMethodRequests();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                      if (req != null && inputContext.useBelowTheSpotInput()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                          inputContext.setCompositionAreaUndecorated(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                      } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                          inputContext.setCompositionAreaUndecorated(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                // restores the composition area if it was set to invisible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                // when focus got lost
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                if (compositionAreaHidden == true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                    ((InputMethodContext)this).setCompositionAreaVisible(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                    compositionAreaHidden = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * Activates the current input method of this input context, and grabs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * the composition area for use by this input context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * If updateCompositionArea is true, the text in the composition area
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     * is updated (set to false if the text is going to change immediately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     * to avoid screen flicker).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    private void activateInputMethod(boolean updateCompositionArea) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        // call hideWindows() if this input context uses a different
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        // input method than the previously activated one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        if (inputMethodWindowContext != null && inputMethodWindowContext != this &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                inputMethodWindowContext.inputMethodLocator != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                !inputMethodWindowContext.inputMethodLocator.sameInputMethod(inputMethodLocator) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                inputMethodWindowContext.inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            inputMethodWindowContext.inputMethod.hideWindows();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        inputMethodWindowContext = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            if (previousInputMethod != inputMethod &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                    previousInputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                // let the host adapter pass through the input events for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                // new input method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                ((InputMethodAdapter) previousInputMethod).stopListening();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            previousInputMethod = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
3938
ef327bd847c0 6879044: Eliminate the dependency on logging from the AWT/2D/Swing classes
mchung
parents: 1311
diff changeset
   389
            if (log.isLoggable(PlatformLogger.FINE)) log.fine("Current client component " + currentClientComponent);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
            if (inputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                ((InputMethodAdapter) inputMethod).setClientComponent(currentClientComponent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            inputMethod.activate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
            isInputMethodActive = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            if (perInputMethodState != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                Boolean state = (Boolean) perInputMethodState.remove(inputMethod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                if (state != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                    clientWindowNotificationEnabled = state.booleanValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            if (clientWindowNotificationEnabled) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                if (!addedClientWindowListeners()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                    addClientWindowListeners();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                synchronized(this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                    if (clientWindowListened != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                        notifyClientWindowChange(clientWindowListened);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                if (addedClientWindowListeners()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                    removeClientWindowListeners();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        InputMethodManager.getInstance().setInputContext(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        ((InputMethodContext) this).grabCompositionArea(updateCompositionArea);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    static Window getComponentWindow(Component component) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            if (component == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            } else if (component instanceof Window) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                return (Window) component;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                component = component.getParent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     * Handles focus lost events for any component that's using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     * this input context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     * These events are generated by AWT when the keyboard focus
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
     * moves away from a component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
     * Besides actual client components, the source components
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     * may also be the composition area or any component in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     * input method window.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
     * @param source the component losing the focus
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
     * @isTemporary whether the focus change is temporary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    private void focusLost(Component source, boolean isTemporary) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        // see the note on synchronization in focusGained
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        synchronized (source.getTreeLock()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            synchronized (this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                // We need to suppress deactivation if removeNotify has been called earlier.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                // This is indicated by isInputMethodActive == false.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                if (isInputMethodActive) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                    deactivateInputMethod(isTemporary);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                awtFocussedComponent = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                if (inputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                    ((InputMethodAdapter) inputMethod).setAWTFocussedComponent(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                // hides the composition area if currently it is visible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                InputMethodContext inputContext = ((InputMethodContext)this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                if (inputContext.isCompositionAreaVisible()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                    inputContext.setCompositionAreaVisible(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                    compositionAreaHidden = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     * Checks the key event is the input method selection key or not.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    private boolean checkInputMethodSelectionKey(KeyEvent event) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        if (inputMethodSelectionKey != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            AWTKeyStroke aKeyStroke = AWTKeyStroke.getAWTKeyStrokeForEvent(event);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            return inputMethodSelectionKey.equals(aKeyStroke);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    private void deactivateInputMethod(boolean isTemporary) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        InputMethodManager.getInstance().setInputContext(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
            isInputMethodActive = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            inputMethod.deactivate(isTemporary);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            previousInputMethod = inputMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * Switches from the current input method to the one described by newLocator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     * The current input method, if any, is asked to end composition, deactivated,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     * and saved for future use. The newLocator is made the current locator. If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     * the input context is active, an input method instance for the new locator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     * is obtained; otherwise this is deferred until required.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    synchronized void changeInputMethod(InputMethodLocator newLocator) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        // If we don't have a locator yet, this must be a new input context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        // If we created a new input method here, we might get into an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        // infinite loop: create input method -> create some input method window ->
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        // create new input context -> add input context to input method manager's context list ->
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        // call changeInputMethod on it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        // So, just record the locator. dispatchEvent will create the input method when needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        if (inputMethodLocator == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            inputMethodLocator = newLocator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            inputMethodCreationFailed = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        // If the same input method is specified, just keep it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        // Adjust the locale if necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        if (inputMethodLocator.sameInputMethod(newLocator)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            Locale newLocale = newLocator.getLocale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            if (newLocale != null && inputMethodLocator.getLocale() != newLocale) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                    inputMethod.setLocale(newLocale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                inputMethodLocator = newLocator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        // Switch out the old input method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        Locale savedLocale = inputMethodLocator.getLocale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        boolean wasInputMethodActive = isInputMethodActive;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        boolean wasCompositionEnabledSupported = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        boolean wasCompositionEnabled = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                wasCompositionEnabled = inputMethod.isCompositionEnabled();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                wasCompositionEnabledSupported = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
            } catch (UnsupportedOperationException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            if (currentClientComponent != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                if (!isInputMethodActive) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                    activateInputMethod(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                endComposition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                deactivateInputMethod(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                if (inputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                    ((InputMethodAdapter) inputMethod).setClientComponent(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            savedLocale = inputMethod.getLocale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            // keep the input method instance around for future use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            if (usedInputMethods == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                usedInputMethods = new HashMap(5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            if (perInputMethodState == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                perInputMethodState = new HashMap(5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            usedInputMethods.put(inputMethodLocator.deriveLocator(null), inputMethod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            perInputMethodState.put(inputMethod,
438
2ae294e4518c 6613529: Avoid duplicate object creation within JDK packages
dav
parents: 2
diff changeset
   559
                                    Boolean.valueOf(clientWindowNotificationEnabled));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            enableClientWindowNotification(inputMethod, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
            if (this == inputMethodWindowContext) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                inputMethod.hideWindows();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                inputMethodWindowContext = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            inputMethodLocator = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            inputMethod = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            inputMethodCreationFailed = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        // Switch in the new input method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        if (newLocator.getLocale() == null && savedLocale != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                newLocator.isLocaleAvailable(savedLocale)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            newLocator = newLocator.deriveLocator(savedLocale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        inputMethodLocator = newLocator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        inputMethodCreationFailed = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        // activate the new input method if the old one was active
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        if (wasInputMethodActive) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            inputMethod = getInputMethodInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            if (inputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                ((InputMethodAdapter) inputMethod).setAWTFocussedComponent(awtFocussedComponent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            activateInputMethod(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        // enable/disable composition if the old one supports querying enable/disable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        if (wasCompositionEnabledSupported) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                    inputMethod.setCompositionEnabled(wasCompositionEnabled);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                } catch (UnsupportedOperationException e) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     * Returns the client component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    Component getClientComponent() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        return currentClientComponent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     * @see java.awt.im.InputContext#removeNotify
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * @exception NullPointerException when the component is null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    public synchronized void removeNotify(Component component) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        if (component == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        if (inputMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            if (component == currentClientComponent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                currentClientComponent = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        // We may or may not get a FOCUS_LOST event for this component,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        // so do the deactivation stuff here too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        if (component == awtFocussedComponent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
            focusLost(component, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        if (component == currentClientComponent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            if (isInputMethodActive) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                // component wasn't the one that had the focus
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                deactivateInputMethod(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            inputMethod.removeNotify();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            if (clientWindowNotificationEnabled && addedClientWindowListeners()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                removeClientWindowListeners();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            currentClientComponent = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
            if (inputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                ((InputMethodAdapter) inputMethod).setClientComponent(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            // removeNotify() can be issued from a thread other than the event dispatch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
            // thread.  In that case, avoid possible deadlock between Component.AWTTreeLock
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            // and InputMethodContext.compositionAreaHandlerLock by releasing the composition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
            // area on the event dispatch thread.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            if (EventQueue.isDispatchThread()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                ((InputMethodContext)this).releaseCompositionArea();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                EventQueue.invokeLater(new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                    public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                        ((InputMethodContext)InputContext.this).releaseCompositionArea();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     * @see java.awt.im.InputContext#dispose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     * @exception IllegalStateException when the currentClientComponent is not null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    public synchronized void dispose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        if (currentClientComponent != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
            throw new IllegalStateException("Can't dispose InputContext while it's active");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            if (this == inputMethodWindowContext) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                inputMethod.hideWindows();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                inputMethodWindowContext = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
            if (inputMethod == previousInputMethod) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                previousInputMethod = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
            if (clientWindowNotificationEnabled) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                if (addedClientWindowListeners()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                    removeClientWindowListeners();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                clientWindowNotificationEnabled = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            inputMethod.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            // in case the input method enabled the client window
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            // notification in dispose(), which shouldn't happen, it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            // needs to be cleaned up again.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            if (clientWindowNotificationEnabled) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                enableClientWindowNotification(inputMethod, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
            inputMethod = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        inputMethodLocator = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        if (usedInputMethods != null && !usedInputMethods.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
            Iterator iterator = usedInputMethods.values().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
            usedInputMethods = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
            while (iterator.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                ((InputMethod) iterator.next()).dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        // cleanup client window notification variables
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        clientWindowNotificationEnabled = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        clientWindowListened = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        perInputMethodState = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
     * @see java.awt.im.InputContext#getInputMethodControlObject
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    public synchronized Object getInputMethodControlObject() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        InputMethod inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
            return inputMethod.getControlObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     * @see java.awt.im.InputContext#setCompositionEnabled(boolean)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     * @exception UnsupportedOperationException when input method is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
    public void setCompositionEnabled(boolean enable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        InputMethod inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        if (inputMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            throw new UnsupportedOperationException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        inputMethod.setCompositionEnabled(enable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
     * @see java.awt.im.InputContext#isCompositionEnabled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
     * @exception UnsupportedOperationException when input method is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
    public boolean isCompositionEnabled() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
        InputMethod inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        if (inputMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            throw new UnsupportedOperationException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        return inputMethod.isCompositionEnabled();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
     * @return a string with information about the current input method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
     * @exception UnsupportedOperationException when input method is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    public String getInputMethodInfo() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        InputMethod inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        if (inputMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            throw new UnsupportedOperationException("Null input method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        String inputMethodInfo = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        if (inputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
            // returns the information about the host native input method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
            inputMethodInfo = ((InputMethodAdapter)inputMethod).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                getNativeInputMethodInfo();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        // extracts the information from the InputMethodDescriptor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        // associated with the current java input method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        if (inputMethodInfo == null && inputMethodLocator != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            inputMethodInfo = inputMethodLocator.getDescriptor().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                getInputMethodDisplayName(getLocale(), SunToolkit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
                                          getStartupLocale());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        if (inputMethodInfo != null && !inputMethodInfo.equals("")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
            return inputMethodInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        // do our best to return something useful.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        return inputMethod.toString() + "-" + inputMethod.getLocale().toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
     * Turns off the native IM. The native IM is diabled when
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
     * the deactive method of InputMethod is called. It is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
     * delayed until the active method is called on a different
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
     * peer component. This method is provided to explicitly disable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
     * the native IM.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    public void disableNativeIM() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        InputMethod inputMethod = getInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        if (inputMethod != null && inputMethod instanceof InputMethodAdapter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
            ((InputMethodAdapter)inputMethod).disableInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
    private synchronized InputMethod getInputMethod() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
            return inputMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        if (inputMethodCreationFailed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
        inputMethod = getInputMethodInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        return inputMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
     * Returns an instance of the input method described by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
     * the current input method locator. This may be an input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
     * method that was previously used and switched out of,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
     * or a new instance. The locale, character subsets, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
     * input method context of the input method are set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
     * The inputMethodCreationFailed field is set to true if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
     * instantiation failed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
     * @return an InputMethod instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
     * @see java.awt.im.spi.InputMethod#setInputMethodContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
     * @see java.awt.im.spi.InputMethod#setLocale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
     * @see java.awt.im.spi.InputMethod#setCharacterSubsets
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    private InputMethod getInputMethodInstance() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        InputMethodLocator locator = inputMethodLocator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
        if (locator == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            inputMethodCreationFailed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        Locale locale = locator.getLocale();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        InputMethod inputMethodInstance = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        // see whether we have a previously used input method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        if (usedInputMethods != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
            inputMethodInstance = (InputMethod) usedInputMethods.remove(locator.deriveLocator(null));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
            if (inputMethodInstance != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                if (locale != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                    inputMethodInstance.setLocale(locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                inputMethodInstance.setCharacterSubsets(characterSubsets);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                Boolean state = (Boolean) perInputMethodState.remove(inputMethodInstance);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                if (state != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                    enableClientWindowNotification(inputMethodInstance, state.booleanValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                ((InputMethodContext) this).setInputMethodSupportsBelowTheSpot(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                        (!(inputMethodInstance instanceof InputMethodAdapter)) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                        ((InputMethodAdapter) inputMethodInstance).supportsBelowTheSpot());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                return inputMethodInstance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        // need to create new instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
            inputMethodInstance = locator.getDescriptor().createInputMethod();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
            if (locale != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                inputMethodInstance.setLocale(locale);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            inputMethodInstance.setInputMethodContext((InputMethodContext) this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
            inputMethodInstance.setCharacterSubsets(characterSubsets);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            logCreationFailed(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
            // there are a number of bad things that can happen while creating
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
            // the input method. In any case, we just continue without an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
            // input method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            inputMethodCreationFailed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
            // if the instance has been created, then it means either
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
            // setLocale() or setInputMethodContext() failed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
            if (inputMethodInstance != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                inputMethodInstance = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        } catch (LinkageError e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
            logCreationFailed(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
            // same as above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
            inputMethodCreationFailed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
        ((InputMethodContext) this).setInputMethodSupportsBelowTheSpot(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                (!(inputMethodInstance instanceof InputMethodAdapter)) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                ((InputMethodAdapter) inputMethodInstance).supportsBelowTheSpot());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
        return inputMethodInstance;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    private void logCreationFailed(Throwable throwable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
        String errorTextFormat = Toolkit.getProperty("AWT.InputMethodCreationFailed",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                                                     "Could not create {0}. Reason: {1}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
        Object[] args =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
            {inputMethodLocator.getDescriptor().getInputMethodDisplayName(null, Locale.getDefault()),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
             throwable.getLocalizedMessage()};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        MessageFormat mf = new MessageFormat(errorTextFormat);
3938
ef327bd847c0 6879044: Eliminate the dependency on logging from the AWT/2D/Swing classes
mchung
parents: 1311
diff changeset
   892
        PlatformLogger logger = PlatformLogger.getLogger("sun.awt.im");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
        logger.config(mf.format(args));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    InputMethodLocator getInputMethodLocator() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
            return inputMethodLocator.deriveLocator(inputMethod.getLocale());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        return inputMethodLocator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
     * @see java.awt.im.InputContext#endComposition
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    public synchronized void endComposition() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
        if (inputMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
            inputMethod.endComposition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
     * @see java.awt.im.spi.InputMethodContext#enableClientWindowNotification
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
    synchronized void enableClientWindowNotification(InputMethod requester,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
                                                     boolean enable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
        // in case this request is not from the current input method,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
        // store the request and handle it when this requesting input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
        // method becomes the current one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
        if (requester != inputMethod) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
            if (perInputMethodState == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
                perInputMethodState = new HashMap(5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
            }
438
2ae294e4518c 6613529: Avoid duplicate object creation within JDK packages
dav
parents: 2
diff changeset
   924
            perInputMethodState.put(requester, Boolean.valueOf(enable));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
        if (clientWindowNotificationEnabled != enable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
            clientWindowLocation = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
            clientWindowNotificationEnabled = enable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
        if (clientWindowNotificationEnabled) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
            if (!addedClientWindowListeners()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
                addClientWindowListeners();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
            if (clientWindowListened != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
                clientWindowLocation = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
                notifyClientWindowChange(clientWindowListened);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            if (addedClientWindowListeners()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
                removeClientWindowListeners();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    private synchronized void notifyClientWindowChange(Window window) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
        if (inputMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        // if the window is invisible or iconified, send null to the input method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        if (!window.isVisible() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            ((window instanceof Frame) && ((Frame)window).getState() == Frame.ICONIFIED)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
            clientWindowLocation = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            inputMethod.notifyClientWindowChange(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        Rectangle location = window.getBounds();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
        if (clientWindowLocation == null || !clientWindowLocation.equals(location)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            clientWindowLocation = location;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
            inputMethod.notifyClientWindowChange(clientWindowLocation);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    private synchronized void addClientWindowListeners() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        Component client = getClientComponent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        if (client == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
        Window window = getComponentWindow(client);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
        if (window == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        window.addComponentListener(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        window.addWindowListener(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
        clientWindowListened = window;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
    private synchronized void removeClientWindowListeners() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
        clientWindowListened.removeComponentListener(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
        clientWindowListened.removeWindowListener(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
        clientWindowListened = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
     * Returns true if listeners have been set up for client window
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
     * change notification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
    private boolean addedClientWindowListeners() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
        return clientWindowListened != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
     * ComponentListener and WindowListener implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    public void componentResized(ComponentEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
        notifyClientWindowChange((Window)e.getComponent());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
    public void componentMoved(ComponentEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
        notifyClientWindowChange((Window)e.getComponent());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
    public void componentShown(ComponentEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
        notifyClientWindowChange((Window)e.getComponent());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
    public void componentHidden(ComponentEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
        notifyClientWindowChange((Window)e.getComponent());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
    public void windowOpened(WindowEvent e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
    public void windowClosing(WindowEvent e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
    public void windowClosed(WindowEvent e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
    public void windowIconified(WindowEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        notifyClientWindowChange(e.getWindow());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
    public void windowDeiconified(WindowEvent e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
        notifyClientWindowChange(e.getWindow());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
    public void windowActivated(WindowEvent e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
    public void windowDeactivated(WindowEvent e) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
     * Initializes the input method selection key definition in preference trees
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
    private void initializeInputMethodSelectionKey() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        AccessController.doPrivileged(new PrivilegedAction() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            public Object run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
                // Look in user's tree
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
                Preferences root = Preferences.userRoot();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
                inputMethodSelectionKey = getInputMethodSelectionKeyStroke(root);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
                if (inputMethodSelectionKey == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
                    // Look in system's tree
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
                    root = Preferences.systemRoot();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
                    inputMethodSelectionKey = getInputMethodSelectionKeyStroke(root);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        });
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
    private AWTKeyStroke getInputMethodSelectionKeyStroke(Preferences root) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
            if (root.nodeExists(inputMethodSelectionKeyPath)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
                Preferences node = root.node(inputMethodSelectionKeyPath);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                int keyCode = node.getInt(inputMethodSelectionKeyCodeName, KeyEvent.VK_UNDEFINED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
                if (keyCode != KeyEvent.VK_UNDEFINED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
                    int modifiers = node.getInt(inputMethodSelectionKeyModifiersName, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                    return AWTKeyStroke.getAWTKeyStroke(keyCode, modifiers);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
        } catch (BackingStoreException bse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
}