マイペースなプログラミング日記

x86エミュレータやFPGA、WebGLにお熱なd-kamiがマイペースに書くブログ

日本語入力コンポーネント

JavaのSwingで日本語を入力、変換できるコンポーネントを作成したので、
そのソースコードを載せてみました。
日本語入力モードにしておかなければ、何も起こりません。
日本語を入力してEnterを押せば1行分したにその文字列が表示されます。
JEditorPaneやJTextPaneに満足できればこんなことやる必要もないのだけど…


import java.awt.*;
import java.awt.event.*;
import java.awt.im.*;
import java.awt.font.*;
import javax.swing.*;
import java.text.*;

public class InputComponent extends JComponent
implements InputMethodListener, InputMethodRequests{

String commit;
String str;
String old;
TextLayout textLayout;

public static void main(String[] args){
JFrame f = new JFrame();

InputComponent input = new InputComponent();

f.getContentPane().add(input);
f.setSize(300, 250);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public InputComponent(){
super();

addInputMethodListener(this);
}

public InputMethodRequests getInputMethodRequests(){
return this;
}

public void inputMethodTextChanged(InputMethodEvent ime){
AttributedCharacterIterator iter = ime.getText();
if(iter == null){
str = null;
textLayout = null;
repaint();
return;
}

if (iter.getEndIndex() > iter.getBeginIndex()) {
FontRenderContext context = ( (Graphics2D)getGraphics()).getFontRenderContext();
textLayout = new TextLayout(iter, context);
}

int start = iter.getBeginIndex();
int end = iter.getEndIndex();

char[] tmp = new char[end - start];
int i = 0;

for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
// System.out.print(c);
tmp[i++] = c;
}

// System.out.println();
str = new String(tmp);

//前回と同じ文字列なら確定文字列とする
if(str.equals(old))
commit = str;

old = str;
repaint();
}

//変換候補ウインドウの表示位置を返す
public Rectangle getTextLocation(TextHitInfo offset){
System.out.println("getTextLocation");
System.out.println(offset.getInsertionIndex());
return new Rectangle(getX() + 50, getY() - 50, 100, 100);
}

//フォーカスを取得できるようにする
public boolean isFocusable(){
return true;
}

public void paint(Graphics g){
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);

//変換中の文字列があれば表示する
if (textLayout != null) {
textLayout.draw( (Graphics2D) g, 0, 16);
}

//前回確定した日本語の文字列を表示する
if(commit != null)
g.drawString(commit, 0, 32);
}

public void caretPositionChanged(InputMethodEvent ime){
System.out.println(ime.getCaret().getCharIndex());
}

public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes){
System.out.println("cancelLatestCommittedText");
return null;
}

public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, AttributedCharacterIterator.Attribute[] attributes){
System.out.println("getCommittedText");
return null;
}

public int getCommittedTextLength(){
System.out.println("getCommitedTextLength");
return 0;
}

public int getInsertPositionOffset(){
System.out.println("getInsertPositionOffset");
return 0;
}

public TextHitInfo getLocationOffset(int x, int y){
System.out.println("getLocationOffset");
return null;
}

public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes){
System.out.println("getSelectedText");
return null;
}
}