Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


doEvents in Java

Posted on 2001-07-23
Medium Priority
Last Modified: 2007-11-27
Is there a statement in Java that is similar to the Visual Basic DoEvents statement?  I would like to update a progress bar while running a series of tasks.  After each task I set a progress bar value but the progress bar is not updated until all of the tasks complete.
Question by:rossc
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Expert Comment

ID: 6310080
In java you need to register listeners for events you want to track. So if you wish to track the Mouse events like mousedown, up a certain class, you have to implement the MouseListener interface. What that means is your class must implement the methods in the MouseListener interface. Once you do that, in the main or elsewhere you add your object as a listener. For. e.g. in your Frame class you do this.addListener(<object of your class which implements the MouseListener interface>....when you do this, for all mouse events your class' methods will be invoked.....more work than the DoEvents of VB...but neat....

Expert Comment

ID: 6310103
for your purpose, if you're using a JProgressBar, you might just have to call a setValue and then repaint everytime a task might be missing the repaint part

Expert Comment

ID: 6311977
You may consider letting the process you are following in the progress bar run in another thread.

LVL 19

Accepted Solution

Jim Cakalic earned 150 total points
ID: 6313691
You are probably doing your processing as part of some event that occurred in your UI, right? Like maybe the user presses a JButton. You have an ActionListener registered on the JButton and your actionPerformed method looks something like:

   public void actionPerformed(ActionEvent e) {
       setup JProgressBar
       task loop:
           do a task
           update the progress bar

Let me know if I'm off base here. What is happening is that AWT (and thus Swing) handles events on a single thread which is created when your UI is "realized". That thread does all the event dispatching for Swing/AWT components used in your application. When an event like a button press occurs, it delivers it to the target component, your JButton, which gets all it's registered ActionListeners and calls their actionPerformed methods one at a time. This is all happening on the AWT event dispatch thread. Since requests to repaint are queued on the EventQueue serviced by the dispatch thread, the fact that you are blocking that thread from going about it's normal activities "freezes" your UI until the actionPerformed method completes.

The best way to work around that is to start another thread on which the non-UI processing will be done. The first step is to create a Runnable with the work to be done in it's run method. Use that Runnable (created here from an anonymous inner class) to construct a new Thread object and start the Thread.

   private JProgressBar bar;
   public void actionPerformed(ActionEvent e) {
           ... setup the progress bar, put it in the containment hierarchy,
           ... whatever you're already doing is probably okay as long as the
           ... JProgressBar variable is an instance field of the class

           Thread th = new Thread(new Runnable() {
               public void run() {
                   task loop:
                       do a task
                       update the progress bar

This introduces a new wrinkle, though. During the processing we want to update a JProgressBar. Before we moved this code to another thread, it was executing in the event dispatch thread by virtue of the fact that it was occuring in the actionPerformed method. But now it is running on another thread. Great. Unfortunately, it means that you cannot update the JProgressBar component directly by calling its methods. This is because Swing is not thread-safe. Swing components should only be updated from the event dispatch thread.

How to do it then? Use the SwingUtilities class. Here is a basic skeleton that shows what you would do in the loop of your run method above.

  while (continueWorking) {
      ... do some work
      // time to update progress
      private class ProgressUpdater implements Runnable {
          private JProgressBar _bar;
          private int _value;

          ProgressUpdater(JProgressBar bar, int value) {
              _bar = bar;
              _value = value;
          public void run() {

      try {
          Runnable updater = new ProgressUpdater(pbar, n);
      } catch (Exception e) {
          // ignore or do whatever

      ... maybe more work

The basics of this are that we have some bit of code that we want to be invoked on the event dispatch thread. The way SwingUtilities lets us do that is by putting the code we want invoked in the run method of a Runnable object which it will then put on the EventQueue. The invokeAndWait method will wait until the requested action has occurred -- probably what you want. There is another invokeLater method which queues the event and continues. Using that will probably result in stalling again because your work thread could possibly get too much of the available CPU and prevent the UI from updating in a timely manner.

Anyway, the assumption I made here was that the JProgressBar object was available -- probably as an instance variable. You probably wouldn't need to pass them to the constructor of the ProgressUpdater but I showed that happening for completeness. The value n is the progress bar value you went to set. It is definitely best that these be passed as arguments like this. You have to do it in a constructor because the run method doesn't take any arguments.

You could move the ProgressUpdater class definition out of the method if you felt better about it. Just so long as it remains in the same class as the rest of the code. Not just in the same source file. It should be a private member of the same class.

Let me know if you have any problem with this and I'll help you work through it. I didn't test this code but it is cut and paste from working code that I have. If you'd like additional material on this topic, you might have a look at the Java Tutorial:

Of course, I'd be remiss if I didn't mention that JComponent declares a paintImmediately method which "Paints the specified region in this component and all of its descendants that overlap the region, immediately. It's rarely necessary to call this method. In most cases it's more efficient to call repaint, which defers the actual painting and can collapse redundant requests into a single paint call. This method is useful if one needs to update the display while the current event is being dispatched." Here is an example of how to call this method:

    JProgressBar bar = ...

Best regards,
Jim Cakalic

Author Comment

ID: 6322716

You are right, the problem is that the GUI is not being updated until all of the processes have completed.  I used your code and move the processes to another thread but the progress bar still didn't update until everything completed.  To be sure the problem wasn't with the progress bar, I added code to update a label during processing and it also didn't change until all of the processes completed.

I even tried using a progress monitor but it never appeared.  Could be that I got the code for the progress monitor wrong though.

Featured Post

The top UI technologies you need to be aware of

An important part of the job as a front-end developer is to stay up to date and in contact with new tools, trends and workflows. That’s why you cannot miss this upcoming webinar to explore the latest trends in UI technologies!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses

704 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question