0

My Java Swing app performs a number of HTTP requests that, by nature, freeze the screen until response received and processed.

I would like to show a wait cursor during this time, using:

frame.setCursor(JFrame.WAIT_CURSOR);

Unfortunately, this is not working as it is being executed on the UI Thread which will continue processing my HTTP requests.

I'm aware that I should execute the lengthy tasks on a separate Swing Worker Thread, but, to keep my code simple (because in some cases my HTTP request can be interrupted to show a dialog that needs to be executed on the UI thread), I'm looking for a solution to "force" swing to update the mouse cursor before executing future code.

Is there any way to achieve this?

msrd0
  • 7,816
  • 9
  • 47
  • 82
Tom
  • 1,375
  • 3
  • 24
  • 45
  • *"Is there any way to achieve this?"* Not with your current approach. You could use `SwingUtilities.invokeAndWait` to request more details from the UI from within the `SwingWorker`, but a simpler solution would be to design a solution which broke down the segments of your problem into background/non-UI and UI portions... – MadProgrammer Sep 06 '14 at 20:54

2 Answers2

1

My Java Swing app performs a number of HTTP requests that, by nature, freeze the screen until response received and processed.

No. Not by nature!
Only when doing long operations (like HTTP-Requests) in EDT (Event-Dispatch-Thread).
Try to use SwingWorker.

You can take a look here: https://stackoverflow.com/a/782309/3887073

EDIT:
To force setting an custom Cursor (before doing long operation), you may try use:

SwingUtilities.invokeLater(new Runnable()
         {
             public void run() 
             {
                 /*change cursor code here*/
             }
         });

But this may not help. (i did not test)
Anyway, it is absolutely recommended to use SwingWorker.

Community
  • 1
  • 1
Ben
  • 3,378
  • 30
  • 46
  • Thx but that's exactly what I explained: it is executed on the UI Thread (i.e. EDT thread) and I want to avoid using SwingWorker if possible as my situation is quite complex (work will potentially be interrupted and open dialog) – Tom Sep 06 '14 at 20:48
  • @Tom Then use a `Thread`, but remember, Swing is not thread safe, all interactions and modifications to the UI MUST be made within the context of the EDT – MadProgrammer Sep 06 '14 at 20:51
  • @Ben Can you just verify that you're not suggesting to use `invokeAndWait` on the EDT, which would cause and `Exception` to be thrown...in fact, `invokeLater` would be then justifiable in this circumstance. Mind you, it might also be better to use a `PropertyListener` on `SwingWorker` to monitor the state change...but there's not enough context to the question to know which way yo fall... – MadProgrammer Sep 06 '14 at 20:57
  • @MadProgrammer: you are right. invoking invokeAndWait on EDT does not make sense. i edited my Answer. – Ben Sep 06 '14 at 21:00
  • Just tried Ben's suggestion: doesn't work as the cursor code is executed after my http requests are done. Any other idea? Forcing a repaint before doing http? – Tom Sep 06 '14 at 21:23
1

I'm aware that I should execute the lengthy tasks on a separate Swing Worker Thread,

Then that is what you should be doing.

but, to keep my code simple (because in some cases my HTTP request can be interrupted to show a dialog

Then the "interrupted code" should be using a SwingUtitlities.invokeLater(...) to create and display the dialog.

camickr
  • 321,443
  • 19
  • 166
  • 288