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

2022-09-01 23:20:19

确信(“受过教育”)Mac上的Swing应用程序看起来确实是原生的之后,我试图让我的看起来尽可能原生。一切看起来都很棒,但是当我点击+或从菜单中执行此操作时,my不会在我的主JFrame上触发(如果我以任何其他方式退出,它确实会触发)。我该如何回应真正的苹果退出?commandQwindowStateChanged(WindowEvent e)


答案 1

您可以实现 com.apple.eawt.ApplicationListener 并响应事件。在 Mac OS X Reference Library 示例 OSXAdapter 中可以找到一个示例Quit

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

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

Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);

如此所述,您可以从命令行设置该属性

java -Dapple.eawt.quitStrategy=CLOSE_ALL_WINDOWS -cp build/classes gui.QuitStrategyTest

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

System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
EventQueue.invokeLater(new QuitStrategyTest()::display);

image

控制台,在 :⌘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

法典:

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

答案 2

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

System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");

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

作为下面讨论的结果,似乎在应用程序的早期执行此操作至关重要。在执行任何 UI 代码之前,我在主类的静态初始值设定项中很早就写了这篇文章。