JComboBoxを使ってポップアップメニューをスクロール
Total: 15736, Today: 2, Yesterday: 2
Posted by aterai at
Last-modified:
Summary
JComboBoxを使ってスクロール可能なポップアップメニューを表示します。
Screenshot

Advertisement
Source Code Examples
class EditorComboPopup extends BasicComboPopup {
private final JTextComponent textArea;
private transient MouseAdapter listener;
protected EditorComboPopup(JTextComponent textArea, JComboBox cb) {
super(cb);
this.textArea = textArea;
}
@Override protected void installListListeners() {
super.installListListeners();
listener = new MouseAdapter() {
@Override public void mouseClicked(MouseEvent e) {
hide();
String str = (String) comboBox.getSelectedItem();
try {
Document doc = textArea.getDocument();
doc.insertString(textArea.getCaretPosition(), str, null);
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
};
if (Objects.nonNull(list)) {
list.addMouseListener(listener);
}
}
@Override public void uninstallingUI() {
if (Objects.nonNull(listener)) {
list.removeMouseListener(listener);
listener = null;
}
super.uninstallingUI();
}
@Override public boolean isFocusable() {
return true;
}
}
View in GitHub: Java, KotlinDescription
上記のサンプルでは、Shift+Tabでポップアップメニューが表示され、Up・Downキーで移動、EnterでJTextPaneのカーソルの後に選択された文字列が入力されます。
JComboBoxのポップアップ部分のUIを表現するBasicComboPopupを利用することで垂直スクロールバーありのポップアップメニューを実現しています。
- フォーカスを取得してキー入力で選択を変更できるように
BasicComboPopup#isFocusableメソッドをオーバーライドBasicComboPopup#show()を実行した後BasicComboPopup#requestFocusInWindow()を呼びだす必要がある
JFrameから、ポップアップメニューがはみ出す(親WindowがHeavyWeightWindowになる)場合、カーソルキーなどで、アイテムが移動選択できないバグがある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(); } }); }
ただし、バージョン(6uN?)、Web Startなどで実行すると、AccessControlExceptionが発生するException in thread "AWT-EventQueue-0" java.security.AccessControlException: access denied (java.awt.AWTPermission setWindowAlwaysOnTop)
- 上記の
AccessControlExceptionは、6u10 build b26で修正されている
