3

I know about the Swing components and that they should be called from the event dispatch thread but as of now i developed test applications which are event thread centric, that means the UI does the program flow definition by calling listeners on event invocation. But i have read that other threads should not communicate with the UI because it is not synchronized.

Most books just teach how to use individual components and not how to to use them in a real world application context.

How does one update status of a completed or in process thread status to a swing component.

UPDATE: If we configure the listener to invoke the job in an ExecutorService how does the working thread update the UI component in a safe manner.

  • You may have a look into [SwingWorker](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html) – Fildor Feb 15 '17 at 15:32
  • You should not modify swing components from inside of SwingWorker. They are separate threads so you should use 'SwingUtilities.invokeLater anyway' – T.G Feb 15 '17 at 15:33
  • @T.G **not true** : "Event Dispatch Thread: All Swing related activities occur on this thread. **SwingWorker invokes the process and done() methods and notifies any PropertyChangeListeners on this thread**." - from https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingWorker.html - Of course you are not supposed to do that in "doInBackground" ... – Fildor Feb 15 '17 at 15:36
  • yes you right, i should clarify that i meant not modify things in `doInBackground`. this is tempting in most cases, but has to be done in methods called by EDT. When you have to do somethng in background, you should call SwingUtilities – T.G Feb 15 '17 at 15:40

4 Answers4

1

the safest way is to use

SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
        });

inside run method you can manipulate Swing components

T.G
  • 1,913
  • 1
  • 16
  • 29
1

The basic answer is calling repaint.

The idea behind AWT/Swing is that at any moment, a component could be shown, resized, moved etc (either by the code or thru user interaction) prompting the need for repainting. So when you do your updating, you should update the model that the rendering is going to be based on... sometimes necessitating doing this on the EDT for consistency's sake, and then use repaint to show the changes to the model

ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
1

You could...

Use SwingUtilities.invokeLater to schedule an a callback to be executed on the EDT at some time in the future.

The problem with this is synchronising data between the threads, as the data that the update might need might no longer be the same it was when the call was made

You could...

Use a SwingWorker. This provides a means to synchronise data changes between the background thread and the EDT as the data is passed through to the process method, so it can act on "relevant"/"related" data at the time it is called, this decreases (some) of the need for synchronising access to the data that the UI might need

UPDATE: If we configure the listener to invoke the job in an ExecutorService how does the working thread update the UI component in a safe manner.

SwingWorker itself is compatiable with ExecutorService, you can add instances of SwingWorker to it, neat trick ;)

For example

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • May i have a simpler/noob version of the example you linked here. –  Feb 16 '17 at 02:45
  • You have a choice, you can stay as you are and never see the solution to this or other problems, or you could have a look at the, relative speaking, simple example which is already linked, which includes a fully runnable example, which you could run and debug, you could also have a look at [How to use Swing Workers](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html) and learn something new and grow as developer. To be frank, when it comes to threading, there is no such thing as a "simple/noob" version – MadProgrammer Feb 16 '17 at 02:49
0

The EDT's only job is to call your handlers. The only way in which you can "communicate" with it is by registering handlers for it to call. (NOTE: The invokeLater(...) method is just a way to register a handler that the EDT will call immediately.)

i have read that other threads should not communicate with the UI because...

Don't think about it in terms of "communicating." Think about it in terms of threads operating on shared objects. What you ought to be saying is, "Other threads should never operate on Swing objects."

Other threads can operate on your objects, and then your objects can show their updated state on screen when the EDT calls their paint(g) methods.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57