tags:

views:

109

answers:

1

I will try and illustrate my question with examples, I am attempting to create a Java program that will (eventually) incorporate a complex Swing GUI.

I have Main.java

public class Main extends JFrame implements ActionListener {

    JTextArea example;

    public Main()
    {

    //... Missing, basic swing code
       example = new JTextArea();
    //... example added to jpanel, jpanel added to jframe, jframe set visible etc.


    }

    public void actionPerformed(ActionEvent e) {


    if(e.getActionCommand().equalsIgnoreCase("Do Something!"))
    {
       new DoSomething();
    }

   public static void main(String[] args)  {

   SwingUtilities.invokeLater(new Runnable() {
    public void run() {
     new Main();
      }
    });

}

}

So now, I want my DoSomething() class to update my example JTextArea, what is the best way to do this?

I can pass a reference to example to DoSomething(), so DoSomething(example), but that doesn't seem nice. I could also pass "this" to DoSomething() and implement a updateExample(String newString) method in Main but that doesn't seem great either.

Basically, what is the best way to achieve what I want to do? The program I am writing will ultimately get much more complicated than this and I can't see a way that will allow me to do this without it getting too messy.

+2  A: 

It seems you're looking for Observer pattern

I wrapped up a small example using your words

import java.util.Observable;
import java.util.Observer;


public class Main implements Observer {
    private DoSomething businessClass;

    public Main() {
        businessClass = new DoSomething();
        businessClass.addObserver(this);
    }

    public static void main(String[] args) {
     Main main = new Main();
    }

    @Override
    public void update(Observable obs, Object obj) {
        // Do whatever you want to do with textarea or other UI components
    }
}

class DoSomething extends Observable {
    public DoSomething() {
        Object result = new Object();    // It can be any type not just an object
        // After finish...
        setChanged();
        notifyObservers(result);
    }
}

By using this small pattern the UI can be always aware of the status of your DoSomething class, and that class just need to invoke notifyObservers method. Thus your system keeps decoupled while being robust

victor hugo
Brilliant, thankyou!
Andrew
After playing around with this I found that the observer would not be updated unless I called setChanged(); before notifyObservers();
Andrew
You are right I missed that part. Answer updated
victor hugo