Java Swing application: how to get data from a GUI stream to another stream?

In my Swing GUI Java application, I would like to get the following.

There is a non-GUI thread doing some work. At some point, this stream requires input from the user before continuing. Then I would like to make some changes to the GUI, wait for a certain GUI action (for example, click OK), get the entered data from the GUI into a stream without a GUI and continue using calculation.

Looking around, I found a lot of information on how to initiate a task (long run) from a Swing GUI thread in another thread, but none of my problem.

SwingUtilites.invokeAndWait sounds like it is doing a task, but first it takes a Runnable argument instead of Callable , so there is no direct way to return the result, and secondly, it does not solve the problem of waiting for a specific GUI event.

I understand that I can make my own solution using, for example, a CountDownLatch , but for me the problem seems frequent enough to be a standard solution.

So my questions are: is this really a common problem, and if so, is there a solution in the standard library / libraries? If there is no standard solution, how would you solve it? If this problem does not occur often, why not?

+4
source share
4 answers

Removing changes in the GUI is easy, so I assume that you are only asking to return data to the workflow.

First create a Blocking Queue . Ask the worker thread to call take() in the queue and it will block. In the GUI space, as soon as the user enters the correct input, put it in the queue using offer() , and the workflow will receive data and can continue.

+6
source

I think you can use ExecutorService , where you can also track the progress of your task through the Future interface.

+1
source

java.awt.EventQueue.invokeLater works great for running AWT EDT code. It is best to copy changed data or use immutable data better. Locks are possible, but a little risky.

If you are a different thread - this is an event dispatch loop, you can implement something like invokeLater for your thread (but don't make it static!). Probably use it behind some interface that makes sense for the behavior of the thread - so these are real operations, not run , which are specified like anything else. If your thread will block, then the BlockQueue is OK, but it won't block with AWT EDT.

java.awt.EventQueue.invokeAndWait is like a lock. You are probably going to use another lock. Or maybe a castle like invokeAndWait on your own thread. If you do not, AWT will still use locks. Thus, uncontrolled nested locks, this probably means a dead end. Do not use invokeAndWait !

+1
source
 final bool result = doSomething(); SwingUtilities.invokeLater( new Runnable(){ //Runnable method implementation. //use result in your method like local var. }); 

Make sure your shared data is synchronized using lock objects. If you need to pass Runnable arguments, just make your local variables final, and use them in the run method.

0
source

Source: https://habr.com/ru/post/1397840/


All Articles