Swing/VerticalMenuBar の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/VerticalMenuBar へ行く。
- Swing/VerticalMenuBar の差分を削除
--- category: swing folder: VerticalMenuBar title: JMenuBarのレイアウトを変更して垂直方向にJMenuを配置する tags: [JMenuBar, LayoutManager, JMenu, JPopupMenu] tags: [JMenuBar, LayoutManager, BoxLayout, JMenu, JPopupMenu] author: aterai pubdate: 2024-07-15T05:50:16+09:00 description: JMenuBarのレイアウトを垂直BoxLayoutに変更してJMenuを垂直方向に並べて配置するサイドバーを作成します。 image: https://drive.google.com/uc?id=1VnITMJfQEzvdh732gTpWAwrSRpBGKkYF --- * 概要 [#summary] JMenuBarのレイアウトを垂直BoxLayoutに変更してJMenuを垂直方向に並べて配置するサイドバーを作成します。 `JMenuBar`のレイアウトを垂直`BoxLayout`に変更して`JMenu`を垂直方向に並べて配置するサイドバーを作成します。 #download(https://drive.google.com/uc?id=1VnITMJfQEzvdh732gTpWAwrSRpBGKkYF) * サンプルコード [#sourcecode] #code(link){{ JMenuBar menuBar = new JMenuBar() { @Override public void updateUI() { super.updateUI(); setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); // setLayout(new GridLayout(0, 1, 2, 2)); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); } }; initMenuBar(menuBar); MenuListener listener = new MenuListener() { @Override public void menuSelected(MenuEvent e) { Object src = e.getSource(); if (src instanceof JMenu && ((JMenu) src).isTopLevelMenu()) { EventQueue.invokeLater(() -> { JMenu menu = (JMenu) src; Point loc = menu.getLocationOnScreen(); loc.x += menu.getWidth(); menu.getPopupMenu().setLocation(loc); }); } } @Override public void menuDeselected(MenuEvent e) { // Do nothing } @Override public void menuCanceled(MenuEvent e) { // Do nothing } }; for (MenuElement m : menuBar.getSubElements()) { if (m instanceof JMenu) { JMenu menu = (JMenu) m; menu.addMenuListener(listener); Dimension d = menu.getMaximumSize(); d.width = Short.MAX_VALUE; menu.setMaximumSize(d); } } }} * 解説 [#explanation] - `JMenuBar#setLayout(new BoxLayout(this, BoxLayout.Y_AXIS))`して`JMenuBar`のレイアウトを水平`BoxLayout`から垂直`BoxLayout`に変更 -- [[BoxLayoutでリスト状に並べる>Swing/ComponentList]] -- `JSeparator`などを使用せず、縦`JMenuBar`のすべての子`Component`の高さが同じでよい場合は、`JMenuBar#setLayout(new GridLayout(0, 1))`で`JMenuBar`のレイアウトを行数指定なしで`1`列のグリッドに変更する方法もある - `JMenuBar`の子`MenuElement`でトップレベル`JMenu`を`JMenuBar#getSubElements()`で取得し、その`JMenu`が開く`JPopupMenu`の表示位置を修正する`MenuListener`を追加 -- このサンプルでは`MenuListener#menuSelected(MenuEvent)`で親フレームの左側に配置された場合を想定して`JMenuBar`の幅だけ`x`座標を右に移動 -- [[JToolBar内にJMenuBarを配置して分離・移動可能に設定する>Swing/FloatableMenuBar]] -- トップレベル`JMenu`以外は表示位置の修正は不要 * 参考リンク [#reference] - [[JTreeとCardLayoutでサイドメニューを作成する>Swing/VerticalNavigationMenu]] - [[BoxLayoutでリスト状に並べる>Swing/ComponentList]] - [[JToolBar内にJMenuBarを配置して分離・移動可能に設定する>Swing/FloatableMenuBar]] * コメント [#comment] #comment #comment