JPopupMenuをキー入力で開く場合の表示位置を調整する
Total: 1749, Today: 2, Yesterday: 0
Posted by aterai at
Last-modified:
Summary
JPopupMenuをキー入力で開く場合の表示位置をJTextFieldならキャレット、JListなら選択セル中央となるように調整します。
Screenshot

Advertisement
Source Code Examples
class NewspaperStyleList<E extends ListItem> extends JList<E> {
protected NewspaperStyleList(DefaultListModel<E> model) {
super(model);
}
@Override public void updateUI() {
setSelectionForeground(null);
setSelectionBackground(null);
setCellRenderer(null);
super.updateUI();
setLayoutOrientation(JList.HORIZONTAL_WRAP);
getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
setVisibleRowCount(0);
setFixedCellWidth(64);
setFixedCellHeight(64);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setCellRenderer(new ListItemListCellRenderer<>());
}
@Override public Point getPopupLocation(MouseEvent event) {
if (event == null) {
int i = getLeadSelectionIndex();
Rectangle r = getCellBounds(i, i);
if (r != null) {
return new Point((int) r.getCenterX(), (int) r.getCenterY());
}
}
return super.getPopupLocation(event);
}
}
View in GitHub: Java, KotlinDescription
- コンポーネントに
setComponentPopupMenu(JPopupMenu)メソッドで設定したJPopupMenuは、たとえばWindows環境ではマウスの右クリックやCONTEXT_MENUキーで開くことが可能- CONTEXT_MENUやShift+F10キーの入力で
JPopupMenuを開く場合、JRootPaneに設定されたpostPopupアクションが実行される - このとき
getPopupLocation(MouseEvent)でJPopupMenuを開く位置が決まるが、戻り値がデフォルトのnullの場合は対象コンポーネントの中央が原点になる getPopupLocation(MouseEvent)メソッドの引数であるMouseEventはキー入力の場合nullになる
- CONTEXT_MENUやShift+F10キーの入力で
JTextField- キー入力で
JPopupMenuを開く場合、JTextFieldの中央ではなくキャレットの下端にJPopupMenuの左上を配置して開くようJTextField#getPopupLocation(MouseEvent)メソッドをオーバーライド
- キー入力で
JList- キー入力で
JPopupMenuを開く場合、JListの中央ではなく選択セルの中央にJPopupMenuの左上を配置して開くようJList#getPopupLocation(MouseEvent)メソッドをオーバーライド - メモ:
Windows 10などのファイルエクスプローラでファイルなどを選択してCONTEXT_MENUキーでポップアップメニューを開く場合、選択セルの中央に右上?を配置して開く仕様になっている?
- キー入力で
Reference
- JPopupMenuの表示を親コンポーネント領域内のみに制限する
JPopupMenu#show(Component c, int x, int y)をオーバーライドしてマウスクリックで開く場合のJPopupMenuの表示位置を調整
- JMenuから開くJPopupMenuの位置を変更する
JMenuからJPopupMenuを開く場合はJMenu#setMenuLocation(...)をオーバーライド