java - usar - variables de entorno linux
Swing en OSX: cómo atrapar el comando-Q? (6)
¿Has intentado configurar el comando - Q como acelerador en tu menú? ¿Puedes hacer que tu aplicación responda?
No estoy seguro, pero creo que esto funciona en Linux y probablemente en Windows con el Alt - F4 equivalente. Mi aplicación responde a la pulsación de tecla "matar", proceso un código de limpieza y luego hago un System.exit()
programático.
Si estás "solo" después de un manejo elegante de la salida, es posible que también quieras ver el WindowEvent
WINDOW_CLOSING
, donde tradicionalmente "¿estás seguro?" cosas se hacen.
Después de convencerme ("educado") de que las aplicaciones Swing en Mac se ven como nativas , estoy tratando de que las mías parezcan lo más nativas posible. Todo se ve muy bien, pero cuando windowStateChanged(WindowEvent e)
comando + Q o lo hago desde el menú, mi windowStateChanged(WindowEvent e)
no se windowStateChanged(WindowEvent e)
en mi JFrame principal (si salgo de otra manera, se dispara). ¿Cómo puedo responder al verdadero abandono de Apple?
Al principio estaba viendo una violación de ''restricción de acceso'' al intentar acceder a las subclases com.apple.eawt.Application y com.apple.eawt. *.
(Nota: estoy programando en un MAC, usando Eclipse, con Java 1.6 usando Swing)
Así que tuve que modificar mi ruta de compilación java para permitir el acceso a las subclases de Apple agregando la regla de acceso "com / apple / eawt / **". Después de que este código a continuación fue capaz de compilar y trabajar para mí:
//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();
}
});
Esta es una muy buena pregunta, y debo admitir que no tengo la respuesta. Sin embargo, hace un par de años, cuando estaba trabajando en una aplicación Java y me enfrenté a este problema, lo resolví registrando un enlace de cierre con el tiempo de ejecución que haría lo que quería que la aplicación hiciera antes de abandonar. Es una solución pesada pero funcionó. Puede echar un vistazo a mi código y ver si ayuda.
Mirando el enlace a Java para Mac OS X 10.6 Actualización 3 y 10.5 Notas de la versión de actualización 8 Observé que hay una sección en Acción de abandono predeterminado . Esto describe una propiedad del sistema para solicitar que todas las ventanas se cierren en respuesta al elemento de menú "Salir", que parece ser exactamente lo que se necesita. Lo he usado en mi propia aplicación (usando Info.plist para establecer la propiedad solo en OS X), y parece funcionar como se describe. Supuestamente, esto solo funcionaría en versiones recientes de Java / OS X, pero para esas plataformas parece una solución ordenada y no requiere ningún cambio de código.
Puede implementar com.apple.eawt.ApplicationListener
y responder al evento Quit
. Se puede encontrar un ejemplo en el ejemplo de la biblioteca de referencia de Mac OS X , OSXAdapter .
Anexo: Consulte Java para Mac OS X 10.6 Update 3 y 10.5 Update 8 Release Notes para obtener información sobre deprecation, la clase com.apple.eawt.Application
rediseñada y la ubicación de la documentación API para las extensiones Apple Java. .jdk
la .jdk
Control o haga clic con el botón derecho en el archivo .jdk
para Show Package Contents
. Puede navegar por las clases de com.apple.eawt
entre las fuentes OpenJDK.
Como se muestra en este example completo, puede especificar la QuitStrategy
deseada; un WindowListener
responderá a ⌘Q :
Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
Como se observa here , puede establecer la propiedad desde la línea de comando
java -Dapple.eawt.quitStrategy=CLOSE_ALL_WINDOWS -cp build/classes gui.QuitStrategyTest
o al principio del programa, antes de publicar cualquier evento GUI:
System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
EventQueue.invokeLater(new QuitStrategyTest()::display);
Consola, después de ⌘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
Código:
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://.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);
}
}
La respuesta más votado es excelente, pero solo para completar la "mejor manera":
System.setProperty("apple.eawt.quitStrategy", "CLOSE_ALL_WINDOWS");
Esto desencadenará el evento de devolución de llamada de cierre de ventana estándar que debería funcionar muy bien para el código portátil.
Como resultado de la discusión a continuación, parece que es crucial hacer esto muy temprano en la aplicación. Escribí esto temprano en el inicializador estático de la clase principal antes de que se ejecutara cualquier código de UI.