0

I have a Swing GUI, which I build using Netbeans, which up until now used static references to communicate with other classes.

                 +----------------------+
                 | MainClass (static)   |
                 |----------------------|
          +------+  -DataList           +-----+
          |      |                      |     |
    static|      +-+--------------+-----+     |static
  reference        |              |           |reference
          |        |new ()        | new ()    |
          |        |              |           |
          |        |              |           |
        +-+--------v----+      +--v-----------+--+
        |               |      |                 |
        | SwingGUIClass |      | ExecClasses     |
        |               |      |                 |
        +--/\-----------+      +-----------------+
           |
          Input file

(For an overview please see this question) I now want to get rid of the static references and use dependency injection.

public class SwingGUI extends javax.swing.JFrame {
    private MainApp ma;

    public SwingGUI(MainApp ma) {
           this.ma = ma;

    } [...]

One point where I struggle is, that the GUI gets started as a Thread, and as such can't have any arguments.

 [...]
//still in SwingGUI.class
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        new SwingGUI().setVisible(true);
    }
});

How can I inject dependencies while not breaking my code? Most of the questions here on SO that deal with that topic are about Guice - which at this point I don't want to use.

Thanks.

Community
  • 1
  • 1
cete3
  • 647
  • 6
  • 19

2 Answers2

1

You could just change the code to something like:

public class SwingGUI extends javax.swing.JFrame {
    private AppInterface ma;

    public SwingGUI() {
    }
    public SwingGUI setAppInterface(AppInterface ma) {
        this.ma = ma;
        return this;
    }
 [...]

Then you can run it like this:

java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        new SwingGUI().setAppInterface(ma).setVisible(true);
    }
});
AppX
  • 528
  • 2
  • 12
  • This is not possible, since the run method is in the same class. I updated my question to clarify this. I'm not completely sure why it's done this way, since I'm building the GUI with Netbeans. – cete3 Sep 30 '13 at 13:10
0

I don't see any point why you can't use you injector (whatever framework you choose) in the run() method, like

public void run() {
  Injector.getInstance().make(SwingGUI.class).setVisible(true);
}

It is normal that you have some entry point(s) in your code were you manually access the injector. I'd say that the method initializing the GUI is such a point.

Remember that you access parameters and variables of the surrounding methods in an anonymous type declaration (like I assume your thread instance is) by declaring them final:

public void startGUI(final Injector inject) {
  EventQueue.invokeLater(new Runnable {
    public void run() {
      injector.make(SwingGUI.class).setVisible(true);
    }
  });
}

or make an explicit class with a respective field from your Thread:

public class GUIStarter implements Runnable {
  private Injector injector;

  public GUIStarter(Injector injector) {
    this.injector = injector;
  }

  @Override
  public void run() { ... }
}

and then use this like

EventQueue.invokeLater(new GUIStarter(injector));

Finally, you could event pull the injection up a level, with something like

public class GUIStarter implements Runnable {
  @Inject Injector injector;

  @Override
  public void run() { ... }
}

and

GUIStarter s = injector.make(GUIStarter.class);
EventQueue.invokeLater(s);
Sven Amann
  • 565
  • 2
  • 12
  • I'm not using any framework, and I updated my questions to clarify the code structure. Your methods unfortunately don't work, since AFAIU the run() is in a different class. – cete3 Sep 30 '13 at 13:12
  • If you don't use any dependency-injection (DI) framework, how do you plan to use DI? Sorry, I typed Thread instead of Runnable, updated the code above, maybe now it works for you ;) – Sven Amann Sep 30 '13 at 13:30
  • You don't need a framework to DI. Read more [here](http://stackoverflow.com/a/140655/1064781) – cete3 Sep 30 '13 at 13:35
  • You need something that resolves your dependencies and sets the fields/calls the constructor/calls the methods, i.e., a DI container/injector/DI framework, or whatever else you want to call it. The child's name shouldn't be the problem here ;) – Sven Amann Sep 30 '13 at 13:41