Tom
Tom

Reputation: 97

How to stop action events based on Threads in Java

I have a program which moves the mouse cursor when you click 'Start'

On clicking 'Start' I create a new Thread and the cursor starts moving. When I click 'Pause' the cursor still moves even though the variable is set to false.

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Font;

public class Main extends JFrame {
    private final long serialVersionUID = 1L;
    private JPanel contentPane;
    private static final int TEN_SECONDS = 10000;
    private boolean moving = false;
    Thr thr;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Main frame = new Main();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Main() {     
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);

        JButton start = new JButton("Start");
        start.setFont(new Font("Lucida Grande", Font.PLAIN, 15));
        start.setLocation(163, 20);
        start.setSize(146, 53);
        start.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.print("started");
                MouseMoveLogic(true);
                return;
            }
        });
        contentPane.setLayout(null);
        contentPane.add(start);

        JButton pause = new JButton("Pause");
        pause.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.print("paused");
                MouseMoveLogic(false);
                return;
            }
        });
        pause.setFont(new Font("Lucida Grande", Font.PLAIN, 15));
        pause.setBounds(163, 102, 146, 53);
        contentPane.add(pause);

        JButton quit = new JButton("Quit");
        quit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        quit.setFont(new Font("Lucida Grande", Font.PLAIN, 15));
        quit.setBounds(163, 191, 146, 53);
        contentPane.add(quit);



    }

    public void MouseMoveLogic(boolean flag) {
        Thr thr = new Thr(moving, flag);
        thr.start();
    }
}
import java.awt.AWTException;
import java.awt.Robot;
import java.util.Random;

public class Thr extends Thread {
    private static Robot robot;
    private static final int MAX_Y = 400;
    private static final int MAX_X = 400;
    private boolean moving;
    private boolean flag;

    public Thr(boolean moving, boolean flag) {
        this.moving = moving;
        this.flag = flag;
    }

    @Override
    public void run() {
        try {
            if (robot == null) {
                robot = new Robot();
            }

            Random random = new Random();

            if (!flag && moving) {
                moving = flag;
            } else if (flag) {
                moving = flag;
            }

            while (moving) {
                robot.mouseMove(random.nextInt(MAX_X), random.nextInt(MAX_Y));
                robot.delay(2000);
            }

            if (!moving) {
                System.out.println("Trying to stop"); //this is printed when I click 'Pause' so the event is being registered as expected
                Thread.currentThread().interrupt();
            }

        } catch (AWTException e) {
            e.printStackTrace();
        }
    }
}

I cannot figure out why the mouse keeps moving even though moving is set to false when I click 'Pause'.

Can anyone see where I am going wrong or if there is a better approach to this problem?

Upvotes: 0

Views: 226

Answers (1)

camickr
camickr

Reputation: 324098

I cannot figure out why the mouse keeps moving even though moving is set to false when I click 'Pause'.

public void MouseMoveLogic(boolean flag) {
    Thr thr = new Thr(moving, flag);
    thr.start();
}

You start a new Thread. So the old Thread is still executing. Don't start a new Thread.

You need to keep a reference to the original Thread. Then you need to add a method like setMoving(Boolean moving) to the class that implements the Thread. Then you invoke the setMoving(...) method to start/stop the motion.

if there is a better approach to this problem?

You should be using a Swing Timer to schedule the events. The Timer already has stop/start methods that you can invoke.

Read the section from the Swing tutorial on How to Use Timers for more information.

A simple example to get you started: Jlabel showing both old and new numbers

Upvotes: 1

Related Questions