java - 使用 Java7 在 OSX 上启用 Swing 菜单

标签 java macos swing java-7 jmenu

我有一个 swing 应用程序,我需要在其中从不同的线程启用 JMenu。我在 OSX 上执行此操作,并通过 apple.laf.useScreenMenuBar 使用 native 屏幕菜单。自从切换到 Java 7 以来,最初禁用的菜单现在再也没有启用过,我也不知道为什么。我附上了一个说明问题的小程序。单击 Fixed > Change 菜单项应在短暂暂停后启用测试菜单(应打开和关闭对话框)。

使用 java6 它工作正常。在 Java 7 中,菜单未启用。如果我不使用屏幕菜单,它在 6 或 7 中工作,如果我使用 EventQueue.invokeAndWait,它在 6 或 7 中工作,但我认为我不需要这样做。

这是一个错误,还是我误解了 swing 线程之间的交互应该如何工作?

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();
    }

}

最佳答案

我认为问题的根源是您的 setVisible(false) 在 Swing 线程之外。将它移到 invokeLater() 调用中似乎更正确,并为您提供预期的行为。

EventQueue.invokeLater(new Runnable() {
    public void run() {
        window.makeVisible();    
        setVisible(false);
    }
});

关于java - 使用 Java7 在 OSX 上启用 Swing 菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16057872/

相关文章:

java - 请建议我使用 GridBag 布局之外的基本布局

JAVA-PriorityQueue实现

objective-c - 如何在 applicationDidFinishLaunching 中启动第二个窗口

java - 如何在对话框可见时更改对话框的模式

python - 在 MacOs Python shell 中粘贴多行返回 SyntaxError

macos - conda 错误 : could not found url

java - 捕获未按标签按下的 Jbutton

java - 动态注册实体类,无需重新创建 session 工厂

java - For 循环嵌套在 do... while 不起作用

java - Android Studio 在 DefaultHttpClient 中获取错误