JPopupMenuをキー入力で開く場合の表示位置を調整する
Total: 1226
, Today: 1
, Yesterday: 4
Posted by aterai at
Last-modified:
概要
JPopupMenu
をキー入力で開く場合の表示位置をJTextField
ならキャレット、JList
なら選択セル中央となるように調整します。
Screenshot
Advertisement
サンプルコード
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, Kotlin解説
- コンポーネントに
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キーでポップアップメニューを開く場合、選択セルの中央に右上?を配置して開く仕様になっている?
- キー入力で
参考リンク
- JPopupMenuの表示を親コンポーネント領域内のみに制限する
JPopupMenu#show(Component c, int x, int y)
をオーバーライドしてマウスクリックで開く場合のJPopupMenu
の表示位置を調整
- JMenuから開くJPopupMenuの位置を変更する
JMenu
からJPopupMenu
を開く場合はJMenu#setMenuLocation(...)
をオーバーライド