--- a/jdk/src/share/demo/jfc/CodePointIM/CodePointInputMethod.java Thu Jan 24 18:06:24 2013 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,499 +0,0 @@
-/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This source code is provided to illustrate the usage of a given feature
- * or technique and has been deliberately simplified. Additional steps
- * required for a production-quality application, such as security checks,
- * input validation and proper error handling, might not be present in
- * this sample code.
- */
-
-package com.sun.inputmethods.internal.codepointim;
-
-
-import java.awt.AWTEvent;
-import java.awt.Toolkit;
-import java.awt.Rectangle;
-import java.awt.event.InputMethodEvent;
-import java.awt.event.KeyEvent;
-import java.awt.font.TextAttribute;
-import java.awt.font.TextHitInfo;
-import java.awt.im.InputMethodHighlight;
-import java.awt.im.spi.InputMethod;
-import java.awt.im.spi.InputMethodContext;
-import java.io.IOException;
-import java.text.AttributedString;
-import java.util.Locale;
-
-
-/**
- * The Code Point Input Method is a simple input method that allows Unicode
- * characters to be entered using their code point or code unit values. See the
- * accompanying file README.txt for more information.
- *
- * @author Brian Beck
- */
-public class CodePointInputMethod implements InputMethod {
-
- private static final int UNSET = 0;
- private static final int ESCAPE = 1; // \u0000 - \uFFFF
- private static final int SPECIAL_ESCAPE = 2; // \U000000 - \U10FFFF
- private static final int SURROGATE_PAIR = 3; // \uD800\uDC00 - \uDBFF\uDFFF
- private InputMethodContext context;
- private Locale locale;
- private StringBuffer buffer;
- private int insertionPoint;
- private int format = UNSET;
-
- public CodePointInputMethod() throws IOException {
- }
-
- /**
- * This is the input method's main routine. The composed text is stored
- * in buffer.
- */
- public void dispatchEvent(AWTEvent event) {
- // This input method handles KeyEvent only.
- if (!(event instanceof KeyEvent)) {
- return;
- }
-
- KeyEvent e = (KeyEvent) event;
- int eventID = event.getID();
- boolean notInCompositionMode = buffer.length() == 0;
-
- if (eventID == KeyEvent.KEY_PRESSED) {
- // If we are not in composition mode, pass through
- if (notInCompositionMode) {
- return;
- }
-
- switch (e.getKeyCode()) {
- case KeyEvent.VK_LEFT:
- moveCaretLeft();
- break;
- case KeyEvent.VK_RIGHT:
- moveCaretRight();
- break;
- }
- } else if (eventID == KeyEvent.KEY_TYPED) {
- char c = e.getKeyChar();
-
- // If we are not in composition mode, wait a back slash
- if (notInCompositionMode) {
- // If the type character is not a back slash, pass through
- if (c != '\\') {
- return;
- }
-
- startComposition(); // Enter to composition mode
- } else {
- switch (c) {
- case ' ': // Exit from composition mode
- finishComposition();
- break;
- case '\u007f': // Delete
- deleteCharacter();
- break;
- case '\b': // BackSpace
- deletePreviousCharacter();
- break;
- case '\u001b': // Escape
- cancelComposition();
- break;
- case '\n': // Return
- case '\t': // Tab
- sendCommittedText();
- break;
- default:
- composeUnicodeEscape(c);
- break;
- }
- }
- } else { // KeyEvent.KEY_RELEASED
- // If we are not in composition mode, pass through
- if (notInCompositionMode) {
- return;
- }
- }
-
- e.consume();
- }
-
- private void composeUnicodeEscape(char c) {
- switch (buffer.length()) {
- case 1: // \\
- waitEscapeCharacter(c);
- break;
- case 2: // \\u or \\U
- case 3: // \\ux or \\Ux
- case 4: // \\uxx or \\Uxx
- waitDigit(c);
- break;
- case 5: // \\uxxx or \\Uxxx
- if (format == SPECIAL_ESCAPE) {
- waitDigit(c);
- } else {
- waitDigit2(c);
- }
- break;
- case 6: // \\uxxxx or \\Uxxxx
- if (format == SPECIAL_ESCAPE) {
- waitDigit(c);
- } else if (format == SURROGATE_PAIR) {
- waitBackSlashOrLowSurrogate(c);
- } else {
- beep();
- }
- break;
- case 7: // \\Uxxxxx
- // Only SPECIAL_ESCAPE format uses this state.
- // Since the second "\\u" of SURROGATE_PAIR format is inserted
- // automatically, users don't have to type these keys.
- waitDigit(c);
- break;
- case 8: // \\uxxxx\\u
- case 9: // \\uxxxx\\ux
- case 10: // \\uxxxx\\uxx
- case 11: // \\uxxxx\\uxxx
- if (format == SURROGATE_PAIR) {
- waitDigit(c);
- } else {
- beep();
- }
- break;
- default:
- beep();
- break;
- }
- }
-
- private void waitEscapeCharacter(char c) {
- if (c == 'u' || c == 'U') {
- buffer.append(c);
- insertionPoint++;
- sendComposedText();
- format = (c == 'u') ? ESCAPE : SPECIAL_ESCAPE;
- } else {
- if (c != '\\') {
- buffer.append(c);
- insertionPoint++;
- }
- sendCommittedText();
- }
- }
-
- private void waitDigit(char c) {
- if (Character.digit(c, 16) != -1) {
- buffer.insert(insertionPoint++, c);
- sendComposedText();
- } else {
- beep();
- }
- }
-
- private void waitDigit2(char c) {
- if (Character.digit(c, 16) != -1) {
- buffer.insert(insertionPoint++, c);
- char codePoint = (char) getCodePoint(buffer, 2, 5);
- if (Character.isHighSurrogate(codePoint)) {
- format = SURROGATE_PAIR;
- buffer.append("\\u");
- insertionPoint = 8;
- } else {
- format = ESCAPE;
- }
- sendComposedText();
- } else {
- beep();
- }
- }
-
- private void waitBackSlashOrLowSurrogate(char c) {
- if (insertionPoint == 6) {
- if (c == '\\') {
- buffer.append(c);
- buffer.append('u');
- insertionPoint = 8;
- sendComposedText();
- } else if (Character.digit(c, 16) != -1) {
- buffer.append("\\u");
- buffer.append(c);
- insertionPoint = 9;
- sendComposedText();
- } else {
- beep();
- }
- } else {
- beep();
- }
- }
-
- /**
- * Send the composed text to the client.
- */
- private void sendComposedText() {
- AttributedString as = new AttributedString(buffer.toString());
- as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT,
- InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT);
- context.dispatchInputMethodEvent(
- InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
- as.getIterator(), 0,
- TextHitInfo.leading(insertionPoint), null);
- }
-
- /**
- * Send the committed text to the client.
- */
- private void sendCommittedText() {
- AttributedString as = new AttributedString(buffer.toString());
- context.dispatchInputMethodEvent(
- InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
- as.getIterator(), buffer.length(),
- TextHitInfo.leading(insertionPoint), null);
-
- buffer.setLength(0);
- insertionPoint = 0;
- format = UNSET;
- }
-
- /**
- * Move the insertion point one position to the left in the composed text.
- * Do not let the caret move to the left of the "\\u" or "\\U".
- */
- private void moveCaretLeft() {
- int len = buffer.length();
- if (--insertionPoint < 2) {
- insertionPoint++;
- beep();
- } else if (format == SURROGATE_PAIR && insertionPoint == 7) {
- insertionPoint = 8;
- beep();
- }
-
- context.dispatchInputMethodEvent(
- InputMethodEvent.CARET_POSITION_CHANGED,
- null, 0,
- TextHitInfo.leading(insertionPoint), null);
- }
-
- /**
- * Move the insertion point one position to the right in the composed text.
- */
- private void moveCaretRight() {
- int len = buffer.length();
- if (++insertionPoint > len) {
- insertionPoint = len;
- beep();
- }
-
- context.dispatchInputMethodEvent(
- InputMethodEvent.CARET_POSITION_CHANGED,
- null, 0,
- TextHitInfo.leading(insertionPoint), null);
- }
-
- /**
- * Delete the character preceding the insertion point in the composed text.
- * If the insertion point is not at the end of the composed text and the
- * preceding text is "\\u" or "\\U", ring the bell.
- */
- private void deletePreviousCharacter() {
- if (insertionPoint == 2) {
- if (buffer.length() == 2) {
- cancelComposition();
- } else {
- // Do not allow deletion of the leading "\\u" or "\\U" if there
- // are other digits in the composed text.
- beep();
- }
- } else if (insertionPoint == 8) {
- if (buffer.length() == 8) {
- if (format == SURROGATE_PAIR) {
- buffer.deleteCharAt(--insertionPoint);
- }
- buffer.deleteCharAt(--insertionPoint);
- sendComposedText();
- } else {
- // Do not allow deletion of the second "\\u" if there are other
- // digits in the composed text.
- beep();
- }
- } else {
- buffer.deleteCharAt(--insertionPoint);
- if (buffer.length() == 0) {
- sendCommittedText();
- } else {
- sendComposedText();
- }
- }
- }
-
- /**
- * Delete the character following the insertion point in the composed text.
- * If the insertion point is at the end of the composed text, ring the bell.
- */
- private void deleteCharacter() {
- if (insertionPoint < buffer.length()) {
- buffer.deleteCharAt(insertionPoint);
- sendComposedText();
- } else {
- beep();
- }
- }
-
- private void startComposition() {
- buffer.append('\\');
- insertionPoint = 1;
- sendComposedText();
- }
-
- private void cancelComposition() {
- buffer.setLength(0);
- insertionPoint = 0;
- sendCommittedText();
- }
-
- private void finishComposition() {
- int len = buffer.length();
- if (len == 6 && format != SPECIAL_ESCAPE) {
- char codePoint = (char) getCodePoint(buffer, 2, 5);
- if (Character.isValidCodePoint(codePoint) && codePoint != 0xFFFF) {
- buffer.setLength(0);
- buffer.append(codePoint);
- sendCommittedText();
- return;
- }
- } else if (len == 8 && format == SPECIAL_ESCAPE) {
- int codePoint = getCodePoint(buffer, 2, 7);
- if (Character.isValidCodePoint(codePoint) && codePoint != 0xFFFF) {
- buffer.setLength(0);
- buffer.appendCodePoint(codePoint);
- sendCommittedText();
- return;
- }
- } else if (len == 12 && format == SURROGATE_PAIR) {
- char[] codePoint = {
- (char) getCodePoint(buffer, 2, 5),
- (char) getCodePoint(buffer, 8, 11)
- };
- if (Character.isHighSurrogate(codePoint[0]) && Character.
- isLowSurrogate(codePoint[1])) {
- buffer.setLength(0);
- buffer.append(codePoint);
- sendCommittedText();
- return;
- }
- }
-
- beep();
- }
-
- private int getCodePoint(StringBuffer sb, int from, int to) {
- int value = 0;
- for (int i = from; i <= to; i++) {
- value = (value << 4) + Character.digit(sb.charAt(i), 16);
- }
- return value;
- }
-
- private static void beep() {
- Toolkit.getDefaultToolkit().beep();
- }
-
- public void activate() {
- if (buffer == null) {
- buffer = new StringBuffer(12);
- insertionPoint = 0;
- }
- }
-
- public void deactivate(boolean isTemporary) {
- if (!isTemporary) {
- buffer = null;
- }
- }
-
- public void dispose() {
- }
-
- public Object getControlObject() {
- return null;
- }
-
- public void endComposition() {
- sendCommittedText();
- }
-
- public Locale getLocale() {
- return locale;
- }
-
- public void hideWindows() {
- }
-
- public boolean isCompositionEnabled() {
- // always enabled
- return true;
- }
-
- public void notifyClientWindowChange(Rectangle location) {
- }
-
- public void reconvert() {
- // not supported yet
- throw new UnsupportedOperationException();
- }
-
- public void removeNotify() {
- }
-
- public void setCharacterSubsets(Character.Subset[] subsets) {
- }
-
- public void setCompositionEnabled(boolean enable) {
- // not supported yet
- throw new UnsupportedOperationException();
- }
-
- public void setInputMethodContext(InputMethodContext context) {
- this.context = context;
- }
-
- /*
- * The Code Point Input Method supports all locales.
- */
- public boolean setLocale(Locale locale) {
- this.locale = locale;
- return true;
- }
-}