Качание на OSX: как ловушка command-Q?

Убедившись («обученный»), что Swing-приложения на Mac выглядят родными , я стараюсь сделать мой взгляд максимально родным. Все выглядит великолепно, но когда я нажимаю команду + Q или делаю это из меню, мой windowStateChanged(WindowEvent e) не windowStateChanged(WindowEvent e) мой основной JFrame (если я windowStateChanged(WindowEvent e) иначе, он срабатывает). Как я могу ответить на настоящий Apple?

Высший проголосовавший ответ отличный, но просто для того, чтобы заполнить «лучший способ»:

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

Это вызовет стандартное закрытие windows обратного вызова, которое должно отлично работать для переносимого кода.

В результате обсуждения ниже кажется, что его очень важно сделать это на самом деле в начале приложения. Я написал это раньше в статическом инициализаторе основного classа до того, как был выполнен любой код пользовательского интерфейса.

Вы можете реализовать com.apple.eawt.ApplicationListener и ответить на событие Quit . Пример можно найти в примере справочной библиотеки Mac OS X , OSXAdapter .

Приложение: см. Java для Mac OS X 10.6 Update 3 и 10.5 Update 8 Примечания к выпуску для получения информации об устаревании, измененном classе com.apple.eawt.Application и местоположении документации API для расширений Apple Java. Нажмите «Control» или щелкните правой кнопкой .jdk файл .jdk для .jdk Show Package Contents . Вы можете просматривать classы com.apple.eawt среди источников OpenJDK.

Как показано в этом полном примере , вы можете указать желаемую QuitStrategy ; WindowListener ответит на ⌘Q :

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

Как отмечено здесь , вы можете установить свойство из командной строки

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

или в начале программы, перед публикацией каких-либо графических интерфейсов:

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

образ

Консоль после ⌘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); } } 

Это довольно хороший вопрос, и я должен признать, что у меня нет ответа. Тем не менее, пару лет назад, когда я работал над Java-приложением и столкнулся с этой проблемой, я решил это, зарегистрировав завершающий крючок с временем выполнения, который будет делать то, что я хотел, чтобы приложение выполнялось до выхода из игры. Это тяжелое решение, но оно сработало. Вы можете взглянуть на мой код и посмотреть, помогает ли он.

Первоначально я видел нарушение «ограничения доступа» при попытке доступа к подclassам com.apple.eawt.Application и com.apple.eawt. *.

(Примечание: я программирую на MAC, используя Eclipse, с Java 1.6, используя Swing)

Поэтому мне нужно было изменить свой путь сборки Java, чтобы разрешить доступ к подclassам Apple, добавив правило доступа «com / apple / eawt / **». После этого этот код ниже смог скомпилировать и работать для меня:

 //NOTE: This code only works for MAC OS. If you run this on Windows //the application never starts (so you literally need to remove this block of code) import com.apple.eawt.*; import com.apple.eawt.QuitHandler; Application a = Application.getApplication(); a.setQuitHandler(new QuitHandler() { @Override public void handleQuitRequestWith(com.apple.eawt.AppEvent.QuitEvent qe, com.apple.eawt.QuitResponse qr) { // TODO Auto-generated method stub int res = JOptionPane.showConfirmDialog(frame, "Are you sure you want to exit the program?", "Quit ?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (res == JOptionPane.YES_OPTION) qr.performQuit(); else qr.cancelQuit(); } }); 

Вы пробовали настроить командуQ как ускоритель в вашем меню? Можете ли вы заставить приложение реагировать на него?

Я не уверен, но я думаю, что это работает в Linux и, вероятно, в Windows с эквивалентным Alt- F4 . Мое приложение реагирует на «убийство» нажатия клавиши, я обрабатываю код очистки, а затем я делаю программный System.exit() .

Если вы «просто» после грациозной обработки выхода, вы также можете захотеть поймать WindowEvent WINDOW_CLOSING , где традиционно «вы уверены»? вещи делаются.

Посмотрев ссылку на Java для Mac OS X 10.6 Update 3 и 10.5 Update 8 Замечания по выпуску Я заметил, что есть раздел об отключении по умолчанию . Это описывает системное свойство, чтобы запросить, чтобы все windows были закрыты в ответ на пункт меню «Выход», что похоже на то, что нужно? Я использовал это в своем собственном приложении (используя Info.plist для установки свойства только в OS X), и он работает, как описано. Это, по-видимому, будет работать только на последних версиях Java / OS X, но для этих платформ это похоже на опрятное решение и не требует каких-либо изменений кода.

  • Word Wrap в JButtons
  • Как рисовать несколько осей на диаграмме с использованием диаграмм JAVAFX
  • Вращение экземпляров BufferedImage
  • «Метод сравнения нарушает общий контракт!» - TimSort и GridLayout
  • Как представить двойные значения в виде кругов в 2d-матрице в java
  • Добавление jRadioButton в jTable
  • Использование JFileChooser с Swing GUI-classами и слушателями
  • Swing GUI не ждет ввода пользователем
  • Переменная макет в Swing
  • Как отменить выполнение SwingWorker?
  • Проблема с игрой жизни
  • Давайте будем гением компьютера.