Endlosschleife mit Startbutton starten und Stopbutton stoppen

Hallo Leute,

ich bin relativ unerfahren in Java und sitze gerade an einem kleinen Tool, das beim Klick auf Start eine Endlosschleife starten soll, welches dann immer zwei Werte zufällig ausgibt und dann zufällig ein, zwei oder drei Sekunden zwischen dem Wechsel der Werte wartet.
Das funktioniert alles auch wunderbar, nur kann ich es nicht wie gewünscht stoppen... 🙁

Ich wollte mit einem BooleanFlag "run" arbeiten, dass bei Klick auf den "EndButton" auf "false" gestellt werden sollte, um die Schleife zu stoppen.

Der Fehler muss hier irgendwo im Code liegen:


Java:
public void actionPerformed(ActionEvent e){       
       
        if(e.getSource() == StartButton){
        run = true;   
        do{
            a= (int) ((Math.random()*length1));
            b= (int) ((Math.random()*length2));
            c= (int) ((Math.random()*3+1));
           
            label1.setText(""+array1[a]+"");
            label2.setText(""+array2[b]+"");
           
            if(c==1){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }else if (c==2){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }else if (c==3){
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
           
        }while(run);
           
        }
        

        if(e.getSource() == EndButton){

            System.out.println("Beendet!");
            run=false;

        }
        
   
    }



Ich würde mich freuen, wenn mir hier jemand weiterhelfen könnte 🙂
 
Kannst du den "EndButton" klicken oder ist die UI eingfroren?
Dein Problem ist das du deine Endlosschleife innerhalb des UI Threads (EDT) ausführst, dadurch blockierst du eben diesen Thread. Einerseits kann der Thread dadurch nicht neuzeichnen andereseits ist die Ausführung von Events blockiert, da alle diese Events im EDT ausgeführt werden.

Lagere deine Schleife in einen eigenen Thread aus.
 
Vielen Dank für die schnelle Rückmeldung 🙂
Ehrlich gesagt weiß ich nicht wie ich das machen kann oder soll :-/
Bin mit Java nicht so vertraut und arbeite mich Stück für Stück mit kleinen Tools ran...
Wenn ich dir den gesamten Code schicke, könntest du es dir dann mal anschauen?
 
Wir können es gerne hier lösen. 🙂
Was genau verstehst du nicht? Wo liegt genau das Problem?

Im vorherigen Post habe ich dich schon mal gefragt ob du den Button klicken kannst oder ob deine UI eingefrorern ist.
 
Ja, UI ist eingefroren und Button kann also nicht geklickt werden.

Ich verstehe an sich nach etwas einlesen das Konzept der Threads schon und dass ich damit dann Funktionen in andere Threads auslagern kann, damit diese dort genutzt werden können.
Aber ich weiß/verstehe nicht, wie ich es in meinem Code umsetzen kann/soll...

Hier mal der Code:

Java:
import java.awt.*;
import java.awt.event.*;

public class Gui extends Frame implements ActionListener{
    private static final long serialVersionUID = 1L;

    static Button StartButton = new Button("Start!");
    static Button EndButton = new Button ("Stop!");
   
    int a, b, c;
    int r1, r2, r3;
    public boolean run = true;
   
    String[] array1 = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q"};
    int length1 = array1.length;
    String[] array2 = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"};
    int length2 = array2.length;

    static Label label1=new Label("");
    static Label label2=new Label("");
   
    public Gui(String s){
        super(s); 
       
        setLayout(new GridLayout(2,2,2,2));
               
        StartButton.addActionListener(this);
        EndButton.addActionListener(this);
        setSize(500,500);
        add(label1);
        add(label2);
       
        add(StartButton);
        add(EndButton);
       
        this.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e){
                dispose();
                System.exit(0);
            }
        });
       
       
        pack();
        setVisible(true);                          
    }

    public void actionPerformed(ActionEvent e){       
       
        if(e.getSource() == StartButton){
        run = true;   
        do{
            a= (int) ((Math.random()*length1));
            b= (int) ((Math.random()*length2));
            c= (int) ((Math.random()*3+1));
           
            System.out.println("Gestartet!");
            System.out.println(""+a+"");
            System.out.println(""+b+"");
            System.out.println(""+c+"");
           
            label1.setText(""+array1[a]+"");
            label2.setText(""+array2[b]+"");
           
            if(c==1){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }else if (c==2){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }else if (c==3){
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
           
        }while(run);
           
        }
       
        if(e.getSource() == EndButton){
           
            System.out.println("Beendet!");
            run=false;
           
        }
           
    }
}


Danke vorab 🙂
 
Erstelle eine Klasse welche das Interface "Runnable" implementiert, dafür musst du die "run" Methode implementieren.
In diese "run" Methode schreibst du dann deine gewünschte Schleife. Die Klasse sollte außerdem dann eine "stop" Methode enthalten sowie das Attribut "run".

In deiner Gui Klasse erstellst du dann ein einen Thread und übergibst ein Objekt deiner Runnable Klasse und startest den Thread.
Wenn du den Thread stoppen willst rufst du von deinem Runnable Objekt eben die "stop" Methode auf.

Hier hast du ein Beispiel: https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html
 

Zurück
Oben