Welcome to the fascinating world of UI programming! You will have to retrain a bit: here everything is not the same as in the command line programs. Here, all background tasks related to the interface do not occur immediately, as soon as you have commanded, but in tandem with your work. All this happens in a fixed thread, the so-called UI thread.
What happens in your code?
- You block the UI thread for half a second, then set the button text. An internal flag is set in the graphic library that says "when there is a free minute, you need to update the button".
- You immediately block the UI stream for half a second, and reinstall the button text. Since the “free time” (the “idle loop”) did not come, the text did not have time to be updated. In addition, there is no one to handle mouse and keyboard events at the time of the lock (because the UI thread is busy for
sleep ), so the program looks hung. - Then you install the button text again, this does not change anything, since the flag indicating the need for updating is already cocked.
- And so on, 11 times.
- In the end, when your loop is over, the UI thread is finally free, and can draw your changes. You finally see 0.
What is the problem? You do not have to perform long operations in a UI thread. Thread.sleep is one such operation, but many also read files, load data from a network, or access a database. You have the right to load the UI stream for only a few milliseconds. For the entire time of a long operation running in a UI thread, the application will appear to hang, and UI event handlers will not be called. This behavior of the program immediately turns it into a student crafts.
Updating the UI, the reaction to the mouse, the redrawing of the controls - everything happens in the UI stream, at that moment when this stream is not busy at all. A good program with a UI should be event-oriented, not imperative: you should not steer the program yourself, but only respond to events with short handlers.
What do we have to do? There are two ways. A simple way, which is quite suitable for your purposes: do not block the UI stream, but use the timer that goes with your UI library. It will call your handler at the right time, you will set the button text there, and finish processing. thus, you release the UI flow so that it can update the UI.
Difficult path that applies if you really need to perform a lengthy operation. In this case, you create a separate thread (thread), in which and perform the desired operation. At the right moment, you send the results of the work to the UI stream, which should simply update the UI. Note that in this case, programming becomes much more difficult, since you have to take care of synchronization, locking and communication between threads (just the global variable does not roll). But for your case, this is superfluous, a simple timer is enough.