3

I come from .NET environment where event listening is pretty easy to implement even for a beginner. But this time I have to do this in Java.

My pseudo code:

MainForm-

public class MainForm extends JFrame {
   ...
   CustomClass current = new CustomClass();       
   Thread t = new Thread(current);
   t.start();
   ...
}

CustomClass-

public class CustomClass implements Runnable {

   @Override
   public void run()
   {
      //...be able to fire an event that access MainForm
   }
}

I found this example but here I have to listen for an event like in this other one. I should mix them up and my skill level in Java is too low. Could you help me elaborating a optimal solution?

Community
  • 1
  • 1
fillobotto
  • 3,698
  • 5
  • 34
  • 58

1 Answers1

1

I think that what you are looking for is SwingWorker.

public class BackgroundThread extends SwingWorker<Integer, String> {

    @Override
    protected Integer doInBackground() throws Exception {
        // background calculation, will run on background thread

        // publish an update
        publish("30% calculated so far");

        // return the result of background task
        return 9;
    }

    @Override
    protected void process(List<String> chunks) { // runs on Event Dispatch Thread
        // if updates are published often, you may get a few of them at once
        // you usually want to display only the latest one:
        System.out.println(chunks.get(chunks.size() - 1));
    }

    @Override
    protected void done() { // runs on Event Dispatch Thread
        try {
            // always call get() in done()
            System.out.println("Answer is: " + get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

Of course when using Swing you want to update some GUI components instead of printing things out. All GUI updates should be done on Event Dispatch Thread.

If you want to only do some updates and the background task doesn't have any result, you should still call get() in done() method. If you don't, any exceptions thrown in doInBackground() will be swallowed - it is very difficult to find out why the application is not working.

Jaroslaw Pawlak
  • 5,538
  • 7
  • 30
  • 57
  • I saw this over the net, but I've got two dubs about: how is it supposed to get the reference of the form in main thread? This way shouldn't be possible to handle many different types of events? – fillobotto Mar 09 '15 at 17:07
  • 1
    You can pass the components via constructor and make them fields in `BackgroundThread` class. Then you can update them in `process(...)` and `done()` methods. Depending on what you are doing, to may not want to have dependency on these components, in which case I would recommend to pass a function via constructor instead. – Jaroslaw Pawlak Mar 09 '15 at 17:11