Hier ist, was ich für meine Firma App gemacht habe, das ist ein Pseudo-Code aus rechtlichen Gründen, aber die Jist ist, dass, wenn der Bildschirm nicht mehr reagiert, wird es die GUI neu starten. Wenn Sie SwingUtilities zum Starten des EDT verwenden, erstellen Sie in demselben init-Block zwei Watcher-Threads. Ein Thread führt einfach eine Aktion für den EDT-Thread mithilfe von Swing-Dienstprogrammen durch. Ein anderer Thread überwacht den ersten Thread, um zu sehen, ob der erste Thread reagiert. Der erste Thread erkennt die Reaktionsfähigkeit nur, wenn er einen sehr einfachen Befehl ausführen kann.
Satz isEDTCheck auf true, wenn in der normalen Art und Weise, falsch im Debug-Modus ausgeführt wird (sonst werden Sie ständig neu gestartet bekommen.
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);
}
So kann ich die Handlung() Code läuft in einer Klasse machen will, die sich SwingWorker, und führen Sie diesen rechenintensiven Code in der Funktion doInBackground() aus und verwenden Sie dann die Funktion done(), um meine Anzeige zu aktualisieren. Wird meine GUI während der Berechnung noch aktiv sein? – smuggledPancakes
@ user464095: Ja, genau. – ColinD
Bingo. Dafür ist und ist SwingWorker. –