在OSX上摇摆:如何捕获命令-Q?

Dan*_*ark 23 java macos swing

确信("受过教育")Mac上的Swing应用程序确实看起来很原生之后,我试图让我的外观尽可能本地化.一切看起来都很棒,但当我点击command+ Q或从菜单中执行此操作时,windowStateChanged(WindowEvent e)我的主要JFrame没有触发(如果我以任何其他方式退出,它会触发).我如何回应真正的Apple退出?

tra*_*god 15

您可以实施com.apple.eawt.ApplicationListener并响应该Quit事件.可以在Mac OS X参考库示例OSXAdapter中找到示例.

附录:有关弃用的信息,重新设计的类以及Apple Java扩展的API文档的位置,请参阅Java for Mac OS X 10.6 Update 3和10.5 Update 8发行说明com.apple.eawt.Application.按住Control键单击或右键单击.jdk文件Show Package Contents.您可以浏览com.apple.eawtOpenJDK源中的类.

如完整示例所示,您可以指定所需的 QuitStrategy; a WindowListener将回复⌘Q:

Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
Run Code Online (Sandbox Code Playgroud)

如前所述在这里,你可以在命令行设置属性

java -Dapple.eawt.quitStrategy=CLOSE_ALL_WINDOWS -cp build/classes gui.QuitStrategyTest
Run Code Online (Sandbox Code Playgroud)

或者在程序早期,在发布任何GUI事件之前:

System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
EventQueue.invokeLater(new QuitStrategyTest()::display);
Run Code Online (Sandbox Code Playgroud)

图片

控制台,之后⌘Q:

java.vendor: Oracle Corporation
java.version: 1.8.0_60
os.name: Mac OS X
os.version: 10.11
apple.eawt.quitStrategy: CLOSE_ALL_WINDOWS
java.awt.event.WindowEvent[WINDOW_CLOSING,opposite=null,oldState=0,newState=0] on frame0
Run Code Online (Sandbox Code Playgroud)

码:

package gui;

import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JTextArea;

/**
 * @see https://stackoverflow.com/a/7457102/230513
 */
public class QuitStrategyTest {

    private void display() {
        JFrame f = new JFrame("QuitStrategyTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println(e);
            }
        });
        f.add(new JTextArea(getInfo()));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private String getInfo() {
        String[] props = {
            "java.vendor",
            "java.version",
            "os.name",
            "os.version",
            "apple.eawt.quitStrategy"
        };
        StringBuilder sb = new StringBuilder();
        for (String prop : props) {
            sb.append(prop);
            sb.append(": ");
            sb.append(System.getProperty(prop));
            sb.append(System.getProperty("line.separator"));
        }
        System.out.print(sb);
        return sb.toString();
    }

    public static void main(String[] args) {
        System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
        EventQueue.invokeLater(new QuitStrategyTest()::display);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 似乎从版本1.6开始,该类已被弃用.请参阅:https://developer.apple.com/library/mac/#releasenotes/Java/JavaSnowLeopardUpdate3LeopardUpdate8RN/NewandNoteworthy/NewandNoteworthy.html重新设计的eAWT (2认同)

Sha*_*mog 7

最高投票的答案非常好,但只是填写"最佳方式":

System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
Run Code Online (Sandbox Code Playgroud)

这将触发标准窗口关闭回调事件,该事件对于可移植代码应该非常好用.

由于下面的讨论,似乎在应用程序的早期做到这一点至关重要.在执行任何UI代码之前,我在主类的静态初始化程序中尽早编写了这个.

  • 是的.但它不需要访问您不希望便携式应用程序使用的Application类.它的一行代码而不是反射. (3认同)