无法重新启用OSX菜单栏

时间:2015-11-18 17:52:57

标签: java macos swing menu look-and-feel

我有一个程序,它为不同的窗口使用多个不同的JMenuBar(通过JFrame.setJMenuBar())。我们发现在OSX中,在某些情况下,其中一个菜单栏可能会被禁用,并且事后似乎无法重新启用它。这是我的简单例子:

public class Demo {

   public static void main(String[] args) {
      System.setProperty("apple.laf.useScreenMenuBar", "true");
      try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      }
      catch (Exception e) {
         System.out.println("Error setting LAF: " + e);
      }
      new MyFrame("Alpha frame");
      new MyFrame("Beta frame");
   }

   public static class MyFrame extends JFrame {
      public MyFrame(String title) {
         super(title);
         final JMenuBar menuBar = new JMenuBar();
         JButton button = new JButton("Toggle menu") {
            @Override 
            public Dimension getPreferredSize() {
               return new Dimension(300, 300);
            }
         };
         add(button);
         button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
               menuBar.setEnabled(!menuBar.isEnabled());
            }
         }); 

         JMenu fileMenu = new JMenu("File");
         fileMenu.add(new JMenuItem("Dummy action"));
         menuBar.add(fileMenu);
         setJMenuBar(menuBar);
         pack();
         setVisible(true);
      } 
   }    
}

如果您使用其按钮禁用其中一个框架的菜单栏,则将焦点切换到另一个框架,切换回来,然后再次单击该按钮,菜单栏不会在视觉上重新启用 - 菜单项仍然存在灰显且不可操作,但isEnabled()方法将返回true。

这是一个问题,因为某些模态对话框似乎会自动禁用当前菜单栏。我已经看到它发生在JFileChooser,我也看到它发生在FileDialog。事件调度线程中也可能存在一些异常问题;我还没有做过详细的分析。理想情况下,我只是确定每当给定窗口获得焦点时,其菜单栏会自动重新启用 - 但setEnabled() JMenuBar方法实际上并没有做任何事情,如果你'我将焦点切换到另一个窗口,正如我的演示所示。

我该如何解决这个问题?

(Java 6,令我很懊恼的是,我们会尽快更新到Java 8)

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

对我来说,我必须禁用JMenuItem而不是JMenuBar。禁用菜单栏的代码:

for(int i = 0; i<menuBar.getMenuCount(); i++){
    JMenu menu = menuBar.getMenu(i);
    if(menu==null) continue;
    for(int j = 0; j<menu.getItemCount(); j++){
       JMenuItem item = menu.getItem(j);
       if(item==null) continue;
       item.setEnabled(false);
    }
}

启用菜单栏的代码。

for(int i = 0; i<menuBar.getMenuCount(); i++){
    JMenu menu = menuBar.getMenu(i);
    if(menu==null) continue;
    for(int j = 0; j<menu.getItemCount(); j++){
       JMenuItem item = menu.getItem(j);
       if(item==null) continue;
       item.setEnabled(true);
    }
}