Reputation: 3
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();
}
}
Upvotes: 0
Views: 104
Reputation: 209
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.
Upvotes: 1