You have to understand the thread concept. AWT and Swing run on a thread called EDT (see more in that reply and also in that question). The EDT is responsible for receiving operating system events (mouse, keyboard, drag windows, maximize, minimize, redesign the screen, etc). The EDT is also the thread that responds to events, such as a click on a button.
It is important for the application to be responsive, never to overload the EDT with heavy tasks. You must always make the best effort for her to be free to do what is her purpose and nothing else. That is, tasks such as reading or writing files, performing complicated loop operations, performing batch operations, uploading or downloading data on the internet, etc from within the EDT is a bad idea.
What happens is that you are locking the EDT in an infinite loop. Thus, it will be trapped in the loop and will not be able to process events to redesign the screen nor receive the click on the other button. The solution in your case is to use another thread to release the EDT:
private volatile Thread runner;
private void loop() {
while (runner == Thread.currentThread()) {
System.out.print("Olá");
}
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
if (runner != null) return;
runner = new Thread(this::loop);
runner.start();
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
runner = null;
}
It’s not better to work with Swingworker, that was made to work in parallel with the EDT, rather than create a Thread?
– user28595
@diegofm may be. But in this particular case, this would not bring any advantage, as the method
done()
would not be necessary and thedoInBackground()
would end in a comebackVoid
. In the case of some computation in background which produces a final result with possible intermediate results, certainly theSwingWorker
would be superior, but that’s not the case here.– Victor Stafusa