Voici ce que j'ai fait pour l'application de mon entreprise, c'est un peu de code pseudo pour des raisons légales, mais l'idée générale est que si l'écran est non réactif, il redémarrera l'interface GUI. Chaque fois que vous utilisez SwingUtilities pour démarrer l'EDT, dans le même bloc d'initialisation, créez deux threads de surveillance. Un thread se contentera d'effectuer une action sur le thread EDT en utilisant Swing utilities. Un autre thread surveillera le premier thread pour voir s'il est réactif. Le premier thread ne reconnaîtra la réactivité que s'il peut exécuter une commande très simple.
définir isEDTCheck sur true lors de l'exécution normale, false en mode débogage (sinon vous allez être constamment redémarré).
if (isEDTCheck) {
new Thread("EDTHeartbeat") {
@Override
public void run() {
Runnable thisThingYouDo = new Runnable() {
public void run() {
int x = 0;
}
};
while (true) {
// le premier thread dit que nous attendons, alias mauvais état
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();
}
// le premier thread dit que nous n'attendons pas, bon état
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) {
// le premier thread est-il dans un mauvais état ?
if (edtwait) {
try {
Thread.sleep(3000);
// après 3 secondes sommes-nous toujours dans un mauvais état ? si c'est le cas, supprimer le cadre initial, afficher une boîte de dialogue en AWT qui ne fait aucune commande
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("PROBLÈME DÉTECTÉ DANS L'APPLICATION");
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; // ne pas utiliser WIDTH masqué par la classe Panel
int top = Dialog.HEIGHT/2 - 20; // pareil que ci-dessus
g.drawString("L'APPLICATION A DÉTECTÉ UN PROBLÈME", left, top);
}
};
this.add("Center", p1);
this.setAlwaysOnTop(true);
TextArea tb = new TextArea("L'APPLICATION A DÉTECTÉ UN PROBLÈME MAJEUR\nELLE VA RECOMMENCER DANS 5 SECONDES");
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);
}