Mac上的Java菜单在更改焦点时变灰
我有一个JFrame和一个JMenuBar,我正在Mac系统上开发和测试。在这个JFrame上,我已经将其中一个JMenus编程为禁用。然而,当我将焦点从Java应用程序转移到计算机上的其他程序,然后回到这个JFrame时,奇怪的事情正在发生。我观察到所有菜单都被禁用。我还观察到所有菜单都已启用。谁能告诉我这里发生了什么事 下面是一段代码,它将重现错误(至少在我的机器上是这样):Mac上的Java菜单在更改焦点时变灰,java,macos,swing,jmenu,Java,Macos,Swing,Jmenu,我有一个JFrame和一个JMenuBar,我正在Mac系统上开发和测试。在这个JFrame上,我已经将其中一个JMenus编程为禁用。然而,当我将焦点从Java应用程序转移到计算机上的其他程序,然后回到这个JFrame时,奇怪的事情正在发生。我观察到所有菜单都被禁用。我还观察到所有菜单都已启用。谁能告诉我这里发生了什么事 下面是一段代码,它将重现错误(至少在我的机器上是这样): 当我运行这个时,在将焦点切换到另一个窗口然后再切换回来的操作下,enabled属性不稳定 Swing GUI对象应仅
当我运行这个时,在将焦点切换到另一个窗口然后再切换回来的操作下,enabled属性不稳定 Swing GUI对象应仅在上构造和操作 根据设计,Mac应用程序使用屏幕菜单栏在后台禁用菜单。当您的应用程序出现在前台时,您的应用程序可以使用(例如a)适当地启用菜单 附录:对于测试,此修订示例添加了一个切换按钮,用于跟踪
文件>打开
菜单项的状态
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);
}
});
}
}
你能发一张SSCE或截图吗?一切对我来说都很好。我不是Mac OS用户,但我敢打赌这一行代码有问题:
System.setProperty(“apple.laf.useScreenMenuBar”,“true”)代码>为什么要设置该属性?它会导致框架的菜单栏显示在屏幕顶部,就像Mac OSX操作系统中的本机应用程序一样。和UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())代码>代表?:)我不明白你的问题。这段代码不在我的示例中。org.jhotdraw.samples.draw.Main
就是一个例子。我当然可以使用WindowListener,但我很好奇你说这种行为是“设计的”。当然,当我的应用程序没有焦点时,菜单必须消失,但我不认为菜单项的属性应该从焦点移到另一个窗口再移回来是多么令人满意。特别是考虑到我看到了从所有菜单项突然启用到所有菜单项突然禁用的不可预测的变化,我认为这是一个错误。我不能排除一个错误,但苹果指定管理单个菜单项的启用状态。如果你不在EDT上工作,你会经历不可预知的行为。一旦您进入EDT,如上所示,就更容易继续。感谢您指出有关使用事件调度线程的问题。这是我不知道的事情之一,我不知道。@AdamCross:这是基础,但很容易被忽视。我认为关于第五项你是对的。菜单。我已经更新了示例以供参考。
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);
}
});
}
}