3

We have built a splash screen for our application. It works fine when the initialization of application is in the main thread, but when I move the initialization in EDT (SwingUtilities.invokeLater in main method), the progress bar and info label do not repaint itself due to blocking of EDT. I know, that using of invokeLater can help me to repaint the GUI. But my problem is: it's really hard to split the initialization of aplication in separate pieces (legacy code). And even if I do it, I will get a ugly matroshka-code (six times invokeLater in invokeLater).

Which solution should I prefer:

  1. Leave initialization in main thread (my current decision)
  2. Try to move it to EDT (if possible) and get matroshka code
  3. Using Foxtrot lib to provide a non-blocking-sleep in EDT each time I update the splash screen (it works fine - the splash screen can repaint itself, but it's a hack for me)

Probably someone has a better solution?

P.S. I've already read some similar questions here but did not found anything helpful for me.

Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
  • I don't see a reason to do the initialization on the `EDT`. Just make sure everything that concerns the `GUI` is done on the `EDT` but the rest can be done in another thread if needed. – Jonathan Drapeau May 28 '14 at 13:16
  • use JWindow (required JFrame as parent) or undecorated JDialog, most common workaround before the SplashSceen was implemented in official API – mKorbel May 28 '14 at 13:17
  • @mKorbel Swing elements like progress bar or label cannot repaint itself due to blocked EDT. – Sergiy Medvynskyy May 28 '14 at 13:23
  • @JonathanDrapeau This is my problem. Lots of XML layout files are read and used on initialization. And I cannot get splitted GUI and non-GUI code. Currently we have no problems with initialization in main thread , but I'm not sure whether it will always work fine. – Sergiy Medvynskyy May 28 '14 at 13:27
  • [Profile](http://stackoverflow.com/q/2064427/230513) to find the lowest hanging fruit. You have to construct GUI component models on the EDT, but you can load the data later used by a particular model on any thread. – trashgod May 28 '14 at 17:47
  • @trashgod you are right. It would better to refactor our initialization code (and if I get time I will do it), but I've hoped to get a simple solution here. – Sergiy Medvynskyy May 28 '14 at 19:37
  • The alternative is to use a `SwingWorker` to initialize model(s); it will take no less time, but the _perceived_ improvement in liveness may be acceptable. – trashgod May 28 '14 at 21:30
  • @trashgod Bingo! Good Idea. Load XML file in doInBackground() and initialize the GUI in done(). I'm not sure whether I can refactor the code for this proposal, but it's realy good! – Sergiy Medvynskyy May 28 '14 at 21:56

1 Answers1

2

Load the source data in the doInBackground() method of a SwingWorker, and publish() intermediate results; update the GUI component's model in process(). While data continues to load, initial results will be displayed and the GUI will function nominally. The real time to load data will remain unchanged, but the perceived time will be less.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045