弹出窗口禁用Mac上Java应用程序中的菜单

时间:2012-11-02 13:31:32

标签: java macos swing popup jmenuitem

我有一个Java程序,我在其中启用和禁用菜单。它在Windows下运行良好,但在Mac上运行时遇到一些问题。

这是一段演示问题的代码:

import javax.swing.*;
import java.awt.event.*;

public class PopTest extends JFrame {
    JMenu menu1;
    JMenu menu2;

    public PopTest() {
        menu1 = new JMenu("Menu 1");
        menu2 = new JMenu("Menu 2");
        menu2.setEnabled(false);

        menu1.add(new JMenuItem(new AbstractAction("With popup") {
                public void actionPerformed(ActionEvent event) {
                    JOptionPane.showMessageDialog(PopTest.this,"Popup","Popup",JOptionPane.ERROR_MESSAGE);
                    menu2.setEnabled(true);
                    menu2.add(new JMenuItem("New item"));
                }
            }));

        menu1.add(new JMenuItem(new AbstractAction("Without popup") {
                public void actionPerformed(ActionEvent event) {
                    menu2.setEnabled(true);
                    menu2.add(new JMenuItem("New item"));
                }
            }));

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(menu1);
        menuBar.add(menu2);
        setJMenuBar(menuBar);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200, 200);
        setVisible(true);
    }

    public static void main(String[] args) {
        try {
            System.setProperty("apple.laf.useScreenMenuBar", "true");
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch(Exception e) {
            System.out.println("Exception: " + e.getMessage());
        }

        SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new PopTest();
                }
            });

    }
}

这就是该计划的作用:

该程序有两个菜单,“菜单1”和“菜单2”。从一开始,菜单1启用,菜单2被禁用。

菜单1有两个几乎完全相同的项目:它们启用菜单2并向其添加菜单项。区别在于其中一个项目在启用菜单2之前显示消息对话框,而另一个项目则不显示。

现在,编译程序并尝试:

实验1:选择菜单1>没有弹出。现在点击菜单2,您将看到菜单中有一个名为“新项目”的已启用菜单项。

Expermiment 2:关闭程序!再次启动该程序。选择菜单1>使用弹出窗口。在消息对话框中单击“确定”。现在单击菜单2,您将看到菜单中有一个名为“新项目”的已禁用菜单项。单击桌面上的其他位置,以便应用程序失去焦点。单击应用程序。单击菜单2,您将看到菜单项现已启用。

在实验2中,在指示您单击桌面上的其他位置之前,应用程序不会失去焦点是非常重要的。否则你不会看到问题。

为什么在第二个实验中禁用菜单2中的菜单项?这是一个错误吗?我正在使用OS X 10.8.2(Mountain Lion)和Java 1.7.0_09。

2 个答案:

答案 0 :(得分:2)

我可以在Java 7中复制这个问题,但不能在Java 6中复制。我不明白为什么会这样做,但有一件事就是把它固定在JOptionPane.showMessageDialog()之上:

    menu1.add(new JMenuItem(new AbstractAction("With popup")
    {
        public void actionPerformed(ActionEvent event)
        {
            menu2.setEnabled(true);
            JOptionPane.showMessageDialog(Test.this, "Popup", "Popup", JOptionPane.ERROR_MESSAGE);
            menu2.add(new JMenuItem("New item"));
        }
    }));

答案 1 :(得分:1)

在我的早期版本中,两个菜单始终处于启用状态,但您可以通过向Runnable发布第二个EventQueue来强制执行特定序列。

EventQueue.invokeLater(new Runnable() {

    @Override
    public void run() {
        menu2.add(new JMenuItem("New item"));
    }
});

经测试;请注意默认的L& F,@Override注释并使用pack()

import java.awt.EventQueue;
import java.awt.event.*;
import javax.swing.*;

public class PopTest extends JFrame {

    JMenu menu1;
    JMenu menu2;

    public PopTest() {
        menu1 = new JMenu("Menu 1");
        menu2 = new JMenu("Menu 2");
        menu2.setEnabled(false);

        menu1.add(new JMenuItem(new AbstractAction("With popup") {

            @Override
            public void actionPerformed(ActionEvent event) {
                JOptionPane.showMessageDialog(PopTest.this,
                    "Popup", "Popup", JOptionPane.ERROR_MESSAGE);
                menu2.setEnabled(true);
                menu2.add(new JMenuItem("New item"));
            }
        }));

        menu1.add(new JMenuItem(new AbstractAction("Without popup") {

            @Override
            public void actionPerformed(ActionEvent event) {
                menu2.setEnabled(true);
                EventQueue.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        menu2.add(new JMenuItem("New item"));
                    }
                });
            }
        }));

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(menu1);
        menuBar.add(menu2);
        setJMenuBar(menuBar);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setSize(200, 200);
        setVisible(true);
    }

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

        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new PopTest();
            }
        });

    }
}
相关问题