Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stopping and starting a loop with a button

I am trying to control a while loop in my program to stop and start based on a user input. I have attempted this with a button and the "start" part of it works but then the code goes into an infinite loop which I cant stop without manually terminating it. The following is all my code: Header Class

package test;

    import javax.swing.JFrame;

    public class headerClass {
        public static void main (String[] args){
            frameClass frame = new frameClass();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(150,75);
            frame.setVisible(true);
        }
    }

Frame Class

package test;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class frameClass extends JFrame {

    private JButton click;

    public frameClass(){
        setLayout(new FlowLayout());
        click = new JButton("Stop Loop");
        add(click);

        thehandler handler = new thehandler();
        click.addActionListener(handler);
    }

    private class thehandler implements ActionListener{
        public void actionPerformed(ActionEvent e){
            if(e.getSource()==click){
                looper loop = new looper();
                looper.buttonSet = !looper.buttonSet;
            }
        }
    }
}

Looping class

package test;

public class looper {
    public static boolean buttonSet;

    public looper(){
        while (buttonSet==false){
            System.out.println("aaa");
        }       
    }
}

How do I fix this and stop if from going into the infinite loop please?

like image 230
Suraj Khosla Avatar asked Dec 26 '14 22:12

Suraj Khosla


People also ask

How do you stop a while loop using a button?

Generally, in programming languages, to stop a continuous while loop, we use a break statement. However, in Tkinter, in place of the while loop, we use after() to run the defined function in a loop. To break the continuous loop, use a global Boolean variable which can be updated to change the running state of the loop.

How do you turn an Arduino on and off with a button?

Simply press the pushbutton for a few seconds and the Arduino will power on and run code. Then, push and hold the pushbutton until the LED illuminates and then release the button to switch power off.

How do you stop a loop in Arduino?

break is used to exit from a for , while or do… ​while loop, bypassing the normal loop condition. It is also used to exit from a switch case statement.

How do I start over loop in Arduino?

The easiest way to jump to begin of loop() is the return; statement. It will leave loop() no matter where you place the command. As loop() is called (invisibly) in a while construct it will start over again.


2 Answers

Swing is a single threaded framework, this means that while the loop is running, the Event Dispatching Thread is been blocked and can't process new events, including repaint requests...

You need to start your Looper class inside it's own thread context. This would also mean that your loop flag would need to be declared volatile or you should use an AtomicBoolean so that state can be inspected and modified across thread boundaries

For example...

public class Looper implements Runnable {

    private AtomicBoolean keepRunning;

    public Looper() {
        keepRunning = new AtomicBoolean(true);
    }

    public void stop() {
        keepRunning.set(false);
    }

    @Override
    public void run() {
        while (keepRunning.get()) {
            System.out.println("aaa");
        }
    }

}

Then you might be able to use something like...

private class thehandler implements ActionListener {

    private Looper looper;

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == click) {
            if (looper == null) {
                looper = new Looper();
                Thread t = new Thread(looper);
                t.start();
            } else {
                looper.stop();
                looper = null;
            }
        }
    }
}

to run it...

Take a look at Concurrency in Swing and Concurrency in Java for some more details

Also beware, Swing is not thread safe, you should never create or modify the UI from out side the context of the EDT

like image 179
MadProgrammer Avatar answered Oct 16 '22 17:10

MadProgrammer


The problem is you start an infinite loop and try to terminate it in the same thread. That doesn't work because the VM executes one task in a thread after another. It would execute the command to stop the looper directly after the loop is finished but an infinite loop never finishes. So it cannot be stopped like this. You need to create a second Thread for the looper. This way you can stop it from your main thread.

like image 2
Gumbo Avatar answered Oct 16 '22 18:10

Gumbo