Java Swing依赖注入

时间:2013-09-30 11:19:23

标签: java swing dependency-injection

我有一个Swing GUI,我使用Netbeans构建,直到现在使用静态引用与其他类进行通信。

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

(有关概述,请参阅此question)我现在想要摆脱静态引用并使用依赖注入。

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

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

    } [...]

我苦苦挣扎的一点是,GUI作为一个线程启动,因此不能有任何参数。

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

如何在不破坏我的代码的情况下注入依赖项?这里涉及该主题的大多数问题都是关于Guice的 - 在这一点上我不想使用。< / p>

感谢。

2 个答案:

答案 0 :(得分:1)

您可以将代码更改为:

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

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

然后你可以像这样运行它:

java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        new SwingGUI().setAppInterface(ma).setVisible(true);
    }
});

答案 1 :(得分:0)

我没有看到为什么你不能在run()方法中使用你的注入器(你选择的任何框架),比如

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

如果手动访问进样器,代码中有一些入口点是正常的。我会说初始化GUI的方法就是这样的一点。

请记住,通过将它们声明为final,可以在匿名类型声明中访问周围方法的参数和变量(就像我假设你的线程实例一样):

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

或使用Thread中的相应字段创建一个显式类:

public class GUIStarter implements Runnable {
  private Injector injector;

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

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

然后像

一样使用它
EventQueue.invokeLater(new GUIStarter(injector));

最后,你可以把注射拉到一个水平,比如

public class GUIStarter implements Runnable {
  @Inject Injector injector;

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

GUIStarter s = injector.make(GUIStarter.class);
EventQueue.invokeLater(s);