0

To learn some JAVA. I have created a simple SwingUI, a frame and a button. It should return System.out loop every 2 seconds. The button would then stop the loop. But it seems to freeze.. go figure

I would like some help on this. I do have some books here mostly 'dummies', if you can point out the topic or book title I should read. I would be grateful. Thanks.

/**
 * A basic JFrame with a button to stop 'while-loop'
 */
public class TestCode {

    private boolean runLoop;

    public void initFrameUI() {
        // create frame
        JFrame frame = new JFrame();
        frame.setSize(300, 200);
        frame.setVisible(true);
        frame.setLayout(null);

        // create button
        JButton button = new JButton();
        frame.add(button);
        button.setBounds(60, 60, 90, 30);
        button.addActionListener(new ActionListener() {

            // button click event
            @Override
            public void actionPerformed(ActionEvent e) {
                runLoop = false;
            }
        });
    }

    public void printLoop() {
        while (runLoop) {
            try {
                Thread.sleep(2000);
                System.out.println("Loop-da-loop");
            } catch (InterruptedException ex) {
                Logger.getLogger(TestCode.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public static void main(String[] args) {
        // just a start point
        new TestCode();
    }

    public TestCode() {
        // constructor for JFrame
        initFrameUI();
        
        // start the loop
        runLoop = true;
        printLoop();
    }
}
WHISKAS
  • 3
  • 3
  • 2
    *I do have some books here mostly 'dummies'* - well, if those books teach you to use a null layout then you should definitely throw them in the garbage. Swing was designed to be used with layout managers. *if you can point out the topic or book* - read the [Swing tutorial](https://docs.oracle.com/javase/tutorial/uiswing/TOC.html) for all Swing basics. Start with the sections on `Layout Mangers` and `How to Use Timers`. Use the Timer to replace your looping code. See: https://stackoverflow.com/a/25084314/131872 for a basic example that does what you want. Also read the section on `Concurrency`. – camickr May 26 '21 at 14:12
  • Dummies all-in-one is a reference book, it does have a topic on Concurrency, thank you. – WHISKAS May 27 '21 at 13:36

1 Answers1

1

The problem is, your code is blocking the main thread. A thread is essentially responsible for executing your code and there can be multiple threads running at the same time. The main thread is the thread executing your code when your program starts, that is, the thread which executes the main(String[]) method.

Now, the main thread is responsible for updating the UI and reacting to events, like when the user presses a button. However, in your case, the main thread is stuck in the method printLoop() and never gets to chance to react to a pressed button. (It does check the variable runLoop, however it is also responsible for executing the ActionListener which sets this variable to false. But this never happens here.)

What you could do is have a different thread take care of repeatedly printing to the console:

/**
 * A basic JFrame with a button to stop 'while-loop'
 */
public class TestCode {

    private boolean runLoop;

    public void initFrameUI() {
        // create frame
        JFrame frame = new JFrame();
        frame.setSize(300, 200);
        frame.setVisible(true);
        frame.setLayout(null);

        // create button
        JButton button = new JButton();
        frame.add(button);
        button.setBounds(60, 60, 90, 30);
        button.addActionListener(new ActionListener() {

            // button click event
            @Override
            public void actionPerformed(ActionEvent e) {
                runLoop = false;
            }
        });
    }

    public void printLoop() {
        while (runLoop) {
            try {
                Thread.sleep(2000);
                System.out.println("Loop-da-loop");
            } catch (InterruptedException ex) {
                Logger.getLogger(TestCode.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public static void main(String[] args) {
        // just a start point
        new TestCode();
    }

    public TestCode() {
        // constructor for JFrame
        initFrameUI();
        
        // start the loop
        runLoop = true;
        // Have a different thread call printLoop() so the main thread can handle button presses
        new Thread(this::printLoop).start();
    }
}

If you are unfamiliar with working with multiple threads, you should take a look into that before using it frequently, because there are lots of things that can go wrong.

Jolly
  • 199
  • 6