입력 메소드 클라이언트 API 튜토리얼 - xrath.com 에서 번역됨

#
입력 메소드 클라이언트 API 튜토리얼

## 목차

1. 액티브 클라이언트 컴퍼넌트의 구현
   - 입력 메소드 이벤트의 처리
   - 입력 메소드의 반전 표시 속성의 처리
   - 입력 메소드의 요구의 처리
   - 입력 조작의 종료
2. 액티브 클라이언트 컴퍼넌트의 확장
   - 텍스트의 부가 속성의 처리
   - 사적인 입력 문맥의 작성
   - 입력 메소드의 선택
   - 유효한 문자 부분집합의 설정
   - 엔진에 고유한 기능의 사용
3. 비클라이언트의 구현
4. 샘플 코드

## 1. 액티브 클라이언트 컴퍼넌트의 구현

입력 메소드 클라이언트 API 를 사용하면(자), 온더 스포트 입력등의 통합 텍스트 입력 사용자 인터페이스를 클라이언트 컴퍼넌트에 구현할 수 있습니다. API 에 의해 정의되는 이벤트와 메소드에 의해, 클라이언트 컴퍼넌트와 입력 메소드의 사이에서의 원활한 통신을 합니다. 또, API 를 사용하면(자), 클라이언트 컴퍼넌트는, 특정의 언어를 위한 입력 메소드를 요구할 수 있습니다.

API 에서는, 텍스트가 draw 되는 방법이나 장소에 대한 전제는 없기 때문에, 오버더 스포트 편집 등, 다른 입력 형식의 구현에 API 를 사용할 수도 있습니다. 오버더 스포트 편집의 입력 형식에서는, 변환되는 텍스트는, 전후의 텍스트와 통합되어 포맷 되는 것이 아니라, 주위의 텍스트를 덮어 가리도록(듯이) 위에 draw 됩니다.

임의의 클라이언트 컴퍼넌트 클래스는, 입력 메소드 클라이언트 API 의 액티브 클라이언트가 될 수가 있어 다음의 스텝을 실행해 통합 텍스트 입력 사용자 인터페이스를 지원할 수 있습니다.

- `InputMethodListener` 인터페이스를 구현해 현재의 입력 메소드에 의해 생성된 `InputMethodEvents` 의 착신을 처리해, 청취자를 등록한다
- `InputMethodRequests` 인터페이스를 구현해 `getInputMethodRequests` 를 오버라이드(override) 해, 요구 핸들러를 돌려준다
- 변환 텍스트와 함께 `InputMethodHighlight` 속성을 포함해, 그것을 draw 루틴에 건네준다
- 모든 텍스트의 확정을 요구하는 조작을 사용자가 실행한 시점에서, 입력 조작을 종료한다

클라이언트 컴퍼넌트에서는, 필요에 따라서 다음의 기능도 사용할 수 있습니다.

- 입력 메소드가 작성한 것 외의 텍스트 속성을 포함해, 텍스트가 요구되었을 때에 그것을 돌려준다
- 같은 윈도우외의 컴퍼넌트와 입력 문맥을 공유하는 대신에, 사적인 입력 문맥을 작성한다
- 편집하는 텍스트의 언어 등에 기초를 두어, 입력 메소드를 선택한다
- 예상되는 문자 부분집합을 설정한다

입력 문맥의 셋업, 문맥의 기동과 정지, 입력 메소드에의 이벤트의 발송 등은 모두 AWT 가 자동적으로 처리하므로, 클라이언트 컴퍼넌트가 처리할 필요는 없습니다.

### 입력 메소드 이벤트의 처리

Input Method Framework 는, 이벤트 클래스 `InputMethodEvent` 를 제공해, 입력 메소드와 텍스트 컴퍼넌트간의 통신을 지원합니다. 클래스에는, 2 종류가 다른 이벤트, 텍스트 변경과 caret 변경이 있습니다. 이벤트 청취자 인터페이스 `InputMethodListener` 는, 이것들 2 개의 이벤트를 지원하고 있습니다. 액티브 클라이언트의 컴퍼넌트는,`InputMethodListener` 인터페이스를 구현해, 청취자를 등록해, 양쪽 모두의 이벤트를 처리할 필요가 있습니다.

사용자의 입력 텍스트 (반전 표시)가 변화하면(자), 또는 변환되고 있는 텍스트의 내부의 caret의 위치가 바뀌면(자),`InputMethodEvent` 의 인스턴스가 클라이언트 컴퍼넌트에 보내집니다. caret만이 변화했을 때에 송신되는 이벤트는, 텍스트 변경의 이벤트로부터 텍스트 정보만이 제외해져 간략화된 것이므로, 이하에서는 텍스트 변경 이벤트에 대해 설명합니다.

텍스트 변경을 전하는 이벤트에는, 변환 텍스트와 확정 텍스트의 어느 쪽인지 한편 혹은 양쪽 모두를 나타내는 `AttributedCharacterIterator` 의 인스턴스에의 참조가 포함되어 있습니다. 이벤트의 확정 문자수의 값은, 반복자의 범위내의 몇개의 문자가 확정된 텍스트인지를 지정합니다. 나머지의 문자는 모두 변환 텍스트입니다. 확정 텍스트는 항상, 변환 텍스트보다 우선됩니다. 컴퍼넌트에 이전의 변환 텍스트가 없는 경우는, 확정되고 변환된 텍스트는 선택된 임의의 텍스트에 취해 대신하는지, 컴퍼넌트의 텍스트의 현재의 삽입 위치에 삽입됩니다. 이전의 변환 텍스트가 있는 경우는, 그 이전의 변환 텍스트 전체가, 새롭게 확정되고 변환된 텍스트로 옮겨집니다. 삽입 포인트가, 확정 텍스트의 마지막에 이동합니다. 갱신된 텍스트의 재draw는, 클라이언트 컴퍼넌트가 실시합니다.

이벤트에는, 변환 텍스트내의 caret의 현재 위치 (caret를 표시하지 않는 경우는 null)에 대한 정보, 및 변환 텍스트 중(안)에서 표시할 필요가 있는 가장 중요한 부분 (입력 메소드에 의한 추천 부분이 없는 경우는 null)에 대한 정보도 포함됩니다.

### 입력 메소드의 반전 표시 속성의 처리

일반적으로, 텍스트 컴퍼넌트는, 표준의 텍스트 레이아웃과 draw 기능을 사용해, 편집되고 있는 텍스트의 일부로서 변환 텍스트를 draw 합니다. 다만, 변환의 현재 상태를 나타내기 (위해)때문에, 반전 표시 스타일의 속성을 변환 텍스트에 추가할 필요가 있습니다. 시스템에서는, 이러한 스타일 속성은 추상적인 스타일 (변환되지 않고 선택되어 있지 않은 텍스트, 변환되고 있어 선택되고 있는 텍스트등)로서 정의되고 있어 플랫폼에 의존하는 구체적인 스타일 (예를 들어, 회색으로 2 픽셀의 밑줄)에 내부적으로 매핑 됩니다.

반전 표시 속성은,`InputMethodHighlight` 클래스에 의해 표현됩니다. 이 클래스의 인스턴스는, 변환 텍스트를 나타내는 AttributedCharacterIterator 의 인스턴스의 속성치로서 사용됩니다. 텍스트 컴퍼넌트는, 변환 텍스트와 함께 이러한 속성을 포함해, 변환 텍스트를 draw 하려면 , 텍스트와 속성을 draw 루틴에 건네줍니다. `AttributedCharacterIterator` 를 받아들이는 `drawString` 메소드를 사용하는 일도, 반복자로부터 `TextLayout` 를 작성해 그 draw 메소드를 사용하는 일도, 어느쪽이나 가능합니다. 이러한 draw 메소드는, Input Method Framework 와 통신해, 추상적으로부터 구체적인 반전 표시 스타일에 매핑 합니다. 따라서, 이러한 메소드를 사용하는 텍스트 컴퍼넌트는, 일반적으로, 입력 메소드에서의 반전 표시의 내부적인 상세하게 관련될 필요가 없습니다. 텍스트 컴퍼넌트가 다른 방식을 사용해 텍스트를 렌더링 하는 경우는, 입력 메소드의 반전 표시로 구체적인 스타일에 관한 정보를 조사해 정보가 없으면,`Toolkit.mapInputMethodHighlight` 를 사용해 구체적인 스타일에 매핑 할 필요가 있습니다.

입력 메소드에 따라서는, 강조 표시를 「주석」으로서 취급하는 경우가 있습니다. 주석은, 지정된 범위의 텍스트에 적용되는 속성입니다만, 부분 범위 또는 범위의 연결에 대해서는 적용되지 않습니다. 주석은,`InputMethodHighlight` 인스턴스를 `Annotation` 인스턴스에 랩 하는 것에 의해 표현됩니다. 입력 메소드는, 주석의 반전 표시를 사용해 복수의 텍스트 세그먼트(segment)에 단락지어, 유니트 마다 변환할 수도 있습니다. 세그먼트(segment)를 명시하기 위해서, 세그먼트(segment)간의 짧은 단락에 가세해 밑줄을 사용하는 등 해, 반전 표시를 draw 하는 플랫폼도 있습니다. 텍스트 컴퍼넌트는, 입력 메소드의 반전 표시를, 그것이 `Annotation` 의 인스턴스내에 랩 될지 어떨지 에 관계없이, 처리할 수 없으면 안됩니다. 텍스트 컴퍼넌트가 행의 반환을 구현하는 경우는, 반전 표시의 주석이 적용되는 범위가, 행 경계를 넘을 때 특별히 주의할 필요가 있습니다. `AttributedString` 내에서 구현되는 경우등의 일반적으로의 동작에서는, 속성이 부분 범위에 적용되지 않기 때문에, 속성을 방폐합니다. 그러나 이 경우는, 표시상의 단락이 있는 것만으로 논리상의 단락은 없기 때문에, 반전 표시를 보존할 필요가 있습니다. 이 반전 표시는, 다른 행에 draw 되는 부분 범위에 적용되었는지와 같이 취급할 필요가 있습니다. 이것은, 목적의 범위의 부분 범위에 대해서도 반전 표시의 주석을 돌려주는 방법으로 `AttributedCharacterIterator` 를 구현하는 것으로써 실현될 수 있습니다.

### 입력 메소드의 요구의 처리

입력 조작을 실시하기 위해서(때문에)는, 입력 메소드는 컴퍼넌트의 정보에 액세스 할 필요가 있습니다. 예를 들어, 선택사항의 리스트를 표시할 수 있는 장소를 알 필요가 있습니다.

따라서, 액티브 클라이언트 컴퍼넌트는,`InputMethodRequests` 인터페이스를 구현해,`getInputMethodRequests` 를 오버라이드(override) 해 요구 핸들러를 돌려주지 않으면 안됩니다. 인터페이스에는, 다음의 조작을 실시하는 메소드가 포함됩니다.

- 화면상의 좌표와 변환 텍스트내의 오프셋(offset)의 사이의 변환
- 컴퍼넌트의 지정된 텍스트의 취득
- 마지막에 확정된 텍스트의 캔슬
- 컴퍼넌트의 확정 텍스트내의 삽입 위치의 취득

### 입력 조작의 종료

일반적으로, 입력 메소드는, 입력 조작을 종료시키는 사용자의 행위를 인식합니다. 예를 들어, 미확정의 모든 텍스트를 확정하는 조작 등입니다. 다만, 입력 조작의 종료가 필요한 조작을 개시하는 사용자의 행위안에는, 입력 메소드를 인식할 수 없는 것도 있습니다. 텍스트를 포함한 문서의 보존은, 입력 메소드를 인식할 수 없는 행위의 예입니다. 그러한 경우, 컴퍼넌트는, 입력 문맥의 `endComposition` 메소드를 명시적으로 호출할 필요가 있습니다.

## 2. 액티브 클라이언트 컴퍼넌트의 확장

### 텍스트의 부가 속성의 처리

입력 메소드는, 텍스트 컴퍼넌트에 보내는 텍스트에, 반전 표시 정보 이외의 속성을 부가하는 경우가 있습니다. 이러한 속성안에는, 컴퍼넌트에 있어 유용한 정보가 포함되어 있습니다. 또,`InputMethodRequest` 메소드로 돌려주는 것으로, 입력 메소드의 성능이 향상하는 경우도 있습니다. 후자의 이유로부터, 텍스트 컴퍼넌트에는, 텍스트의 편집을 하고 있는 동안 이 속성 정보를 보관 유지해, 요구된 텍스트와 함께 이 정보를 돌려주는 것이 추천 됩니다.

`AttributedCharacterIterator.Attribute` 클래스에서는, 다음의 공통 속성이 정의되고 있습니다.

- `LANGUAGE` - 텍스트의 언어,`Locale` 객체로서 지정된다
- `READING` - 음성 표현 (일본어에서의 「읽기」),`String` 객체로서 지정된다
- `INPUT_METHOD_SEGMENT` - 입력 메소드가 사용하는 분할 정보

Java 프로그램 언어로 기술되는 입력 메소드에서는, 속성이 추가될 가능성이 있습니다.

### 사적인 입력 문맥의 작성

디폴트에서는, 윈도우의 인스턴스 마다 1 개의 `InputContext` 의 인스턴스가 작성되어, 윈도우의 포함 관계의 계층에 포함되는 모든 컴퍼넌트가 이 입력 문맥을 공유합니다. 이것에 의해, 전체로 작성되는 인스턴스의 수가 줄어들어, 입력 메소드는, 이 윈도우로 입력되는 모든 텍스트에 대한 정보를 조합해 이용할 수 있습니다. 입력 메소드에서는, 지금까지의 입력된 텍스트에 대한 정보를 사용해, 변환의 정밀도를 높이고 있습니다. 다만, 이것은, 1 개의 윈도우 중(안)에서는 한 번에 1 개의 입력 조작 밖에 용서되지 않고, 어느 텍스트 컴퍼넌트로부터 다른 텍스트 컴퍼넌트에 포커스가 옮기려면 텍스트의 확정이 필요한 것을 의미합니다. 이러한 동작이 적절하지 않은 경우는, 텍스트 컴퍼넌트로 독자적인 입력 문맥의 인스턴스를 작성해,`getInputContext` 를 오버라이드(override) 해, 작성한 인스턴스를 돌려줄 수가 있습니다. 독자적인 입력 문맥을 가지지 않는 컴퍼넌트는, 부모의 입력 문맥을 사용합니다.

### 입력 메소드의 선택

텍스트 컴퍼넌트에서는, 입력 문맥의 `selectInputMethod` 오퍼레이션을 사용해, 특정의 언어 또는 로케일에 대한 입력 메소드를 선택할 수 있습니다. 예를 들어, 텍스트안이 있는 부분을 사용자가 클릭했을 경우, 그 개소와 같은 언어에서의 입력 조작의 계속을 사용자가 희망하고 있다고 생각되므로, 입력 메소드 선택의 기능이 도움이 됩니다. 또는, 특정의 언어에 의한 텍스트 입력만을 어플리케이션이 허가하고 있는 것을, 텍스트 컴퍼넌트가 인식하고 있는 경우도 있습니다.

### 유효한 문자 부분집합의 설정

텍스트 컴퍼넌트에서는, 입력 문맥의 `setCharacterSubsets` 오퍼레이션을 사용해, 입력치로서 유효한 문자를 입력 메소드에 통지할 수 있습니다. 예를 들어, 데이타베이스 어플리케이션에서는, 필드에 의해, 히라가나만, 알파벳만, 또는 임의의 종류의 문자와 같이, 입력을 받아들이는 문자가 정해져 있는 경우가 있습니다. 입력 메소드에 이 정보를 건네주는 것으로, 입력할 수 있는 문자의 범위를 제한하거나 특정의 문자 부분집합만을 전문에 지원하는 다른 입력 모드로 전환하거나 하는 처리를, 입력 메소드를 실시할 수 있게 됩니다.

### 엔진에 고유한 기능의 사용

입력 메소드에 따라서는, Input Method Framework API 를 개입시켜 이용 가능하게 할 수 없는 기능을 클라이언트 컴퍼넌트에 제공하는 일이 있습니다. 이러한 기능은, 「입력 메소드 컨트롤 객체」를 개입시켜 제공할 수 있습니다. 입력 메소드의 개발자는, 이러한 객체의 인터페이스를 공개할 필요가 있습니다. 클라이언트 컴퍼넌트로 추가의 기능을 이용하는 경우는, 그 컴퍼넌트로부터 `InputContext.getInputMethodControlObject` 를 호출해, 반환된 객체가 기존의 컨트롤 객체 클래스의 인스턴스일지 어떨지를 확인합니다. 확인할 수 있었을 경우는, 그 메소드를 호출합니다.

## 3. 비클라이언트의 구현

디폴트에서는, 키 이벤트를 처리하는 컴퍼넌트는 모두, Input Method Framework 의 클라이언트가 됩니다. 즉, 컴퍼넌트에서는 입력 메소드의 지원가 유효하게 됩니다. 경우에 따라서는, 입력 메소드에 의한 처리를 받지 않는 입력이, 컴퍼넌트로 필요하게 되는 일이 있습니다. 예를 들어, 게임에서는, 키보드 이벤트를 직접 해석해야 하는 경우가 있습니다. 이러한 컴퍼넌트에서는,`enableInputMethods (false)` 를 호출해, 이벤트가 입력 메소드에 전송 되지 않게 합니다.

## 4. 샘플 코드

이 샘플 코드에서는, Input Method Framework 를 사용해 이용 가능한, 종류가 다른 입력 메소드 클라이언트인 액티브 클라이언트, 패시브 클라이언트, 비클라이언트, 및 피어 텍스트 클라이언트를 구현하는 방법을 나타냅니다.

- 애플릿 - Java 2 를 사용할 수 있는 브라우저로 이 애플릿을 실행하면(자), 각종의 클라이언트 컴퍼넌트를 체험할 수 있다
- Javadoc
  - LWTextComponent - 액티브 클라이언트에 확장할 수 있는 경량 텍스트 편집 컴퍼넌트의 구조의 설명
  - ActiveClient - 액티브 클라이언트 컴퍼넌트의 구조의 설명
- 원시 코드
  - IMFDemo.java - 각종의 클라이언트 컴퍼넌트를 포함한 애플릿/어플리케이션
  - LWTextComponent.java - 입력 메소드를 인식하지 않지만, 액티브 클라이언트에 확장할 수 있는 경량 텍스트 편집 컴퍼넌트
  - ActiveClient.java - LWTextComponent 의 액티브 클라이언트 컴퍼넌트에의 확장
  - PeeredTextArea.java - 피어 텍스트 컴퍼넌트

Copyright © 2004 Sun Microsystems, Inc. All Rights Reserved. 연락처 | Java Software