I have a swing application in which I need to enable a JMenu from a different thread. I'm doing this on OSX and am using the native screen menu via apple.laf.useScreenMenuBar. Since switching to java 7 the initially disabled menus now never become enabled and I can't figure out why. I've attached a small program which illustrates the problem. Clicking on the Fixed > Change menu item should enable the test menu after a brief pause (a dialog should open and close).
Using java6 it works fine. In java 7 the menu is not enabled. If I don't use the screen menu it works in 6 or 7, and if I use EventQueue.invokeAndWait it works in 6 or 7, but I don't think I should need to do this.
Is this a bug, or am I mis understanding how interactions between swing threads should work?
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();
}
}