We help IT Professionals succeed at work.

Callable with Swing

allelopath
allelopath asked
on
I'm trying to use the Callable interface with one of the tasks being to display a Swing component. You run the main in the attached CallableDemo class to see. The problem is the the swing invoke doesn't happen till after then 2nd task. How can this be done?

CallableDemo.java
GenericProgressDialog.java
Comment
Watch Question

Awarded 2011
Awarded 2011

Commented:
I'm not sure what is your problem.
It seesm to work as I understand it should.
So I added sleeping there -
but it fisrt wrietes taht it starts first task and progress bar appears and moves back and forsth
then it sleeps, the writes that it started
second task, seesm that is how it should be


package callablewithswing;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.swing.SwingUtilities;

public class CallableDemo {

	/**
	 * constructor
	 */
	public CallableDemo() {

		final GenericProgressDialog genericProgressDialog = new GenericProgressDialog("Test Callable");

		// set of Callable<Integer>
		Set<Callable<Integer>> taskSet = new HashSet<Callable<Integer>>();

		// add a task to the set
		taskSet.add(new Callable<Integer>() {

			public Integer call() throws Exception {

        		// ensure progress bar updates happen on the event dispatch thread
        		SwingUtilities.invokeLater(new Runnable() {
        			public void run() {
        				genericProgressDialog.setVisible(true);
        			}
        		});

				return 1;
			}
		});

		// add a another task to the set
		taskSet.add(new Callable<Integer>() {
		
			public Integer call() throws Exception {
				// sleep 3 seconds total, 1 second at a time
				for (int s = 0; s < 3; s++) {
					System.out.println (s+1);
					Thread.sleep(1);
				}
				return 2;
			}
		});

		ExecutorService executor = Executors.newSingleThreadExecutor();
        int count = 0;

		for (Callable<Integer> task : taskSet) {
            System.out.println("submitting task " + count);
			Future<Integer> future = executor.submit(task);
            count++;
           
			try {
				Integer result = future.get();
				System.out.println("Finished Task.  Result: " + result);
              
			}
			catch (InterruptedException ie) {
				// thread was interrupted while waiting
				System.err.println("Thread interrupted, exiting.");
				ie.printStackTrace(System.err);
				break;
			}
			catch (CancellationException ce) {
				// task was cancelled
				System.out.println("Task Cancelled");
			}
			catch (ExecutionException ee) {
				// exception thrown in Callable<>.call()
				System.err.println("Exception thrown during task execution: ");
				// ee.getCause() is the exception thrown in the call() method
				ee.getCause().printStackTrace(System.err);
			}
               try{
                   System.out.println("sleeping");
           Thread.sleep(10000);
                   System.out.println("stop sleeping");
              }catch(Exception ex){
                   ex.printStackTrace();
               }
			// wait for result, then continue

		}

		executor.shutdown();

		//genericProgressDialog.setVisible(false);

	}

	/**
	 *
	 * @param s
	 */
	public static void main(String[] s) {

		new CallableDemo();

	}
}

Open in new window

Awarded 2011
Awarded 2011

Commented:
I commented out
//genericProgressDialog.setVisible(false);

but you can return it back - I see the same effect with it.


I think once in several times when I'm starting I do see some delay with popping up
progress bar, but I think it is dependent of my IDE, which can add
its own quirks and interfere with the threads mechanics.

When I close IDE, and reopen it and start this application the first thing,
then progress bar pops up immediately.

It is probably better to try it form command line

Author

Commented:
Oops, there's a mistake that causes the problem to not be visible. Change the 1 to 1000: in this line:
Thread.sleep(1000);

Open in new window

Awarded 2011
Awarded 2011

Commented:
Didn't understand your reamark - what you mean by mistake?

Author

Commented:
The line:
Thread.sleep(1);
needs to be changed to
Thread.sleep(1000);
so as to create an easily perceptible length of time for the progress bar to display.

Even so, it doesn't work correctly. It counts 1,2,3 then displays the progress bar, and then never takes it down.
Awarded 2011
Awarded 2011
Commented:
Look and try my code - I added even 10000 sleeping in between - and it does show the
progress bar to me immediately and if you uncomment

genericProgressDialog.setVisible(false);

which I commented out in the code I pasted,
it does take it down after the process.

What I also mentioned above, is that indeed - out of several launches
of this program it sometimes happen that it does not pop-up immeditately
(more rarely than it pops up).

However if I close my IDE and run this project first thing after I open - it opens immedaitely.
IDE may inrterfere with threads. So I suggest that you test it form command line