TITLE:JComboBoxを使ってポップアップメニューをスクロール

Posted by at 2005-10-17

JComboBoxを使ってポップアップメニューをスクロール

`JComboBox`を使ってスクロール可能なポップアップメニューを表示します。

  • &jnlp;
  • &jar;
  • &zip;
BasicComboPopup.png

サンプルコード

JComboBox combo = new JComboBox(strArray);
BasicComboPopup popup = new BasicComboPopup(combo) {
  @Override public boolean isFocusable() {
    return true;
  }
  private MouseAdapter listener = null;
  @Override protected void installListListeners() {
    super.installListListeners();
    listener = new MouseAdapter() {
      @Override public void mouseClicked(MouseEvent e) {
        hide();
        System.out.println(comboBox.getSelectedItem());
        append((String)combo.getSelectedItem());
      }
    };
    if(listener!=null) {
      list.addMouseListener(listener);
    }
  }
  @Override public void uninstallingUI() {
    if(listener != null) {
      list.removeMouseListener(listener);
      listener = null;
    }
    super.uninstallingUI();
  }
};
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、`Shift+Tabでポップアップメニューが表示され、上下キーで移動、EnterJTextPane`のカーソルの後に選択された文字列が入力されます。

コンボボックスのポップアップ部分の`UIを表現するBasicComboPopup`を利用することで、スクロールバーをもつポップアップメニューを実現しています。

フォースを取得して、キー入力で選択を変更できるように、`BasicComboPopup#isFocusableメソッドをオーバーライドしています。また、BasicComboPopup#showしたあと、BasicComboPopup#requestFocusInWindow`する必要があります。


`JFrameから、ポップアップメニューがはみ出す(親WindowHeavyWeightWindowになる)場合、カーソルキーなどで、アイテムが移動選択できないバグがあったので、SwingUtilities.getWindowAncestor(popup).toFront();を追加するなどの修正(Ubuntu`ではうまく動作しない?)をしました。

private void popupMenu(ActionEvent e) {
  Rectangle rect = getMyPopupRect();
  popup.show(jtp, rect.x, rect.y + rect.height);
  EventQueue.invokeLater(new Runnable() {
    @Override public void run() {
      SwingUtilities.getWindowAncestor(popup).toFront();
      popup.requestFocusInWindow();
    }
  });
}
BasicComboPopup1.png
  • ただし、バージョン(`6uN?)、Web Startなどで実行すると、AccessControlException`が発生します。
Exception in thread "AWT-EventQueue-0" java.security.AccessControlException: access denied (java.awt.AWTPermission setWindowAlwaysOnTop)

参考リンク

コメント

  • 大変参考になりました。その上、マウスクリックで文字列を選定できるようにしたいですが、どうすればいかがですか? -- java
    • どうもです。とりあえず(以前は、マウスクリックでも動作していたと思うのですが、勘違いだったのかも…?)、手抜きですが、`BasicComboPopup#installListListeners`メソッドをオーバーライドしてマウスリスナーを追加してみました。 -- aterai
  • 助かりました!感動です!ご回答ありがとうございました。 -- java
  • こんにちは。いつもこのサイトを参考にさせていただいています。ようやく自分の`javaアプリケーションをリリースしました(http://www.jdbckit.com まだ更新中ですが、)。次回のバージョンアップで、Special Thanks`をバージョン情報画面に設けて、Terai Atsuhiro様のサイトを感謝対象にさせてよろしいでしょうか? -- java
    • こんばんは。どうもです。おお、おめでとうございます。リンクの件はご自由にどうぞ。 -- aterai
    • 余談: ドキュメントに何か書く必要があるのって、`Apache Software Licenseでしたっけ?基本的(引用先を強調しているTipsを除く)に、このサイトのTips`は、ちいさなサンプルを目指しているため、コピペしても単独ではあまり役に立たないものが多く、完全に無保証なので、ライセンスなどは気しなくても良いです。 -- aterai