使用按钮停止并启动循环

Sur*_*sla 6 java swing button while-loop

我试图控制我的程序中的while循环停止和启动基于用户输入.我用一个按钮尝试了这个,它的"开始"部分工作,但然后代码进入无限循环,我不能手动终止它.以下是我的所有代码: 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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

框架类

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

循环课

package test;

public class looper {
    public static boolean buttonSet;

    public looper(){
        while (buttonSet==false){
            System.out.println("aaa");
        }       
    }
}
Run Code Online (Sandbox Code Playgroud)

如何解决此问题并停止进入无限循环?

Mad*_*mer 8

Swing是一个单线程框架,这意味着当循环运行时,Event Dispatching Thread被阻止,无法处理新事件,包括重绘请求......

你需要在它自己的线程上下文中启动你的Looper类.这也意味着你需要声明你的循环标志,volatile或者你应该使用一个,AtomicBoolean以便可以跨线程边界检查和修改状态

例如...

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");
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用类似......

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

运行它...

看看并发秋千在Java并发的一些细节

另外要注意,Swing不是线程安全的,你永远不应该在EDT的上下文中创建或修改UI