SwingXプロジェクトの解説も、今月が最終回です。今月はコンポーネントを使いやすくするための機能を紹介します。

 SwingXプロジェクトの第1回で紹介しましたが、SwingXプロジェクトのコンポーネントはコンポジッションを使用して機能を追加することができます。例として、第1回ではコンポーネントの修飾を行うPainterインタフェースを紹介しました。

 同じようにコンポジッションで追加できる機能はまだあります。そこで、今月はコンボボックスやテーブルなどで使用できる、オートコンプリート、ハイライト、検索の3種類の機能について紹介していきます。

オートコンプリート

 テキストフィールドなどで文字入力しているとき、入力した文字に応じて候補が表示されることがあります。これをオートコンプリート、もしくは自動補完と呼ばれることは読者の皆さんはご承知でしょう。入力しようとしている文字列があやふやでも、候補から選べるのでとても便利です。

 しかし、Swingでオートコンプリートを行うのはなかなか大変です。

 そこで、SwingXプロジェクトで提供しているオートコンプリートの機能を使ってみましょう。現状、SwingXプロジェクトでは次の5種類のコンポーネントに対してオートコンプリート機能を付加できます。

  • JComboBox
  • JList
  • JTextField, JTextArea, JEditorPane

 ここではJComboBoxクラスとJTextFieldクラスにオートコンプリート機能を付加してみます。

JComboBoxクラスに対するオートコンプリート

 オートコンプリート機能を付加するのはとても簡単です。簡単なサンプルで確かめてみましょう。

サンプルのソース
AutoCompletableComboBox.java

 このサンプルは、コンボボックスで選択した文字列をラベルで表示するというだけの簡単なサンプルです。

リスト1●AutoCompletablleComboBox.javaのコード
public class AutoCompletableComboBox {
    private String[] keywords = new String[] {
        "",
        "abstract", "assert",       "boolean",  "break",
        "byte",     "case",         "catch",    "char",
        "class",    "const",        "continue", "default",
        "do",       "double",       "else",     "enum",
        "extends",  "final",        "finally",  "float",
        "for",      "goto",         "if",       "implements",
        "import",   "instanceof",   "int",      "interface",
        "long",     "native",       "new",      "package",
        "private",  "protected",    "public",   "return",
        "short",    "static",       "strictfp", "super",
        "switch",   "synchronized", "this",     "throw",
        "throws",   "transient",    "try",      "void",
        "volatile", "while",
    };
 
    private JComboBox comboBox;
    private JLabel label;
 
    public AutoCompletableComboBox() {
        JFrame frame = new JFrame("Auto Complete ComboBox");
        frame.setSize(300, 84);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        ((JComponent)frame.getContentPane()).setBorder(new EmptyBorder(10, 10, 10, 10));
        frame.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
        frame.add(createComboBox());
 
        label = new JLabel("");
        frame.add(label);
 
        frame.setVisible(true);
    }
 
    private JComboBox createComboBox() {
        comboBox = new JComboBox(keywords);
 
        // オートコンプリート機能を付加する
        AutoCompleteDecorator.decorate(comboBox);
         
        // イベント処理
        comboBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                // 選択された文字列をラベルに表示
                String selectedItem = (String)comboBox.getSelectedItem();
                label.setText(selectedItem);
            }
        });
        
        return comboBox;
    }
 
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new AutoCompletableComboBox();
            }
        });
    }
}

 コンボボックスはcreateComboBoxメソッドの中で生成しています。コンボボックスは青字で示した文字列の配列を項目として表示するようにしました。

 オートコンプリート機能を付加するのは、とても簡単。赤字で示した1行を付け加えるだけです。

 コンボボックスに追加するのではなく、org.jdesktop.swingx.autocomplete.AutoCompleteDecoratorクラスのdecorateメソッドを使用して、コンボボックスを登録します。

図1●AutoCompletableComboBoxの初期画面
図1●AutoCompletableComboBoxの初期画面

 コンボボックスにオートコンプリート機能を付加すると、コンボボックスに文字を入力するとその文字に対応する項目が表示されます。では、実際にやってみましょう。図1にサンプルの初期画面を示します。

 例えばiを入力すると、図2のように表示が変化し、iで始るifが候補になります。ここまでの動作は単にコンボクラスを使用したときと同じです。

 続いて、nを入力します。すると図3に示したように、inではじまるinstanceofが選択されます。さらにtを入力すると、intが選択されます(図4)。

 このように文字を入力していくことで候補を絞り込むことが可能です。

図2●iを入力
図2●iを入力
[画像のクリックで拡大表示]
図3●inを入力
図3●inを入力
[画像のクリックで拡大表示]
図4●intを入力
図4●intを入力
[画像のクリックで拡大表示]

 ここまで入力した後、e以外の文字を入力してみてください。しかし、何も入力できないはずです。コンボボックスは、候補以外の入力は受け付けないようになっているからです。

 任意の文字列を入力できるようにするには、JComboBoxクラスのsetEditableメソッドをtrueを引数にしてコールします。

リスト2●任意の文字列を入力させるための変更
        comboBox = new JComboBox(keywords);
 
        // 候補以外の文字列を入力できるようにする
        comboBox.setEditable(true);
 
        // オートコンプリート機能を付加する
        AutoCompleteDecorator.decorate(comboBox);

これで任意の文字列を入力できるようになります。