3

How could I simulate a long-running database operation? My requirement is to display a dialog box with a JProgressBar until the operation is completed.

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
James P.
  • 19,313
  • 27
  • 97
  • 155
  • You could just use `Thread.sleep(millis)` inside any method to simulate a long running process. Is it that simple :-) – home Oct 30 '11 at 20:18
  • 5
    @home, It's not that simple. You cannot sleep in the EDT. – mre Oct 30 '11 at 20:18
  • 1
    You mean this?: http://stackoverflow.com/questions/1389586/simulation-of-long-running-oracle-db-query – ypercubeᵀᴹ Oct 30 '11 at 20:20
  • @mre: you're correct, but it's still possible to simulate the blocking database request this way. We do not know in which thread the DB call is executed. – home Oct 30 '11 at 21:00
  • @home: you are correct in that we don't have to know which thread it ***is***, but we do have to know which thread it ***isn't***. It isn't on the EDT. – Hovercraft Full Of Eels Oct 30 '11 at 21:38
  • 2
    @Hovercraft: again, I agree. Nevertheless, my understanding is that the OP has already a 'blocking' database call in place, regardless in which thread. So if it's just about simulating a long running process putting the current thread to sleep should solve the problem (of course other issues may exist). – home Oct 31 '11 at 06:58
  • @home: Yes. I have a empty stored procedure to test against but in practice this stored procedure could involve copying a lot of data as a sort of backup. This would mean that the return output would not be instantaneous. – James P. Oct 31 '11 at 11:33
  • @home: no, I disagree. That is precisely the reason for this exercise: to have a Swing application and to learn how *not* to make call a database call on the current thread, which in a Swing application would be the EDT. Please see this article on [Concurrency in Swing](http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html) to see why this is important. – Hovercraft Full Of Eels Oct 31 '11 at 17:46
  • @Hovercraft: (accidentally) I know this article, maybe we just have a different understanding of the OP's question. Btw: +1'nd your answer some time ago as I think it's the correct one. – home Oct 31 '11 at 18:14
  • @home: Thanks. Hopefully the OP will update us on what he eventually does. – Hovercraft Full Of Eels Oct 31 '11 at 18:45

1 Answers1

6

Use a background thread (such as one provided by a SwingWorker) to run a for loop going from 1 to 10 with a Thread.sleep inside of the loop. Then if it is a determinate mode JProgressBar, you can update its value by passing 10 * the loop index to the progress bar (taking care to do so on the Swing thread, the EDT, of course).

Edit:
@James Poulson: If you're using a SwingWorker object, you would use the publish/process methods and the done method to update on the EDT. If you're using your own background thread, you'd be sure to wrap any group of Swing calls in a Runnable and queue it on the EDT with invokeLater.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • +1 It's perfectly OK to sleep on the worker's background thread to simulate latency, as shown [here](http://stackoverflow.com/questions/4637215/can-a-progress-bar-be-used-in-a-class-outside-main/4637725#4637725). – trashgod Oct 30 '11 at 20:29
  • @HovercraftFullOfEels Thanks for the answer. Have to ask, how do I ensure that a component is updated on the EDT? Do I use an invokeLater? – James P. Oct 31 '11 at 11:41