alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (InputMethodContext.java)

This example Java source code file (InputMethodContext.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

attributedcharacteriterator, attributedstring, awt, component, compositionareahandler, event, font, gui, headlessexception, inputcontext, inputmethodcontext, inputmethodevent, inputmethodrequests, jframe, keyevent, object, swing, text, texthitinfo, window

The InputMethodContext.java Java example source code

/*
 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.awt.im;

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.InputMethodEvent;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodRequests;
import java.awt.im.spi.InputMethod;
import java.security.AccessController;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.text.AttributedString;
import java.text.CharacterIterator;
import javax.swing.JFrame;
import sun.awt.InputMethodSupport;
import sun.security.action.GetPropertyAction;

/**
 * The InputMethodContext class provides methods that input methods
 * can use to communicate with their client components.
 * It is a subclass of InputContext, which provides methods for use by
 * components.
 *
 * @author JavaSoft International
 */

public class InputMethodContext
       extends sun.awt.im.InputContext
       implements java.awt.im.spi.InputMethodContext {

    private boolean dispatchingCommittedText;

    // Creation of the context's composition area handler is
    // delayed until we really need a composition area.
    private CompositionAreaHandler compositionAreaHandler;
    private Object compositionAreaHandlerLock = new Object();

    static private boolean belowTheSpotInputRequested;
    private boolean inputMethodSupportsBelowTheSpot;

    static {
        // check whether we should use below-the-spot input
        // get property from command line
        String inputStyle = AccessController.doPrivileged
                (new GetPropertyAction("java.awt.im.style", null));
        // get property from awt.properties file
        if (inputStyle == null) {
            inputStyle = Toolkit.getProperty("java.awt.im.style", null);
        }
        belowTheSpotInputRequested = "below-the-spot".equals(inputStyle);
    }

    /**
     * Constructs an InputMethodContext.
     */
    public InputMethodContext() {
        super();
    }

    void setInputMethodSupportsBelowTheSpot(boolean supported) {
        inputMethodSupportsBelowTheSpot = supported;
    }

   boolean useBelowTheSpotInput() {
        return belowTheSpotInputRequested && inputMethodSupportsBelowTheSpot;
    }

    private boolean haveActiveClient() {
        Component client = getClientComponent();
        return client != null
               && client.getInputMethodRequests() != null;
    }

    // implements java.awt.im.spi.InputMethodContext.dispatchInputMethodEvent
    public void dispatchInputMethodEvent(int id,
                AttributedCharacterIterator text, int committedCharacterCount,
                TextHitInfo caret, TextHitInfo visiblePosition) {
        // We need to record the client component as the source so
        // that we have correct information if we later have to break up this
        // event into key events.
        Component source;

        source = getClientComponent();
        if (source != null) {
            InputMethodEvent event = new InputMethodEvent(source,
                    id, text, committedCharacterCount, caret, visiblePosition);

            if (haveActiveClient() && !useBelowTheSpotInput()) {
                source.dispatchEvent(event);
            } else {
                getCompositionAreaHandler(true).processInputMethodEvent(event);
            }
        }
    }

    /**
     * Dispatches committed text to a client component.
     * Called by composition window.
     *
     * @param client The component that the text should get dispatched to.
     * @param text The iterator providing access to the committed
     *        (and possible composed) text.
     * @param committedCharacterCount The number of committed characters in the text.
     */
    synchronized void dispatchCommittedText(Component client,
                 AttributedCharacterIterator text,
                 int committedCharacterCount) {
        // note that the client is not always the current client component -
        // some host input method adapters may dispatch input method events
        // through the Java event queue, and we may have switched clients while
        // the event was in the queue.
        if (committedCharacterCount == 0
                || text.getEndIndex() <= text.getBeginIndex()) {
            return;
        }
        long time = System.currentTimeMillis();
        dispatchingCommittedText = true;
        try {
            InputMethodRequests req = client.getInputMethodRequests();
            if (req != null) {
                // active client -> send text as InputMethodEvent
                int beginIndex = text.getBeginIndex();
                AttributedCharacterIterator toBeCommitted =
                    (new AttributedString(text, beginIndex, beginIndex + committedCharacterCount)).getIterator();

                InputMethodEvent inputEvent = new InputMethodEvent(
                        client,
                        InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
                        toBeCommitted,
                        committedCharacterCount,
                        null, null);

                client.dispatchEvent(inputEvent);
            } else {
                // passive client -> send text as KeyEvents
                char keyChar = text.first();
                while (committedCharacterCount-- > 0 && keyChar != CharacterIterator.DONE) {
                    KeyEvent keyEvent = new KeyEvent(client, KeyEvent.KEY_TYPED,
                                                 time, 0, KeyEvent.VK_UNDEFINED, keyChar);
                    client.dispatchEvent(keyEvent);
                    keyChar = text.next();
                }
            }
        } finally {
            dispatchingCommittedText = false;
        }
    }

    public void dispatchEvent(AWTEvent event) {
        // some host input method adapters may dispatch input method events
        // through the Java event queue. If the component that the event is
        // intended for isn't an active client, or if we're using below-the-spot
        // input, we need to dispatch this event
        // to the input window. Note that that component is not necessarily the
        // current client component, since we may have switched clients while
        // the event was in the queue.
        if (event instanceof InputMethodEvent) {
            if (((Component) event.getSource()).getInputMethodRequests() == null
                    || (useBelowTheSpotInput() && !dispatchingCommittedText)) {
                getCompositionAreaHandler(true).processInputMethodEvent((InputMethodEvent) event);
            }
        } else {
            // make sure we don't dispatch our own key events back to the input method
            if (!dispatchingCommittedText) {
                super.dispatchEvent(event);
            }
        }
    }

    /**
     * Gets this context's composition area handler, creating it if necessary.
     * If requested, it grabs the composition area for use by this context.
     * The composition area's text is not updated.
     */
    private CompositionAreaHandler getCompositionAreaHandler(boolean grab) {
        synchronized(compositionAreaHandlerLock) {
            if (compositionAreaHandler == null) {
                compositionAreaHandler = new CompositionAreaHandler(this);
            }
            compositionAreaHandler.setClientComponent(getClientComponent());
            if (grab) {
                compositionAreaHandler.grabCompositionArea(false);
            }

            return compositionAreaHandler;
        }
    }

    /**
     * Grabs the composition area for use by this context.
     * If doUpdate is true, updates the composition area with previously sent
     * composed text.
     */
    void grabCompositionArea(boolean doUpdate) {
        synchronized(compositionAreaHandlerLock) {
            if (compositionAreaHandler != null) {
                compositionAreaHandler.grabCompositionArea(doUpdate);
            } else {
                // if this context hasn't seen a need for a composition area yet,
                // just close it without creating the machinery
                CompositionAreaHandler.closeCompositionArea();
            }
        }
    }

    /**
     * Releases and closes the composition area if it is currently owned by
     * this context's composition area handler.
     */
    void releaseCompositionArea() {
        synchronized(compositionAreaHandlerLock) {
            if (compositionAreaHandler != null) {
                compositionAreaHandler.releaseCompositionArea();
            }
        }
    }

    /**
     * Calls CompositionAreaHandler.isCompositionAreaVisible() to see
     * whether the composition area is visible or not.
     * Notice that this method is always called on the AWT event dispatch
     * thread.
     */
    boolean isCompositionAreaVisible() {
        if (compositionAreaHandler != null) {
            return compositionAreaHandler.isCompositionAreaVisible();
        }

        return false;
    }
    /**
     * Calls CompositionAreaHandler.setCompositionAreaVisible to
     * show or hide the composition area.
     * As isCompositionAreaVisible method, it is always called
     * on AWT event dispatch thread.
     */
    void setCompositionAreaVisible(boolean visible) {
        if (compositionAreaHandler != null) {
            compositionAreaHandler.setCompositionAreaVisible(visible);
        }
    }

    /**
     * Calls the current client component's implementation of getTextLocation.
     */
    public Rectangle getTextLocation(TextHitInfo offset) {
        return getReq().getTextLocation(offset);
    }

    /**
     * Calls the current client component's implementation of getLocationOffset.
     */
    public TextHitInfo getLocationOffset(int x, int y) {
        return getReq().getLocationOffset(x, y);
    }

    /**
     * Calls the current client component's implementation of getInsertPositionOffset.
     */
    public int getInsertPositionOffset() {
        return getReq().getInsertPositionOffset();
    }

    /**
     * Calls the current client component's implementation of getCommittedText.
     */
    public AttributedCharacterIterator getCommittedText(int beginIndex,
                                                       int endIndex,
                                                       Attribute[] attributes) {
        return getReq().getCommittedText(beginIndex, endIndex, attributes);
    }

    /**
     * Calls the current client component's implementation of getCommittedTextLength.
     */
    public int getCommittedTextLength() {
        return getReq().getCommittedTextLength();
    }


    /**
     * Calls the current client component's implementation of cancelLatestCommittedText.
     */
    public AttributedCharacterIterator cancelLatestCommittedText(Attribute[] attributes) {
        return getReq().cancelLatestCommittedText(attributes);
    }

    /**
     * Calls the current client component's implementation of getSelectedText.
     */
    public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
        return getReq().getSelectedText(attributes);
    }

    private InputMethodRequests getReq() {
        if (haveActiveClient() && !useBelowTheSpotInput()) {
            return getClientComponent().getInputMethodRequests();
        } else {
            return getCompositionAreaHandler(false);
        }
    }

    // implements java.awt.im.spi.InputMethodContext.createInputMethodWindow
    public Window createInputMethodWindow(String title, boolean attachToInputContext) {
        InputContext context = attachToInputContext ? this : null;
        return createInputMethodWindow(title, context, false);
    }

    // implements java.awt.im.spi.InputMethodContext.createInputMethodJFrame
    public JFrame createInputMethodJFrame(String title, boolean attachToInputContext) {
        InputContext context = attachToInputContext ? this : null;
        return (JFrame)createInputMethodWindow(title, context, true);
    }

    static Window createInputMethodWindow(String title, InputContext context, boolean isSwing) {
        if (GraphicsEnvironment.isHeadless()) {
            throw new HeadlessException();
        }
        if (isSwing) {
            return new InputMethodJFrame(title, context);
        } else {
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            if (toolkit instanceof InputMethodSupport) {
                return ((InputMethodSupport)toolkit).createInputMethodWindow(
                    title, context);
            }
        }
        throw new InternalError("Input methods must be supported");
    }

    /**
     * @see java.awt.im.spi.InputMethodContext#enableClientWindowNotification
     */
    public void enableClientWindowNotification(InputMethod inputMethod, boolean enable) {
        super.enableClientWindowNotification(inputMethod, enable);
    }

  /**
   * Disables or enables decorations for the composition window.
   */
   void setCompositionAreaUndecorated(boolean undecorated) {
        if (compositionAreaHandler != null) {
            compositionAreaHandler.setCompositionAreaUndecorated(undecorated);
        }
   }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java InputMethodContext.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.