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

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

JTextFieldの変換候補ウインドウの位置を指定する

JTextFieldの漢字変換時にでる変換候補ウインドウの位置を指定したい!というリクエストがあったので、試しに自分で作ってみた。JTextFieldにあるgetInputMethodRequestsで返るInputMethodRequestsにgetTextLocationというメソッドがあり、これの返り値のRectangleが変換候補ウインドウの表示領域となる。まじめにInputMethodRequestsを実装するのは大変だと思うので、今回は手抜きしてJTextFieldのデフォルトのInputMethodRequestsを使わせてもらった。しかし、このサンプルだと動作がわかりづらいような...以下ソースコード

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodRequests;

import javax.swing.JFrame;
import javax.swing.JTextField;

import java.text.AttributedCharacterIterator;

public class MyTextField extends JTextField{
    MyInputMethodRequests myRequest = new MyInputMethodRequests();
    
    public InputMethodRequests getInputMethodRequests(){
        InputMethodRequests request = super.getInputMethodRequests();
        myRequest.setInputMethodRequests(request);
        
        return myRequest;
    }
    
    public class MyInputMethodRequests implements InputMethodRequests{
        private InputMethodRequests defaultRequest;

        public void setInputMethodRequests(InputMethodRequests defaultRequest){
            this.defaultRequest = defaultRequest;
        }
        
        public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes){
            return defaultRequest.cancelLatestCommittedText(attributes);
        }
        
        public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, AttributedCharacterIterator.Attribute[] attributes){
            return defaultRequest.getCommittedText(beginIndex, endIndex, attributes);
        }
        
        public int getCommittedTextLength(){
            return defaultRequest.getCommittedTextLength();
        }
        
        public int getInsertPositionOffset(){
            return defaultRequest.getInsertPositionOffset();
        }
        
        public TextHitInfo getLocationOffset(int x, int y){
            return defaultRequest.getLocationOffset(x, y);
        }
        
        public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes){
            return defaultRequest.getSelectedText(attributes);
        }
        
        public Rectangle getTextLocation(TextHitInfo offset){
            Rectangle rect = defaultRequest.getTextLocation(offset);
            
            //ここで変換候補ウインドウの位置を指定する
            rect.setLocation(getX(), getY());
            
            return rect;
        }
    }
    
    public static void main(String[] args){
        JFrame frame = new JFrame();
        MyTextField field = new MyTextField();
        field.setPreferredSize(new Dimension(240, 24));
        
        frame.add(field);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.setVisible(true);
    }
}