Summary

JPopupMenuの背景を透明に変更し、JToolBarとメニューボタンを分離して配置することで両方を同時に表示します。

Source Code Examples

private static JPopupMenu createCustomPopup() {
  JPopupMenu popup = new JPopupMenu() {
    @Override public void updateUI() {
      setUI(new TransparentPopupMenuUI());
      setOpaque(false);
    }
  };
  popup.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
  popup.setLayout(new BorderLayout(0, 8));

  JToolBar toolbar = new RoundedToolBar(15);
  toolbar.setFloatable(false);
  toolbar.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
  Arrays.asList("📋", "💾", "🔍", "🔖", "🔋", "🔔")
      .forEach(icon -> toolbar.add(createIconButton(icon)));

  RoundPanel menuPanel = new RoundPanel(15);
  menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.Y_AXIS));
  menuPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
  Arrays.asList("Properties", "Rename", "Save", "Delete")
      .forEach(text -> menuPanel.add(createMenuButton(text, popup)));

  popup.add(toolbar, BorderLayout.NORTH);
  popup.add(menuPanel, BorderLayout.WEST);
  return popup;
}
View in GitHub: Java, Kotlin

Description

  • JPopupMenu
    • 背景ウィンドウを完全に透明化
    • 間隔を開けて子JToolBarと子JPanel(JButtonを配置)を配置することで個別にポップアップしたように見せかけている
  • JToolBar
    • 横長ツールバー
    • JToolBar#setFloatable(false)で浮動を不可に設定
  • JPanel
    • JPanelJMenuItemを配置するとマウスオーバーで親JPopupMenuが閉じる場合があるのでJButtonで代用
    • BorderLayout.WESTで左側に寄せて配置

Reference

Comment