Search code examples
javaswingcallbackswingworkerevent-dispatch-thread

java SwingWorker launching runnables from doInBackground() and howto notify event dispatch thread


just learnd the SwingWorker and have a question
( i have search for a answer to this but non specifically address this setup)

Im creating a small server that will have like max simultaneous 2-3 connections only.
Im using a Jframe that have the inner class SwingWorker

In the SwingWorker doInBackground() i have the:

while(true) {
  Socket client_socket = listen_socket.accept();
  Connection con = new Connection(client_socket, "name");
  Future<Connection> future = es.submit(con , con ); 
  tasks.add(future);
 }

The Connection is a runnable and declared as a subclass in SwingWorker.

Before the runnable has completed it write an entry in the SQL.
How can then this runnable before it dies send a heads-up to Jframe event dispatch thread.
and the Jframewill check the SQL for the new entry and display it to user.

what is best to do:

1 - create an interface witch all runnable can send messages to Jframe event dispatch thread.

2 - use SwingWorker insted of runnables for all new connections and have Done() call a method in server SwingWorker that call method in Jframe using EventQueue.invokeLater..

3 - or use a PropertyChangeListener (somehow no sure)

4 - Let each runnables have s ref to Jframe and do EventQueue.invokeLater..


Solution

  • The SwingWorker docs are pretty clear. You should subclass SwingWorker and perform the long task in the doInBackground() method. You should update the UI in the done() method.

    It really is as easy as that.

    Edit:
    To make it clearer. Assuming your Connection class extends SwingWorker it does not need to implement Runnable and you do not need to explicitly provide a thread pool to run the workers in. Just put the contents of the run() method in doInBackground().

    Now your main loop looks something like this;

    while (true) {
      Socket client_socket = listen_socket.accept();
      Connection con = new Connection(client_socket, "name");
      con.execute();
    }
    

    You seem to be submitting to an ExecutorService in your main loop. Is there a specific reason for this (note that a SwingWorker manages its own internal ThreadPoolExecutor for worker threads). Is it to limit the number of concurrent clients? If so there are other ways to accomplish this.