Thread stoppen ohne stop()?

sunny01

Aktives Mitglied
Hallo nochmal,

es gibt noch ein kleines Problem mit meiner GUI. Sie enthält mehrere Buttons, unter anderem einen Start- und Stop-Button.

Wenn der Startbutton gedrückt wurde, sollen gewisse Elemente und Actionlistener der GUI deaktiviert werden und das Programm gestartet werden.

Wenn der Stopbutton gedrückt wurde, sollen die Elemente wieder aktiviert werden. Weiters wird ein Parameter gesetzt der an andereren Stellen des Programms geprüft wird und gegebenfalls werden keine weiteren Schritte mehr durchgeführt. Dieses Prüfen wird allerdings über eine Variable gemacht und nicht per Überprüfung ob der Thread noch läuft (denn ursprünglich hatte ich diesen gar nicht).

So, nun habe ich aber einen Thread starten müssen, da sonst die GUI-Elemente nicht direkt nach Klick aktualisiert werden. Das Ganze sieht jetzt so aus:

Java:
    private void startActionPerformed(java.awt.event.ActionEvent evt) {                                      
        t = new Thread(new Runnable() {
            public void run() {
                    start.setEnabled(false);
                    stop.setEnabled(true);
                    par.setStopSimulation(false);
                    activateInput(false);
                    sim.startSim();
                }
            }
        });
        t.start();
}                                     

    private void stopActionPerformed(java.awt.event.ActionEvent evt) {                                     
        t.stop();
        start.setEnabled(true);
        activateInput(true);
        par.setStopSimulation(true);
    }

Das funktioniert so genau so wie ich das möchte. Allerdings ist stop() ja deprecated. Führe ich nur ein interrupt() aus, so wird das deaktivieren der GUI-Elemente und Actionlistener nicht in allen Fällen korrekt durchgeführt und es existieren dann noch Actionlistener, die eigentlich nach dem Stop weg sein sollten.

Wahrscheinlich kann hier mit dem stop nicht viel "passieren", da außer an diesen zwei Stellen nicht mit dem Thread gearbeitet wird (in weiteren Schleifen und Programmteilen wird ja immer der Parameter stopSimulation überprüft, und nicht der Thread selbst).

Aber da ich damit nicht sonderlich viel Erfahrung habe, bin ich trotzdem nicht wirklich sicher, ob ich das so lassen kann, mit dem stop(). Gibt es da eine bessere Möglichkeit?
Sollte ich vielleicht auch überhaupt "alles" umbauen, sodass der Parameter nicht mehr verwendet wird und an anderen Programmstellen immer der Thread überprüft wird? Ich finde es ja so herum einfacher und ursprünglich gab es wie gesagt keinen Thread ... aber jetzt ist die Information wohl irgendwie "doppelt" ... von daher bin ich unsicher ob das nicht eher "doof" ist, so wie es im Moment ist. Und dann ist ja da eben noch das stop-Problem ...

Sorry, von threads habe ich einfach gar keine Ahnung!
Aber hoffentlich kommt von Euch noch jemand mit, was ich da überhaupt mache ...

Liebe Grüße
sunny
 

Marco13

Top Contributor
Aber hoffentlich kommt von Euch noch jemand mit, was ich da überhaupt mache ...

So halb...
Ich nehme an, dass bei "sim.startSim()" irgendwas gemacht wird, was lange dauert, z.B. sowas wie
Java:
class Sim
{
    void startSim()
    {
        while (!par.isSimulationStopped()) 
        {  
            simulateSomething();
        }
    }
}

Das heißt: Der Thread, der diese Methode aufruft, ist so lange mit simulieren beschäftigt, bis dieses Stop-Flag in den "par(ametern?)" auf "true" gesetzt wird. Wenn man das jetzt direkt in die ActionPerformed-Methode reinschreiben würde...
Java:
    private void startActionPerformed(java.awt.event.ActionEvent evt) 
    {                                      
        ...
        sim.startSim();
    }
dann würde da der "Event-Dispatch-Thread" die Simulation durchführen. Der EDT ist aber dafür verantwortlich, das GUI zu akutualisieren und Benutzereingaben zu verarbeiten, und wenn er mit simulieren beschäftigt ist, kann er das nicht (er kann also auch die Buttons nicht dekativieren...)

Das in einen eigenen Thread auslagern ist so weit schon richtig, aber der sollte dann NUR die simulation machen, der Rest kann noch im EDT gemacht werden.

Um das ganze zu stoppen müßte man wissen, wie die Simulation abläuft. Angenommen, dort ist irgendwo eine Schleife, wie oben angedeutet, dann sollte es eigentlich reichen, sowas zu machen wie
Java:
    private void startActionPerformed(java.awt.event.ActionEvent evt) {                                      
        start.setEnabled(false);
        stop.setEnabled(true);
        par.setStopSimulation(false);
        activateInput(false);

        t = new Thread(new Runnable() {
            public void run() {
                    sim.startSim();
                }
            }
        });
        t.start();
}                                     

    private void stopActionPerformed(java.awt.event.ActionEvent evt) {                                     
        start.setEnabled(true);
        activateInput(true);
        par.setStopSimulation(true);
    }

Sobald man dann auf "stop" drückt, wird mit
[c]par.setStopSimulation(true);[/c]
das Flag gesetzt, das bewirkt, dass die Haupt-Simulations-Schleife hier
Code:
        while (!par.isSimulationStopped()) 
        {  
...
beendet wird.

Um Threads zu beenden, muss man sie "ins leere laufen lassen".
 

sunny01

Aktives Mitglied
Ja, schon, aber mein Problem ist ja, dass das so nicht funktioniert ... es sieht im Moment folgendermaßen aus:

Java:
    private void startActionPerformed(java.awt.event.ActionEvent evt) {                                      
        start.setEnabled(false);
        stop.setEnabled(true);
        par.setStopSimulation(false);
        activateInput(false);
        t = new Thread(new Runnable() {
            public void run() {
                if (getInputValues() && checkStartingPoint()) {
                    sim.startSim();
                }
            }
        });
        t.start();
}                                     

    private void stopActionPerformed(java.awt.event.ActionEvent evt) {                                     
        start.setEnabled(true);
        activateInput(true);
        par.setStopSimulation(true);
    }

Wenn man jetzt start drückt, dann stop, dann stoppt alles, soweit so gut. Drückt man aber wieder auf start, dann funktioniert das deaktivierten eines Actionlisteners (welches in activateInput() passiert) nicht mehr, und der Actionlistener ist dann auch aktiv, während die Simulation läuft.

Füge ich das t.stop() ein, dann passiert das nicht mehr ... dafür wird aber auch gleich der ganze Thread gekillt, was ohnehin nicht so wünschenswert ist.

Also um es nochmal zu verdeutlichen: Das Problem ist, dass die activateInput()-Funktion irgendwie nicht so klappt, wie sie soll, sobald man das zweite Mal auf start drückt ... also start - stop - start -> dann tritt das Problem auf.

Die Funktion die den Actionlistener deaktivieren sollte, sieht so aus:

Java:
    public void activateInput(boolean a) {
        //Deactivate or activate input fields
        birthRate.setEnabled(a);
        [... usw. ... das funktioniert alles]
        //Deactivate or activate MouseListener of map
        if (!a) {
            map.removeMouseListener(map.getMouseListeners()[0]);
        }
        else {
            map.addMouseListener(new java.awt.event.MouseAdapter() {

                @Override
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    mapMouseClicked(evt);
                }
            });
        }
    }

Eventuell liegt der Fehler am Entfernen des Mouselisteners?
 

Marco13

Top Contributor
Sieht frickelig aus. Mach' dir Log-Ausgaben
System.out.println("Füge Mouse(nicht Action)Listener hinzu");
...
System.out.println("Nehme Mouse(nicht Action)Listener weg");
und schau' wann die ausgegeben werden.

Notfalls ein KSKB basteln.
 

sunny01

Aktives Mitglied
Ja klar, der boolean stimmt, alle anderen Felder der GUI werden ja wirklich deaktiviert (Inputs usw. - die sind ja dann auch ausgegraut dargestellt), nur das mit dem Listener (stimmt, ist ein MouseListener), das mag nicht.

Ich versuche dann noch ein Beispiel zu basteln!
 

sunny01

Aktives Mitglied
Also so:

Java:
            MouseListener[] ml = map.getListeners(MouseListener.class);
            for(int i = 0; i < ml.length; i++) {
                map.removeMouseListener(ml[i]);
            }

Funktioniert es jetzt. Anscheinend bekommen spätere MouseListener nicht mehr den Index 0 sondern da wird hochgezählt, auch wenn der Listener wieder entfernt wurde.

Allerdings ist das wohl ziemlich hässlich so, da eigentlich immer nur ein MouseListener da sein sollte, und keine Liste.

Kann man das irgendwie besser machen?
Der ursprüngliche MouseListener wurde eigentlich von einem von Netbeans generierten Code hinzugefügt:

Java:
        map.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                mapMouseClicked(evt);
            }
        });

Ich hätte dann versucht, das zu Löschen, und den MouseListener manuell anzulegen, und ihn zu instanziieren damit er eine Referenz hat, die ich dann direkt wieder löschen kann, aber das hat nicht funktioniert (da es sich hier wohl um abstrakte Klassen handelt).

Lg
sunny
 

Marco13

Top Contributor
Java:
class Foo
{
    private MouseListener currentMouseListener = null;


    public void activateInput(boolean a) 
    {
        if (!a) 
        {
            map.removeMouseListener(currentMouseListener);
            currentMouseListener = null;
        }
        else {
            currentMouseListener = new java.awt.event.MouseAdapter() {
 
                @Override
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    mapMouseClicked(evt);
                }
            };
            map.addMouseListener(currentMouseListener );
        }
    }
:bahnhof:
 

sunny01

Aktives Mitglied
Java:
    private MouseListener currentMouseListener;

[...]

        if (!a) {
            map.removeMouseListener(currentMouseListener);
            currentMouseListener = null;

            /*MouseListener[] ml = map.getListeners(MouseListener.class);
            for(int i = 0; i < ml.length; i++) {
                map.removeMouseListener(ml[i]);
            }*/
        }
        else {
            currentMouseListener = new java.awt.event.MouseAdapter() {
                @Override
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    mapMouseClicked(evt);
                }
            };
            map.addMouseListener(currentMouseListener );
        }

Stimmt, da kommt kein Fehler. Aber der Listener verschwindet wieder nicht.
Ändere ich in der Klasse absolut gar nichts, außer dass ich die auskommentierten Zeilen wieder einkommentiere, dann funktionierts. Versteh' gar nichts mehr :noe:

EDIT: Da sind dann immer 2 MouseListener ... hab's mir grad mal in der Entfernen-Schleife ausgeben lassen ... das gibt's doch nicht ... da können doch nicht auf einmal 2 draus werden.
 
Zuletzt bearbeitet:

sunny01

Aktives Mitglied
Also der Fehler war der, dass an anderer Stelle in einer anderen Klasse die Funktion activateInput() ebenfalls aufgerufen wurde ... und somit waren da dann logischerweise zwei MouseListener ... einmal von der anderen Klasse "ausgelöst" und einmal in der GUI selbst ...

Liebe Grüße
sunny

PS: Und der Thread hatte, wie schon festgestellt, damit eigentlich gar nichts zu tun, nur war mir das ganz am Anfang nicht klar, da das Löschen des Threads (per stop()) natürlich alles beendet hatte und dann sah es "richtig" aus, obwohl das ganz ein anderer Effekt war. Das stoppen des Threads brauche ich so in Wirklichkeit gar nicht (sondern habe es so gemacht wie Marco gepostet hat).
Sorry für den falschen Thementitel.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Thread / Prozess stoppen? Java Basics - Anfänger-Themen 22
O Thread aus dem Thread stoppen Java Basics - Anfänger-Themen 6
G Thread stoppen mit System.in.read() Java Basics - Anfänger-Themen 13
M Threads von Gui Thread starten und stoppen Java Basics - Anfänger-Themen 2
Screen Threads Wie thread stoppen/closen ? und wie GUI at runntime updaten? Java Basics - Anfänger-Themen 10
I Thread stoppen und starten Java Basics - Anfänger-Themen 3
A Jlayer: Wie sound stoppen der in einem Thread läuft Java Basics - Anfänger-Themen 7
Dit_ Thread stoppen und wieder starten Java Basics - Anfänger-Themen 2
Dit_ Thread stoppen. Java Basics - Anfänger-Themen 15
O anonymen Thread stoppen Java Basics - Anfänger-Themen 4
G Thread stoppen? Java Basics - Anfänger-Themen 4
T Thread stoppen Java Basics - Anfänger-Themen 4
B Thread will einfach nicht stoppen Java Basics - Anfänger-Themen 12
loadbrain Thread stoppen Java Basics - Anfänger-Themen 7
7 Thread will nicht stoppen Java Basics - Anfänger-Themen 2
F Thread nach unaktivitätszeit stoppen Java Basics - Anfänger-Themen 7
N Thread soll nur einmal ausgeführt werden, aber wie stoppen? Java Basics - Anfänger-Themen 5
T Thread stoppen und wieder starten. Java Basics - Anfänger-Themen 4
G Thread stoppen Java Basics - Anfänger-Themen 7
D Vorschläge für Umstellung auf Thread-Nutzung erwünscht Java Basics - Anfänger-Themen 11
Z Sikuli Thread Fehler Java Basics - Anfänger-Themen 3
Leyla Thread isInterrupt Java Basics - Anfänger-Themen 18
P Meldung aus Java-Klasse in Thread an aufrufende Klasse Java Basics - Anfänger-Themen 1
A Thread XML-Dateien zusammenfügen Java Basics - Anfänger-Themen 11
F influxdb Upload in eigenem Thread Java Basics - Anfänger-Themen 2
frager2345 Thread - Methoden synchronized deklarieren Java Basics - Anfänger-Themen 10
berserkerdq2 Größter unterschied von extends thread und implements runnable? Java Basics - Anfänger-Themen 2
T Thread beenden aus zweiter Klasse Java Basics - Anfänger-Themen 4
A Thread - Synchronized Java Basics - Anfänger-Themen 10
A Thread Producer - Consumer Java Basics - Anfänger-Themen 1
A Thread-Semhapore Java Basics - Anfänger-Themen 0
A Thread Exchanger Java Basics - Anfänger-Themen 22
A Thread-Cyclicbarrier Java Basics - Anfänger-Themen 4
B In einem Thread Endlosschleife beenden Java Basics - Anfänger-Themen 19
A Thread-Verklemmung Java Basics - Anfänger-Themen 10
A Thread-Schreibe-Lese-Problem Java Basics - Anfänger-Themen 4
A Thread find number Java Basics - Anfänger-Themen 8
F Thread.sleep() Java Basics - Anfänger-Themen 5
F Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11 at main.main(main.java:11) Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 3
M Exception in thread "main" java.util.NoSuchElementException Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 8
B Compiler-Fehler Fehlermeldung Exception in thread, falsche Eingabewert Java Basics - Anfänger-Themen 2
M Thread-Zustände Java Basics - Anfänger-Themen 6
CptK For-Schleife in Thread nach jedem Durchlauf pausieren Java Basics - Anfänger-Themen 35
S Kriege Fehler "Exception in thread" beim Benutzen von SubStrings. Java Basics - Anfänger-Themen 2
B Endlosschleife Thread sauber beenden Java Basics - Anfänger-Themen 19
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 1
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 0
O Exception in thread "main" java.lang.ArithmeticException: / by zero Java Basics - Anfänger-Themen 4
C Thread und TimerTask, Verstädnisproblem Java Basics - Anfänger-Themen 10
amgadalghabra Sorting Thread Launcher Java Basics - Anfänger-Themen 3
B Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
A Thread Java Basics - Anfänger-Themen 4
A Thread Java Basics - Anfänger-Themen 1
A Thread Java Basics - Anfänger-Themen 0
R Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 5
S Compiler-Fehler Exception in thread "main" java.lang.Error: Unresolved compilation problem: Java Basics - Anfänger-Themen 6
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 1
I Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 Java Basics - Anfänger-Themen 3
B Threads Thread sleep() Method einfache Frage Java Basics - Anfänger-Themen 8
W Thread Aufgabe - Vorgehensweise Java Basics - Anfänger-Themen 8
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 0
J Threads PrograssBar update während thread Java Basics - Anfänger-Themen 13
D Compiler-Fehler Wert auf Datenbank übertragen und Sleep Thread Java Basics - Anfänger-Themen 3
Spencer Reid JavaFX Memory Thread.sleep Java Basics - Anfänger-Themen 1
S Thread.sleep mit JProgressBar Java Basics - Anfänger-Themen 1
ralfb1105 Frage zu Thread Synchronisation mit wait() und notify() Java Basics - Anfänger-Themen 3
R Exception in thread "main" java.lang.NullPointerException Java Basics - Anfänger-Themen 10
J JavaFX -> SocketIO -> Thread -> Update Label Java Basics - Anfänger-Themen 13
J Thread Handling Java Basics - Anfänger-Themen 9
A Problem mit Thread.sleep Java Basics - Anfänger-Themen 4
C Thread in Methode + raus aus der Schleife Java Basics - Anfänger-Themen 10
E Threads Thread in While-Schleife nur einmal starten Java Basics - Anfänger-Themen 2
F Daten von Thread an den aufrufenden zurückgeben Java Basics - Anfänger-Themen 22
C Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 Java Basics - Anfänger-Themen 3
B Thread Problem Java Basics - Anfänger-Themen 7
N KeyListener in Thread Java Basics - Anfänger-Themen 0
M Thread.sleep() Funktion Java Basics - Anfänger-Themen 1
W JLabel in Main aus Thread verändern. Java Basics - Anfänger-Themen 4
D Ausgeben welcher Thread gerade Arbeitet Java Basics - Anfänger-Themen 8
N Threads Thread-Fehler Java Basics - Anfänger-Themen 2
F Thread um Uhrzeit ausführen Java Basics - Anfänger-Themen 5
F Get/Post als eigener Thread mit Rückgabe Java Basics - Anfänger-Themen 5
J Exception in thread "main" Java Basics - Anfänger-Themen 1
F Thread der auf eine Queue wartet, sicher beenden Java Basics - Anfänger-Themen 4
B Animation mit Thread(s) Java Basics - Anfänger-Themen 23
I Thread.sleep (1000); Java Basics - Anfänger-Themen 1
M Threads Jede Klasse einem Thread zuweisen Java Basics - Anfänger-Themen 7
J Java Thread cancel() und wiederbeleben Java Basics - Anfänger-Themen 4
J BouncingBalls 1 Thread Java Basics - Anfänger-Themen 3
L Fehler: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 4
J Timer oder Thread programmieren ? Java Basics - Anfänger-Themen 10
fLooojava Laufender Thread | Boolean ändern Java Basics - Anfänger-Themen 9
T Thread Pool mit Work Stealing Java Basics - Anfänger-Themen 1
R Java Thread Java Basics - Anfänger-Themen 10
J Welche Methoden laufen im neuen thread ?? Java Basics - Anfänger-Themen 9
S Java memory fehler: Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap spa Java Basics - Anfänger-Themen 5
K Thread - Methoden in die run Methode Schreiben Java Basics - Anfänger-Themen 5
N Threads Exception in thread "main"... Feher bei dem Versuch ein Radius zu berechnen Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben