1

This may be a basic question but one that I am stuck on.

I would like some more understanding on why the GUI is blocked when I start a new thread(runnable) from a button click event? and how do I overcome that? What am I doing wrong?

The code below starts a new thread when it is clicked, however I would like to change the background color of a textbox when that button is clicked but I am unable to do that, also the main ui is unresponsive whilst that thread is running, I believed that I was implementing it correctly by starting a new thread so as to NOT block the main ui but I must have missed something out as this obviously not desired behaviour.

Code:

private void startButtonEvent(ActionEvent evt) {

         ntmStatusText.setBackground(Color.green);// textbackground I want to change

        //Start Ntm Thread
         Thread thread = new Thread(new NtmThread());
           thread.start();

           while(thread.isAlive()){

               System.out.println("thread still working");

           }
           System.out.println("thread stopped");

    }

How do I stop my Ui from becoming unresponsive when running threads?

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
J4C3N-14
  • 686
  • 1
  • 13
  • 32
  • 'while(thread.isAlive()){' NONONO! Do not wait in a GUI event handler. Don't loop, don't join(), don't wait on events. DO NOT! The GUI handler thread is a state-machine. Don't wait in it. Don't loop on any flag. Don't loop around any thread status. Don't wait in a GUI event-handler. Not ever. – Martin James Oct 20 '14 at 23:45
  • Ok thats explained it, I will never ever, ever, ever do that again! Thanks for your help. – J4C3N-14 Oct 21 '14 at 00:02
  • :) OK, I may be a bit drunk... – Martin James Oct 21 '14 at 00:04
  • @MartinJames Party!! – MadProgrammer Oct 21 '14 at 00:06
  • No problem, thats a testament to your knowledge to be able to answer whilst a bit drunk, I on the other hand should probably consider not trying to learn programming at 0100 in the morning :) haha. – J4C3N-14 Oct 21 '14 at 00:09

2 Answers2

3

while(thread.isAlive()){ is a blocking method, it will stop the Event Dispatching Thread until Thread.isAlive becomes false, this prevents it from been able to process new events that are been added to the event queue, including paint requests

This occurs because Swing is a single threaded environment, meaning that there is a single thread responsible for process all events coming into the program. This is handled by the Event Dispatching Thread.

All user generated events are managed within the EDT (that is, you actionPerformed method, is called within the context of the EDT)

Concurrency in Swing

You eaither theen to provide a call back functionality to your NtmThread or consider using a SwingWorker and attaching a PropertyChanegListener to it a monitor for the property state and check that the SwingWorkers state has changed to DONE

See Worker Threads and SwingWorker for more details

As an example: How to use jProgress bar for ProcessBuilder process?

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thank you for your excellent answer on such a noob question, my next question was going to be how to update the ui on the threads progress but you already have that covered, thank you! – J4C3N-14 Oct 21 '14 at 00:05
0

You have created a new thread but you are using current thread to check if the created thread is alive or not while(thread.isAlive()){.
So the current thread can never come out of the loop untill thread you created is not stopped.
And your this current thread was responsible for doing all gui work, but you made it stuck, that is why your GUI is blocked.

afzalex
  • 8,598
  • 2
  • 34
  • 61