1063 lines · 40.6 KB · Java
RawDownload
    synchronized void changeInputMethod(InputMethodLocator newLocator) {        // If we don't have a locator yet, this must be a new input context.        // If we created a new input method here, we might get into an        // infinite loop: create input method -> create some input method window ->        // create new input context -> add input context to input method manager's context list ->        // call changeInputMethod on it.        // So, just record the locator. dispatchEvent will create the input method when needed.        if (inputMethodLocator == null) {            inputMethodLocator = newLocator;            inputMethodCreationFailed = false;            return;        }         // If the same input method is specified, just keep it.        // Adjust the locale if necessary.        if (inputMethodLocator.sameInputMethod(newLocator)) {            Locale newLocale = newLocator.getLocale();            if (newLocale != null && inputMethodLocator.getLocale() != newLocale) {                if (inputMethod != null) {                    inputMethod.setLocale(newLocale);                }                inputMethodLocator = newLocator;            }            return;        }         // Switch out the old input method        Locale savedLocale = inputMethodLocator.getLocale();        boolean wasInputMethodActive = isInputMethodActive;        boolean wasCompositionEnabledSupported = false;        boolean wasCompositionEnabled = false;        if (inputMethod != null) {            try {                wasCompositionEnabled = inputMethod.isCompositionEnabled();                wasCompositionEnabledSupported = true;            } catch (UnsupportedOperationException e) { }             if (currentClientComponent != null) {                if (!isInputMethodActive) {                    activateInputMethod(false);                }                endComposition();                deactivateInputMethod(false);                if (inputMethod instanceof InputMethodAdapter) {                    ((InputMethodAdapter) inputMethod).setClientComponent(null);                }            }            savedLocale = inputMethod.getLocale();             // keep the input method instance around for future use            if (usedInputMethods == null) {                usedInputMethods = new HashMap(5);            }            if (perInputMethodState == null) {                perInputMethodState = new HashMap(5);            }            usedInputMethods.put(inputMethodLocator.deriveLocator(null), inputMethod);            perInputMethodState.put(inputMethod,                                    Boolean.valueOf(clientWindowNotificationEnabled));            enableClientWindowNotification(inputMethod, false);            if (this == inputMethodWindowContext) {                inputMethod.hideWindows();                inputMethodWindowContext = null;            }            inputMethodLocator = null;            inputMethod = null;            inputMethodCreationFailed = false;        }         // Switch in the new input method        if (newLocator.getLocale() == null && savedLocale != null &&                newLocator.isLocaleAvailable(savedLocale)) {            newLocator = newLocator.deriveLocator(savedLocale);        }        inputMethodLocator = newLocator;        inputMethodCreationFailed = false;         // activate the new input method if the old one was active        if (wasInputMethodActive) {            inputMethod = getInputMethodInstance();            if (inputMethod instanceof InputMethodAdapter) {                ((InputMethodAdapter) inputMethod).setAWTFocussedComponent(awtFocussedComponent);            }            activateInputMethod(true);        }         // enable/disable composition if the old one supports querying enable/disable        if (wasCompositionEnabledSupported) {            inputMethod = getInputMethod();            if (inputMethod != null) {                try {                    inputMethod.setCompositionEnabled(wasCompositionEnabled);                } catch (UnsupportedOperationException e) { }            }        }    }     /**     * Returns the client component.     */    Component getClientComponent() {        return currentClientComponent;    }     /**     * @see java.awt.im.InputContext#removeNotify     * @exception NullPointerException when the component is null.     */    public synchronized void removeNotify(Component component) {        if (component == null) {            throw new NullPointerException();        }         if (inputMethod == null) {            if (component == currentClientComponent) {                currentClientComponent = null;            }            return;        }         // We may or may not get a FOCUS_LOST event for this component,        // so do the deactivation stuff here too.        if (component == awtFocussedComponent) {            focusLost(component, false);        }         if (component == currentClientComponent) {            if (isInputMethodActive) {                // component wasn't the one that had the focus                deactivateInputMethod(false);            }            inputMethod.removeNotify();            if (clientWindowNotificationEnabled && addedClientWindowListeners()) {                removeClientWindowListeners();            }            currentClientComponent = null;            if (inputMethod instanceof InputMethodAdapter) {                ((InputMethodAdapter) inputMethod).setClientComponent(null);            }             // removeNotify() can be issued from a thread other than the event dispatch            // thread.  In that case, avoid possible deadlock between Component.AWTTreeLock            // and InputMethodContext.compositionAreaHandlerLock by releasing the composition            // area on the event dispatch thread.            if (EventQueue.isDispatchThread()) {                ((InputMethodContext)this).releaseCompositionArea();            } else {                EventQueue.invokeLater(new Runnable() {                    public void run() {                        ((InputMethodContext)InputContext.this).releaseCompositionArea();                    }                });            }        }    }     /**     * @see java.awt.im.InputContext#dispose     * @exception IllegalStateException when the currentClientComponent is not null     */    public synchronized void dispose() {        if (currentClientComponent != null) {            throw new IllegalStateException("Can't dispose InputContext while it's active");        }        if (inputMethod != null) {            if (this == inputMethodWindowContext) {                inputMethod.hideWindows();                inputMethodWindowContext = null;            }            if (inputMethod == previousInputMethod) {                previousInputMethod = null;            }            if (clientWindowNotificationEnabled) {                if (addedClientWindowListeners()) {                    removeClientWindowListeners();                }                clientWindowNotificationEnabled = false;            }            inputMethod.dispose();             // in case the input method enabled the client window            // notification in dispose(), which shouldn't happen, it            // needs to be cleaned up again.            if (clientWindowNotificationEnabled) {                enableClientWindowNotification(inputMethod, false);            }             inputMethod = null;        }        inputMethodLocator = null;        if (usedInputMethods != null && !usedInputMethods.isEmpty()) {            Iterator iterator = usedInputMethods.values().iterator();            usedInputMethods = null;            while (iterator.hasNext()) {                ((InputMethod) iterator.next()).dispose();            }        }         // cleanup client window notification variables        clientWindowNotificationEnabled = false;        clientWindowListened = null;        perInputMethodState = null;    }     /**     * @see java.awt.im.InputContext#getInputMethodControlObject     */    public synchronized Object getInputMethodControlObject() {        InputMethod inputMethod = getInputMethod();         if (inputMethod != null) {            return inputMethod.getControlObject();        } else {            return null;        }    }     /**     * @see java.awt.im.InputContext#setCompositionEnabled(boolean)     * @exception UnsupportedOperationException when input method is null     */    public void setCompositionEnabled(boolean enable) {        InputMethod inputMethod = getInputMethod();         if (inputMethod == null) {            throw new UnsupportedOperationException();        }        inputMethod.setCompositionEnabled(enable);    }     /**     * @see java.awt.im.InputContext#isCompositionEnabled     * @exception UnsupportedOperationException when input method is null     */    public boolean isCompositionEnabled() {        InputMethod inputMethod = getInputMethod();         if (inputMethod == null) {            throw new UnsupportedOperationException();        }        return inputMethod.isCompositionEnabled();    }     /**     * @return a string with information about the current input method.     * @exception UnsupportedOperationException when input method is null     */    public String getInputMethodInfo() {        InputMethod inputMethod = getInputMethod();         if (inputMethod == null) {            throw new UnsupportedOperationException("Null input method");        }         String inputMethodInfo = null;        if (inputMethod instanceof InputMethodAdapter) {            // returns the information about the host native input method.            inputMethodInfo = ((InputMethodAdapter)inputMethod).                getNativeInputMethodInfo();        }         // extracts the information from the InputMethodDescriptor        // associated with the current java input method.        if (inputMethodInfo == null && inputMethodLocator != null) {            inputMethodInfo = inputMethodLocator.getDescriptor().                getInputMethodDisplayName(getLocale(), SunToolkit.                                          getStartupLocale());        }         if (inputMethodInfo != null && !inputMethodInfo.equals("")) {            return inputMethodInfo;        }         // do our best to return something useful.        return inputMethod.toString() + "-" + inputMethod.getLocale().toString();    }     /**     * Turns off the native IM. The native IM is diabled when     * the deactive method of InputMethod is called. It is     * delayed until the active method is called on a different     * peer component. This method is provided to explicitly disable     * the native IM.     */    public void disableNativeIM() {        InputMethod inputMethod = getInputMethod();        if (inputMethod != null && inputMethod instanceof InputMethodAdapter) {            ((InputMethodAdapter)inputMethod).disableInputMethod();        }    }      private synchronized InputMethod getInputMethod() {        if (inputMethod != null) {            return inputMethod;        }         if (inputMethodCreationFailed) {            return null;        }         inputMethod = getInputMethodInstance();        return inputMethod;    }     /**     * Returns an instance of the input method described by     * the current input method locator. This may be an input     * method that was previously used and switched out of,     * or a new instance. The locale, character subsets, and     * input method context of the input method are set.     *     * The inputMethodCreationFailed field is set to true if the     * instantiation failed.     *     * @return an InputMethod instance     * @see java.awt.im.spi.InputMethod#setInputMethodContext     * @see java.awt.im.spi.InputMethod#setLocale     * @see java.awt.im.spi.InputMethod#setCharacterSubsets     */    private InputMethod getInputMethodInstance() {        InputMethodLocator locator = inputMethodLocator;        if (locator == null) {            inputMethodCreationFailed = true;            return null;        }         Locale locale = locator.getLocale();        InputMethod inputMethodInstance = null;         // see whether we have a previously used input method        if (usedInputMethods != null) {            inputMethodInstance = (InputMethod) usedInputMethods.remove(locator.deriveLocator(null));            if (inputMethodInstance != null) {                if (locale != null) {                    inputMethodInstance.setLocale(locale);                }                inputMethodInstance.setCharacterSubsets(characterSubsets);                Boolean state = (Boolean) perInputMethodState.remove(inputMethodInstance);                if (state != null) {                    enableClientWindowNotification(inputMethodInstance, state.booleanValue());                }                ((InputMethodContext) this).setInputMethodSupportsBelowTheSpot(                        (!(inputMethodInstance instanceof InputMethodAdapter)) ||                        ((InputMethodAdapter) inputMethodInstance).supportsBelowTheSpot());                return inputMethodInstance;            }        }         // need to create new instance        try {            inputMethodInstance = locator.getDescriptor().createInputMethod();             if (locale != null) {                inputMethodInstance.setLocale(locale);            }            inputMethodInstance.setInputMethodContext((InputMethodContext) this);            inputMethodInstance.setCharacterSubsets(characterSubsets);         } catch (Exception e) {            logCreationFailed(e);             // there are a number of bad things that can happen while creating            // the input method. In any case, we just continue without an            // input method.            inputMethodCreationFailed = true;             // if the instance has been created, then it means either            // setLocale() or setInputMethodContext() failed.            if (inputMethodInstance != null) {                inputMethodInstance = null;            }        } catch (LinkageError e) {            logCreationFailed(e);             // same as above            inputMethodCreationFailed = true;        }        ((InputMethodContext) this).setInputMethodSupportsBelowTheSpot(                (!(inputMethodInstance instanceof InputMethodAdapter)) ||                ((InputMethodAdapter) inputMethodInstance).supportsBelowTheSpot());        return inputMethodInstance;    }     private void logCreationFailed(Throwable throwable) {        String errorTextFormat = Toolkit.getProperty("AWT.InputMethodCreationFailed",                                                     "Could not create {0}. Reason: {1}");        Object[] args =            {inputMethodLocator.getDescriptor().getInputMethodDisplayName(null, Locale.getDefault()),             throwable.getLocalizedMessage()};        MessageFormat mf = new MessageFormat(errorTextFormat);        PlatformLogger logger = PlatformLogger.getLogger("sun.awt.im");        logger.config(mf.format(args));    }     InputMethodLocator getInputMethodLocator() {        if (inputMethod != null) {            return inputMethodLocator.deriveLocator(inputMethod.getLocale());        }        return inputMethodLocator;    }     /**     * @see java.awt.im.InputContext#endComposition     */    public synchronized void endComposition() {        if (inputMethod != null) {            inputMethod.endComposition();        }    }     /**     * @see java.awt.im.spi.InputMethodContext#enableClientWindowNotification     */    synchronized void enableClientWindowNotification(InputMethod requester,                                                     boolean enable) {        // in case this request is not from the current input method,        // store the request and handle it when this requesting input        // method becomes the current one.        if (requester != inputMethod) {            if (perInputMethodState == null) {                perInputMethodState = new HashMap(5);            }            perInputMethodState.put(requester, Boolean.valueOf(enable));            return;        }         if (clientWindowNotificationEnabled != enable) {            clientWindowLocation = null;            clientWindowNotificationEnabled = enable;        }        if (clientWindowNotificationEnabled) {            if (!addedClientWindowListeners()) {                addClientWindowListeners();            }            if (clientWindowListened != null) {                clientWindowLocation = null;                notifyClientWindowChange(clientWindowListened);            }        } else {            if (addedClientWindowListeners()) {                removeClientWindowListeners();            }        }    }     private synchronized void notifyClientWindowChange(Window window) {        if (inputMethod == null) {            return;        }         // if the window is invisible or iconified, send null to the input method.        if (!window.isVisible() ||            ((window instanceof Frame) && ((Frame)window).getState() == Frame.ICONIFIED)) {            clientWindowLocation = null;            inputMethod.notifyClientWindowChange(null);            return;        }        Rectangle location = window.getBounds();        if (clientWindowLocation == null || !clientWindowLocation.equals(location)) {            clientWindowLocation = location;            inputMethod.notifyClientWindowChange(clientWindowLocation);        }    }     private synchronized void addClientWindowListeners() {        Component client = getClientComponent();        if (client == null) {            return;        }        Window window = getComponentWindow(client);        if (window == null) {            return;        }        window.addComponentListener(this);        window.addWindowListener(this);        clientWindowListened = window;    }     private synchronized void removeClientWindowListeners() {        clientWindowListened.removeComponentListener(this);        clientWindowListened.removeWindowListener(this);        clientWindowListened = null;    }     /**     * Returns true if listeners have been set up for client window     * change notification.     */    private boolean addedClientWindowListeners() {        return clientWindowListened != null;    }     /*     * ComponentListener and WindowListener implementation     */    public void componentResized(ComponentEvent e) {        notifyClientWindowChange((Window)e.getComponent());    } 

Lines 501–1000 of 1063. Previous lines