-1

I need to run a background thread in my Java GUI that only runs when I click a button and pauses when I click that button again. I am not exactly sure how to set this up, but I have placed a thread in my constructor and the while loop within is set to go through when I set a specific boolean to TRUE. One button switches from setting this boolean TRUE or FALSE.

Everything else I have in this GUI works fine. When I tried debugging the thread, it actually works as I step through the thread but nothing when I try running the GUI completely. The GUI is rather large so I'm gonna put up a portion of the constructor and the action listener of the button. The rest of the code is unnecessary since it works just fine. I need to know what I am doing wrong here:

public BasketballGUI() {
    // certain labels and buttons
    Thread runningSim = new Thread() {
        public void run() {
            while(simRun) {
                // do stuff here
            }
        }
    };
    runningSim.start();
}

// other GUI stuff

// actionListener that should run the thread.
class SimButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent arg0) {
        if(!simRun) {
            simRun = true;
            sim.setText("Pause Simulator");
        }
        else if(simRun) {
            simRun = false;
            sim.setText("Run Simulator");
        }
        // other stuff in this actionListener
    }
}
user2334278
  • 1
  • 1
  • 2
  • 2
    @LittleChild No, they can't [`Thread#suspend`](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#suspend%28%29) and [`Thread#resume`](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#resume%28%29) are deprecated and are considered unstable... – MadProgrammer Apr 30 '13 at 02:47
  • 1
    @the original poster, please show some code, please give us an idea of just what it is you're trying to do. – Hovercraft Full Of Eels Apr 30 '13 at 02:48
  • 2
    [No code example](http://sscce.org/), no answer – MadProgrammer Apr 30 '13 at 02:48
  • For better help sooner, post an [SSCCE](http://sscce.org/). I would not go quite as far as @MadProgrammer and state 'no SSCCE, no answer', but it does allude to the fact that many people will ignore questions without an SSCCE. – Andrew Thompson Apr 30 '13 at 02:56
  • @AndrewThompson That's just because I'm a grumpy, lazy old sod ;) – MadProgrammer Apr 30 '13 at 02:57
  • @MadProgrammer Didn't you know? I'm president of the GLOS club! Too lazy to attend meetings though.. ;) – Andrew Thompson Apr 30 '13 at 03:01
  • @MadProgrammer - added a code example. – user2334278 Apr 30 '13 at 03:27
  • @user2334278 How is `simRun` defined? – MadProgrammer Apr 30 '13 at 03:30
  • @MadProgrammer It is a private static boolean located within the class, and it is initialized to FALSE. – user2334278 Apr 30 '13 at 03:44
  • @user2334278 Andrew's answer is probably the best approaching, however, you should define any variables that more then one thread relies on as `volatile`. `private volatile static boolean simRun = false`. I'd also be very careful about making it `static` but that's me – MadProgrammer Apr 30 '13 at 03:48
  • @MadProgrammer I originally set it to static because I attempted to run the thread within the main method, so now I'm not gonna make it static. – user2334278 Apr 30 '13 at 03:59
  • Does anyone know if I can make sure the TextArea is always at the bottom of the scrollpane when I set it's text with a large string? – user2334278 Apr 30 '13 at 05:30

2 Answers2

5
  1. Establish a Swing based Timer with an ActionListener that will be called repeatedly.
  2. In the actionPerformed(ActionEvent) method call repaint().
  3. Start the timer (Timer.start()) when the user clicks Start
  4. Stop the timer (Timer.stop()) when the user clicks Stop

If you cannot get it working from that description, I suggest you post an SSCCE of your best attempt.


I thought I had one 'lying around'.. Try this working SSCCE which uses images created in this SSCCE.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
-1

I could see this background thread useful for a Java GUI when handling button events to affect something like a text area or progress bar.

For the sake of argument, I will build you a tiny GUI that affects a Text Area. I hope this helps you.

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.*;

public class TestClass extends JPanel {

    super("TestClass - Title");
    private AtomicBoolean paused;
    private JTextArea jta;
    private JButton btn;
    private Thread thread;

    public TestClass() {

        paused = new AtomicBoolean(false);
        jta = new JTextArea(100, 100);
        btn = new JButton();

        initialize();
    }

    public void initialize() {

        jta.setLineWrap(true);
        jta.setWrapStyleWord(true);
        add(new JScrollPane(jta));
        btn.setPreferredSize(new Dimension(100, 100));
        btn.setText("Pause");
        btn.addActionListener(new ButtonListener());
        add(btn);

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                while(true) {

                    for(int i = 0; i < Integer.MAX_VALUE; i++) {

                        if(paused.get()) {
                            synchronized(thread) {
                                try {

                                    thread.wait();

                                } catch(InterruptedException e) {
                                }
                            }
                        }
                    }

                    jta.append(Integer.toString(i) + ", ");

               try {

                   Thread.sleep(500);

               } catch (InterruptedException e) {
                }
                }
            }
        };
        thread = new Thread(runnable);
        thread.start();
    }

    @Override
    public Dimension getPreferredSize() {

        return new Dimension(100, 30);

    }

            class ButtonListener implements ActionListener {

                @Override
                public void actionPerformed(ActionEvent event) {

                    if(!paused.get()) {
                        btn.setText("Start");
                        paused.set(true);
                    } else {
                        btn.setText("Pause");
                        paused.set(false);

                        synchronized(thread) {
                            thread.notify();
                        }
                    }
                }
            }
}

Main class to call everything.

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class MainClass {

    public static void main(final String[] arg) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestClass());
                frame.pack();
                frame.setVisible(true);
                frame.setLocationRelativeTo(null);
            }
        });
    }
}

I did not test this code to see if it works exactly, Its main goal is to break you through your coders block and use my components to fix your issue. Hope this helped. Need anything else Email me at DesignatedSoftware@gmail.com

PatchGuru
  • 327
  • 2
  • 12
  • 2
    Yours is very dangerous advice by telling the original poster to make Swing calls, specifically `jta.append(Integer.toString(i) + ", ");` off of the Swing Event Dispatch Thread. Please revise this. – Hovercraft Full Of Eels Apr 30 '13 at 03:23
  • Your code works, and this does what I am hoping to accomplish. It seems that my syntax is a bit off, but if I can make the adjustments I should get this to work. – user2334278 Apr 30 '13 at 04:06
  • @PatchGuru do you know if I can make sure the TextArea is always at the bottom of the scrollpane? – user2334278 Apr 30 '13 at 05:29