3

我有一个带有 JMenuBar 的 JFrame,我正在 Mac 系统上开发和测试它。在这个 JFrame 上,我已将其中一个 JMenu 编程为禁用。但是,当我将焦点从我的 Java 应用程序转移到我计算机上的某个其他程序,然后又回到这个 JFrame 时,奇怪的事情正在发生。我观察到所有菜单都被禁用。我还观察到所有菜单都已启用。谁能告诉我这里发生了什么?

这是一段将重现错误的代码(至少在我的机器上是这样):

public class MenuProblemExample {

    public static void main(String[] args) {
        System.setProperty("apple.laf.useScreenMenuBar", "true");
        JFrame frame = new JFrame();
        JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        fileMenu.add(new JMenuItem("open"));
        menuBar.add(fileMenu);
        JMenu editMenu = new JMenu("Edit");
        editMenu.add(new JMenuItem("select all"));
        menuBar.add(fileMenu);
        menuBar.add(editMenu);
        frame.setJMenuBar(menuBar);
        fileMenu.setEnabled(false);
        frame.setVisible(true);        
    }
}

当我运行它时,在将焦点切换到另一个窗口然后再返回的操作下,启用的属性不稳定。

4

1 回答 1

3

Swing GUI 对象应该事件分派线程上构建和操作。

按照设计,使用屏幕菜单栏的 Mac 应用程序会在后台禁用菜单。当您的应用程序进入前台时,您的应用程序可以适当地启用菜单,例如使用WindowListener.

附录:为了测试,这个修改后的示例添加了一个切换按钮,用于跟踪File > Open菜单项的状态。

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToggleButton;

/**
 * @see http://stackoverflow.com/a/13756527/230513
 */
public class MenuProblemExample {

    public static void main(String[] args) {
        System.setProperty("apple.laf.useScreenMenuBar", "true");
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JMenuBar menuBar = new JMenuBar();
                JMenu fileMenu = new JMenu("File");
                final JMenuItem openItem = new JMenuItem("open");
                openItem.setEnabled(false);
                fileMenu.add(openItem);
                menuBar.add(fileMenu);
                JMenu editMenu = new JMenu("Edit");
                editMenu.add(new JMenuItem("select all"));
                menuBar.add(fileMenu);
                menuBar.add(editMenu);
                frame.setJMenuBar(menuBar);
                frame.add(new JToggleButton(new AbstractAction("Toggle") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JToggleButton b = (JToggleButton) e.getSource();
                        openItem.setEnabled(b.isSelected());
                    }
                }));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
于 2012-12-07T03:36:38.043 回答