TITLE:JComboBoxで候補一覧を表示
#navi(../)
RIGHT:Posted by [[terai]] at 2004-12-06
*JComboBoxで候補一覧を表示 [#jc5d9269]
JComboBoxに入力候補の一覧表示機能((補完機能、コードアシスト、コンテンツアシスト))を追加します。

-&jnlp;
-&jar;
-&zip;

#screenshot

**サンプルコード [#c1c19fbc]
#code{{
combo.setEditable(true);
field = (JTextField) combo.getEditor().getEditorComponent();
field.addKeyListener(new KeyAdapter() {
  @Override
  public void keyTyped(KeyEvent e) {
    keyTypedInCombo(e);
  }
  @Override
  public void keyPressed(KeyEvent e) {
    keyPressedInCombo(e);
  }
  //public void keyReleased(KeyEvent e) {
});
}}

#code{{
private boolean hide_flag = false;
private void keyPressedInCombo(KeyEvent ke) {
  String text = field.getText();
  int code = ke.getKeyCode();
  if(code==KeyEvent.VK_ENTER) {
    if(!model.contains(text)) {
      model.addElement(text);
      Collections.sort(model);
      setModel(getSuggestedModel(model, text), text);
    }
    hide_flag = true; //combo.hidePopup();
  }else if(code==KeyEvent.VK_ESCAPE) {
    hide_flag = true; //combo.hidePopup();
  }else if(code==KeyEvent.VK_RIGHT) {
    for(int i=0;i<model.size();i++) {
      String str = model.elementAt(i);
      if(str.startsWith(text)) {
        combo.setSelectedIndex(-1);
        field.setText(str);
        return;
      }
    }
  }
}
private void keyTypedInCombo(final KeyEvent ke) {
  EventQueue.invokeLater(new Runnable() {
    public void run() {
      String text = field.getText();
      if(text.length()==0) {
        combo.hidePopup();
        setModel(new DefaultComboBoxModel(model), "");
      }else{
        DefaultComboBoxModel m = getSuggestedModel(model, text);
        if(m.getSize()==0 || hide_flag) {
          combo.hidePopup();
          hide_flag = false;
        }else{
          setModel(m, text);
          combo.showPopup();
        }
      }
    }
  });
}
}}

**解説 [#se4084d9]
上記のサンプルでは、次のキー操作に対応しています。
-上下キー
--ポップアップ表示
-ESCキー
--ポップアップ非表示
-右キー
--補完
-リターンキー
--選択or追加
-文字入力
--候補をポップアップ

JComboBox#showPopup()とJComboBox#hidePopup()((それぞれ、JComboBox#setPopupVisible メソッドをラップしているだけ))を使って、候補のポップアップメニュー表示を制御します。

JComboBox#setSelectedIndex(-1)で、項目の選択をクリアしないと動作がおかしくなる場合があります。

//**参考リンク
**コメント [#k1139ae6]
- 変換途中の日本語も、問題がないともっといいですね。 -- [[toshi]] &new{2006-04-24 (月) 13:45:06};
- あー、日本語のこと全然考えてなかったです…。 -- [[terai]] &new{2006-04-24 (月) 15:54:00};
- タイトルなどを変更するとしたら AutoCompletion に? -- [[terai]] &new{2007-05-09 (水) 20:14:40};
- 日本語を考えるとKeyReleasedよりKeyTypedのほうがよさそうです -- [[foggi]] &new{2008-05-06 (火) 17:15:39};
-- ご指摘ありがとうございます。keyTyped に変更してみました((ついでにスクリーンショットなども更新))。 -- [[terai]] &new{2008-05-07 (水) 12:23:19};

#comment