2

I have a bot which when started does the following:

    boolean botPaused = false;
    JButton startButton = new JButton("Start/Resume");
    startButton.addMouseListener(new MouseAdapter() {
         @Override
         public void mouseClicked(MouseEvent e) {
             SwingUtilities.invokeLater(() -> {
                 botPaused = false;
                 while (!botPaused) { // infinitely keeps doing this...
                     advertisementBot.advertise();
                }
             });
         }
     });

I want to implement a pause and resume functionality here by changing the botPaused boolean variable. I tried this:

    JButton pauseButton = new JButton("Pause");
    pauseButton.addMouseListener(new MouseAdapter() {
         @Override
         public void mouseClicked(MouseEvent e) {
             SwingUtilities.invokeLater(() -> botPaused = true);
         }
     });
    panel.add(pauseButton);

But it does not pause, I think this is because when I press the pause button, the pause action is added to the event thread, but since the original action is never completed, we never reach the pause action.

How to solve this?

Jeet Roy
  • 91
  • 1
  • 1
  • 4
  • unrelated but the pause button set the loop condition to false. The resume button set te condition back to true, but the loop has been broken so it won't start over. – jhamon Aug 27 '19 at 08:55
  • For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Aug 27 '19 at 08:59
  • Correct @jhamon, thanks for pointing that out, fixed the code. But this still does not solve the issue.... – Jeet Roy Aug 27 '19 at 09:00

1 Answers1

1

The problem is that you run the bot in the Swing event dispatch thread (EDT) so it blocks all other actions.

You should run it in a separate thread. Only the bot actions on the GUI should be done in the EDT.

Something like:

boolean botPaused = false;
JButton startButton = new JButton("Start/Resume");
startButton.addMouseListener(new MouseAdapter() {
     @Override
     public void mouseClicked(MouseEvent e) {
        Thread botThread = new Thread() {
            public void run() {
                while (true) { // infinitely keeps doing this...
                    // do things unrelated to GUI, long tasks, etc
                    SwingUtilities.invokeLater(() -> {
                        // do GUI related task. (display messages, etc.)
                    });
                    // do other things unrelated to GUI, long tasks, etc
                }
            }
        };
        botThread.start();
     }
 });

That's quick dirty code that doesn't treat the pause/resume aspect. I let you figure this part. There are some other posts related (ex: How to Pause and Resume a Thread in Java from another Thread)

As a reminder: EDT should be used only to manipulate swing components. Long/time-consumming tasks should be runned outside the EDT.

jhamon
  • 3,603
  • 4
  • 26
  • 37
  • 1
    You can also use SwingWorker if you need to do a long running background work: https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html – NoDataFound Aug 27 '19 at 10:08
  • Where should I invoke the run method of the botThread then? will it be inside the EDT? – Jeet Roy Aug 27 '19 at 11:05
  • That's not a time consuming step, you can do it right after the declaration. I updated my answer. – jhamon Aug 27 '19 at 12:05