JMenuから開くJPopupMenuの位置を変更する
Total: 1951
, Today: 4
, Yesterday: 1
Posted by aterai at
Last-modified:
概要
JMenu
を選択して開くJPopupMenu
が親ウィンドウ内に表示されるよう位置を変更します。
Screenshot
Advertisement
サンプルコード
JMenu menu = new JMenu(key) {
@Override public void setPopupMenuVisible(boolean b) {
if (isTopLevelMenu()) {
Point p = getLocation();
Rectangle r = getRootPane().getBounds();
Dimension d1 = getPopupMenu().getPreferredSize();
if (p.x + d1.width > r.width) {
Dimension d2 = getPreferredSize();
setMenuLocation(d2.width - d1.width, d2.height);
}
}
super.setPopupMenuVisible(b);
}
};
View in GitHub: Java, Kotlin解説
JMenu
がJMenuBar
に配置されたTopLevelMenu
でJMenu
を選択して表示されるJPopupMenu
が親Window
領域外に配置される場合、オーバーライドしたJMenu#setPopupMenuVisible(...)
内でJMenu#setMenuLocation(...)
を使用して親Window
領域内に収まるようJPopupMenu
の位置を変更JMenu#setPopupMenuVisible(...)
ではなくMenuListener#menuSelected(...)をオーバーライドする方法もある
TopLevelMenu
の場合のJPopupMenu
の表示位置オフセットはUIManager.put("Menu.menuPopupOffsetX", offset)
、UIManager.put("Menu.menuPopupOffsetY", offset)
で変更可能TopLevelMenu
ではない場合のJPopupMenu
の表示位置オフセットはUIManager.put("Menu.submenuPopupOffsetX", offset)
、UIManager.put("Menu.submenuPopupOffsetY", offset)
で変更可能JMenu
がTopLevelMenu
ではなくサブメニューの場合、同じくオーバーライドしたJMenu#setPopupMenuVisible(...)
内でJMenu#setMenuLocation(...)
を使用して親JPopupMenu
と同じ位置に同じサイズでJPopupMenu
を表示するよう位置を変更WindowsLookAndFeel
の場合親JPopupMenu
のハイライトが手前に残る場合がある?- テストとして
JMenu
内にカーソルが入ったときではなくクリックイベントでJPopupMenu
を開閉するようJMenu#setDelay(...)
に100
秒の遅延時間を設定しているがおそらく修正が必要になりそう
JMenu menu = new JMenu(title) {
@Override public void setPopupMenuVisible(boolean b) {
JPopupMenu popup = getPopupMenu();
popup.setPopupSize(getParent().getPreferredSize());
Point p = getLocation();
setMenuLocation(-p.x, -p.y);
super.setPopupMenuVisible(b);
}
@Override public JMenuItem add(JMenuItem item) {
item.setMaximumSize(new Dimension(Short.MAX_VALUE, item.getPreferredSize().height));
return super.add(item);
}
};