简体   繁体   English

Java Swing依赖注入

[英]Java Swing Dependency Injection

I have a Swing GUI, which I build using Netbeans, which up until now used static references to communicate with other classes. 我有一个Swing GUI,它是使用Netbeans构建的,到目前为止,它一直使用静态引用与其他类进行通信。

+----------------------+
                 | 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. 我挣扎的一点是,GUI是作为线程启动的,因此不能包含任何参数。

 [...]
//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. SO上与该主题相关的大多数问题都与Guice有关-目前我不想使用。

Thanks. 谢谢。

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);
    }
});

I don't see any point why you can't use you injector (whatever framework you choose) in the run() method, like 我什么都看不到为什么不能在run()方法中使用注入器(无论选择哪种框架),例如

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. 我想说,初始化GUI的方法就是这样。

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM