• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JComboBoxを使ってポップアップメニューをスクロール
#navi(../)
RIGHT:Posted by [[terai]] at 2005-10-17
RIGHT:Posted by &author(aterai); at 2005-10-17
*JComboBoxを使ってポップアップメニューをスクロール [#cc8b9df3]
JComboBoxを使ってスクロール可能なポップアップメニューを表示します。

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

#screenshot
//#screenshot
#ref(http://lh3.ggpht.com/_9Z4BYR88imo/TQTH_tpIbsI/AAAAAAAAASE/DrHgihVbnn0/s800/BasicComboPopup.png)

**サンプルコード [#q28e6ef6]
#code{{
#code(link){{
JComboBox combo = new JComboBox(strArray);
BasicComboPopup popup = new BasicComboPopup(combo) {
  public boolean isFocusable() {
    return true;
  }
  protected void installListListeners() {
    super.installListListeners();
    list.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        append((String)combo.getSelectedItem());
      }
    });
  }
};
}}

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

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

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

----
JFrameから、ポップアップメニューがはみ出す(親WindowがHeavyWeightWindowになる)場合、カーソルキーなどで、アイテムが移動選択できないバグがあったので、SwingUtilities.getWindowAncestor(popup).toFront();を追加するなどの修正((Ubuntuではうまく動作しない))をしました。
#code{{
private void popupMenu(ActionEvent e) {
  Rectangle rect = getMyPopupRect();
  popup.show(jtp, rect.x, rect.y + rect.height);
  EventQueue.invokeLater(new Runnable() {
    public void run() {
      SwingUtilities.getWindowAncestor(popup).toFront();
      popup.requestFocusInWindow();
    }
  });
}
}}
#screenshot(,screenshot1.png)
//#screenshot(,screenshot1.png)
#ref(http://lh3.ggpht.com/_9Z4BYR88imo/TQTICNIyr1I/AAAAAAAAASI/CorNUGA0pF8/s800/BasicComboPopup1.png)

-%%ただし、バージョン(6uN?)、Web Startなどで実行すると、AccessControlExceptionが発生します。%% 6u10 build b26 で修正済み。
--[http://bugs.sun.com/view_bug.do?bug_id=6675802 Bug ID: 6675802 Regression: heavyweight popups cause SecurityExceptions in applets]
 Exception in thread "AWT-EventQueue-0" java.security.AccessControlException: access denied (java.awt.AWTPermission setWindowAlwaysOnTop)

**参考リンク [#ieff35f1]
-[http://forums.sun.com/thread.jspa?threadID=483165 Swing - Scrollable PopupMenu]

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

#comment