我有一个 Swing 应用程序,我需要在其中启用来自不同线程的 JMenu。我在 OSX 上执行此操作,并通过 apple.laf.useScreenMenuBar 使用本机屏幕菜单。自从切换到 java 7 以来,最初禁用的菜单现在从未启用,我不知道为什么。我附上了一个说明问题的小程序。单击 Fixed > Change 菜单项应在短暂暂停后启用测试菜单(应打开和关闭对话框)。
使用 java6 它工作正常。在 java 7 中,菜单未启用。如果我不使用屏幕菜单,它适用于 6 或 7,如果我使用 EventQueue.invokeAndWait,它适用于 6 或 7,但我认为我不需要这样做。
这是一个错误,还是我误解了摆动线程之间的交互应该如何工作?
import java.awt.EventQueue;
import java.awt.event.*;
import javax.swing.*;
public class MainWindow extends JFrame implements ActionListener {
private JMenu testMenu;
public MainWindow () {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Menu Enable Test");
JMenuBar bar = new JMenuBar();
JMenu fixedMenu = new JMenu("Fixed");
JMenuItem change = new JMenuItem("Change");
change.addActionListener(this);
fixedMenu.add(change);
bar.add(fixedMenu);
testMenu = new JMenu("Test");
testMenu.setEnabled(false);
JMenuItem seeMe = new JMenuItem("Can you see me?");
testMenu.add(seeMe);
bar.add(testMenu);
setJMenuBar(bar);
setSize(800,600);
setLocationRelativeTo(null);
setVisible(true);
}
public void makeVisible () {
testMenu.setEnabled(true);
}
public void actionPerformed(ActionEvent ae) {
new RemoteChanger(this);
}
private class RemoteChanger extends JDialog implements Runnable {
private MainWindow window;
public RemoteChanger (MainWindow window) {
super(window);
setSize(200,100);
setLocationRelativeTo(window);
this.window = window;
setVisible(true);
Thread t = new Thread(this);
t.start();
}
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
EventQueue.invokeLater(new Runnable() {
public void run() {
window.makeVisible();
}
});
setVisible(false);
}
}
public static void main (String [] args) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
new MainWindow();
}
}