Esto es lo que hice para la aplicación de mi compañía, esto es un pseudo código por razones legales, pero la cuestión es que si la pantalla no responde, reiniciará la GUI. Siempre que use SwingUtilities para iniciar el EDT, en ese mismo bloque de inicio, cree dos hilos de observador. Un hilo simplemente realizará una acción en el hilo EDT usando las utilidades Swing. Otro hilo supervisará el primer hilo para ver si siente que el primer hilo responde. El primer subproceso solo reconocerá la capacidad de respuesta si puede realizar un comando muy simple.
conjunto isEDTCheck true cuando se ejecuta en modo normal, falsa en modo de depuración (de lo contrario obtendrá constantemente reiniciado.
if (isEDTCheck) {
new Thread("EDTHeartbeat") {
@Override
public void run() {
Runnable thisThingYouDo = new Runnable() {
public void run() {
int x = 0;
}
};
while (true) {
// first thread says we are waiting, aka bad state
edtwait=true;
try {
javax.swing.SwingUtilities.invokeAndWait(thisThingYouDo);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// first thread says we are not waiting, good state
edtwait=false;
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
new Thread("EDTValidator") {
@Override
public void run() {
while (true) {
// is first thread in bad state?
if (edtwait) {
try {
Thread.sleep(3000);
// after 3 seconds are we still in bad state? if so, get rid of initial frame, pop up a dialog box in AWT that does no commands
if (edtwait) {
mainFrame.setVisible(false);
new Dialog();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
public class Dialog extends Frame {
private static final int WIDTH = 400;
private static final int HEIGHT = 300;
Frame f = null;
public Dialog() {
f = this;
hasSomethingBeenEntered=false;
this.setTitle("APP PROBLEM DETECTED");
this.setSize(WIDTH, HEIGHT);
this.setLocation((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth() - myapp.width, 0);
Panel p1 = new Panel() {
@Override
public void paint(final Graphics g) {
int left = Dialog.WIDTH/2 - 45; // don't use WIDTH shadowed by Panel class
int top = Dialog.HEIGHT/2 - 20; // same as above
g.drawString("APP HAS DETECTED A PROBLEM", left, top);
}
};
this.add("Center", p1);
this.setAlwaysOnTop(true);
TextArea tb = new TextArea("APP HAS DETECTED A MAJOR PROBLEM\nIT WILL NOW RESTART IN 5 SECONDS");
this.add(tb);
this.setVisible(true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
restartApp();
}
private void restartApp() {
Runtime.getRuntime().exec("cmd /c start cmd.exe /K \"cd C:\\Progra~1\\Common~1 && C:\\Progra~1\\Common~1\\MyAppDir\\myjavaapp.jar\"");
System.exit(0);
}
yo también quiero hacer la trama() ejecutar código en una clase que se extiende SwingWorker, y ejecuta ese código computacionalmente pesado en la función doInBackground() y luego usa la función done() para actualizar mi pantalla ¿Mi GUI seguirá activa mientras se lleva a cabo el cálculo? – smuggledPancakes
@ user464095: Sí, exactamente. – ColinD
Bingo. Eso es lo que SwingWorker hace y es para. –