Package org.apache.harmony.awt.im

Source Code of org.apache.harmony.awt.im.CompositionWindow$ActiveClient

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
* @author Dmitry A. Durnev
*/
package org.apache.harmony.awt.im;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.InputMethodEvent;
import java.awt.event.KeyEvent;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodRequests;
import java.text.CharacterIterator;

import javax.swing.text.DefaultCaret;

import org.apache.harmony.awt.ComponentInternals;
import org.apache.harmony.awt.text.InputMethodListenerImpl;
import org.apache.harmony.awt.text.InputMethodRequestsImpl;
import org.apache.harmony.awt.text.TextKit;

/**
* Active IM client used to implement "below-the-spot" input style
* with active clients & "root-window" style with passive clients.
*/
class CompositionWindow extends IMWindow {
    private class ActiveClient extends TextField {

        private final InputMethodRequestsImpl imRequests;
        private final InputMethodListenerImpl imListener;
        private final DefaultCaret caret;
       
        ActiveClient() throws HeadlessException {
            // prevent IM invocation on this component
            enableInputMethods(false);
            ComponentInternals ci = ComponentInternals.getComponentInternals();
            TextKit textKit = ci.getTextKit(this);
            caret = (DefaultCaret) textKit.getCaret();
            caret.setBlinkRate(0);
            caret.setVisible(true);
            imRequests = new InputMethodRequestsImpl(textKit) {
                @Override
                public TextHitInfo getLocationOffset(int x, int y) {
                    if (!isShowing()) {
                        return null;
                    }
                    return super.getLocationOffset(x, y);
                }
            };
            imListener = new InputMethodListenerImpl(textKit) {
                @Override
                public void inputMethodTextChanged(InputMethodEvent ime) {                  
                    super.inputMethodTextChanged(ime);
                    // create KEY_TYPED event for each committed char
                    // and send it to passive client or just
                    // redirect this event to active client
                    if (client == null) {
                        return;
                    }
                    InputMethodRequests imr = client.getInputMethodRequests();
                    if (imr != null) {
                        if (IMManager.belowTheSpot()) {
                            // position window below the spot:
                            TextHitInfo offset = TextHitInfo.leading(0);
                            Rectangle textLoc = imr.getTextLocation(offset);
                            setLocationBelow(textLoc);                          
                        } else {
                            client.dispatchEvent(ime);
                            return;
                        }
                    }
                    sendCommittedText(ime);
                   
                }
            };
            addInputMethodListener(imListener);
        }
       
        private void sendCommittedText(InputMethodEvent ime) {
            int n = ime.getCommittedCharacterCount();
            // remove each committed char from text component
            if (n > 0) {
                setText(getText().substring(n));
            }
            char c;
            CharacterIterator text = ime.getText();
            if (text != null) {
                c = text.first();
                while (n-- > 0) {
                    sendChar((Component) ime.getSource(), ime.getWhen(), c);                   
                    c = text.next();
                }
            }
           
        }

        private void sendChar(Component src, long when, char c) {
            KeyEvent ke = new KeyEvent(src, KeyEvent.KEY_TYPED, when,
                                       0, KeyEvent.VK_UNDEFINED, c);
            src.dispatchEvent(ke);
           
        }

        @Override
        public InputMethodRequests getInputMethodRequests() {
            return imRequests;
        }
       
        @Override
        public void paint(Graphics g) {
            caret.paint(g);
        }
   
    }
   
    private Component client;
    private final ActiveClient activeClient;

    public CompositionWindow(Component client) {
        setClient(client);
        activeClient = new ActiveClient();
        add(activeClient);
        setSize(500, 40);
        // use root window input style by default:
        Dimension screenSize = getScreenSize();
        int x = screenSize.width - getWidth();
        int y = screenSize.height - 3 * getHeight();
        setLocation(x, y);
    }

    private Dimension getScreenSize() {
        return Toolkit.getDefaultToolkit().getScreenSize();
    }
   
    @Override
    public InputMethodRequests getInputMethodRequests() {
        return getActiveClient().getInputMethodRequests();
    }
   
    Component getActiveClient() {
        return activeClient;
    }

    final void setClient(Component client) {
        this.client = client;
    }

    boolean isEmpty() {
        return (activeClient.getText().length() == 0);
    }

    private void setLocationBelow(Rectangle textLoc) {
        Point loc = textLoc.getLocation();
        loc.translate(0, textLoc.height);       
        Dimension screenSize = getScreenSize();
        int h = getHeight();
        int w = getWidth();
        if (loc.y + h > screenSize.height) {
            loc.y = textLoc.y - h;
        }           
        if (loc.x + w > screenSize.width) {
            loc.x = screenSize.width - w;
        }   
       setLocation(loc);
    }

}
TOP

Related Classes of org.apache.harmony.awt.im.CompositionWindow$ActiveClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.