• category: swing folder: SystemMenu title: SystemMenuとして使用されているJMenuを取得する tags: [JRootPane, JMenu, JMenuItem, LookAndFeel] author: aterai pubdate: 2021-05-24T06:11:30+09:00 description: JRootPaneの子コンポーネントを検索してSystemMenuとして使用されているJMenuを取得します。 image: https://drive.google.com/uc?id=17deOtbw1m68IowpoVASZ4QGOeM1WJBnq

概要

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

サンプルコード

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 in GitHub: Java, Kotlin

解説

  • 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のサイズが小さく、システムアイコンを右クリックしてもシステムメニューがポップアップできない場合がある
    • 上記のサンプルではシステムアイコンを再設定してクリック可能な領域を拡大している

参考リンク

コメント