概要

JRootPaneの子コンポーネントを検索してSystemMenuとして使用されているJMenuを取得します。

スクリーンショット

Swing/SystemMenu.png

サンプルコード

JTextArea log = new JTextArea();
EventQueue.invokeLater(() -> {
  JMenu menu = descendants(getRootPane())
      .filter(JMenu.class::isInstance).map(JMenu.class::cast)
      .findFirst().orElse(new JMenu(" "));
  menu.add("added to the SystemMenu");

  log.append(menu.getPreferredSize() + "\n");
  menu.setIcon(UIManager.getIcon("InternalFrame.icon"));
  log.append(menu.getPreferredSize() + "\n---\n");

  Component c = menu;
  while (c != null) {
    log.append(c.getClass().getName() + "\n");
    c = c.getParent();
  }
});
view all

解説

  • OS依存のSystemLookAndFeelではSystemMenuJNIなどを使用しないと取得不可能
  • JFrame.setDefaultLookAndFeelDecorated(true)DefaultLookAndFeelを使用する場合、SystemMenuは以下のようなコンポーネント階層を辿って取得可能
javax.swing.JFrame
└─javax.swing.JRootPane
    └─javax.swing.JLayeredPane
        └─javax.swing.plaf.metal.MetalTitlePane
            └─javax.swing.plaf.metal.MetalTitlePane$SystemMenuBar
                └─javax.swing.JMenu
  • 取得したJMenuのサイズが小さく、システムアイコンを右クリックしてもシステムメニューがポップアップできない場合がある
    • 上記のサンプルではシステムアイコンを再設定してクリック可能な領域を拡大している

参考リンク

コメント