Correct design to prevent blackscreen issue in JFr

2019-09-20 02:00发布

In my application I have a main frame window GUI, that launches a task in an executor service.

The submitted task generates output and stores in a file on Disk.

As soon as the o/p is generated GUI (observer) is informed of the o/p generated.

Here the problem is I am keeping a wait loop inside the main frame and as soon as a notification is received, the main panel is repainted on the main frame.

For small tasks this works fine, but as the size of the threaded task increases. The wait loop time increases and the GUI main window turns black till computations are done.

Can you please help me in correcting the design. Also How can a SwingWorker thread help in this case.

2条回答
男人必须洒脱
2楼-- · 2019-09-20 02:49

1) Wait loops are the bane of all that is GUI. They are OK in other threads you have spawned, tricky in Executors (as they sometimes have limits on number of Threads, depending on which you use), and are completely out of the question on the EDT. That is the reason for your "blackscreen"

2) Instead of using a custom (I assume it's custom) signal protocol and a wait loop, you could use one of the utility classes in Swing. For example, SwingUtilities has a couple of nice methods - invokeLater and invokeAndWait that take a Runnable and execute it on the EDT as soon as they can. Using this instead of the signal you have will allow you to not block the EDT and make your GUI responsive.

3) If you really want to use a SwingWorkeryou may want to look through the documentation for it. It is essentially a way to do background tasks and report progress or completion/result to the EDT. Currently it uses an ExecutorService with 2 background threads, so having a lot of long running tasks on them is not a good idea (they will block each other). When creating a SwingWorker you would specify the method to be ran in the background, the method to be ran on the EDT when intermediate results are available, and the method to be ran on the EDT when you're finished either successfully or in error.

4) This does not pertain to the question at hand, but if you ever get into a situation where you need a wait loop in the EDT and cannot avoid it using another design or technique, you can always switch to using a Timer. It can be setup to be called every x milliseconds without blocking the EDT and turned off once you are satisfied with some condition.

查看更多
祖国的老花朵
3楼-- · 2019-09-20 02:53

The wait loop time increases and the GUI main window turns black till computations are done.

Then you long running task is executing on the Event Dispatch Thread (EDT) which prevents the GUI from repainting itself. You need to execute the long running task in a separate Thread. A SwingWorker is a separate Thread which has an API that also allows you to execute code on the EDT as required, for example when the code finishes executing or when you have intermediate results.

Read the section from the Swing tutorial on Concurrency for more information. You can always search the forums for example of using a SwingWorker.

查看更多
登录 后发表回答