我有一个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。
答案 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();
}
});
}
}