java - 使用 Guice 注入(inject) Swing 组件的最佳实践?

标签 java swing user-interface dependency-injection guice

我正在使用 Google Guice 作为 IOC 容器开发 Java Swing 应用程序。我直接注入(inject)组件,但这让 Guice 在 EDT 之外 创建组件。

应用程序看起来有点像这样:

private Panel1 panel1;
private Panel2 panel2;

@Inject
public class Application(Panel1 panel1, Panel2 panel2) {
    this.panel1 = panel1;
    this.panel2 = panel2;
}

看题herehere ,我得出的结论是注入(inject) loader 而不是直接注入(inject)组件。

private PanelLoader1 loader1;
private PanelLoader2 loader2;

private Panel1 panel1;
private Panel2 panel2;

@Inject
public class Application(PanelLoader1 loader1, PanelLoader2 loader2) {
    this.loader1 = loader1;
    this.loader2 = loader2;

    loader1.load();
    loader2.load();

    this.panel1 = loader1.get();
    this.panel2 = loader2.get();
}

public class PanelLoader {
    private Panel panel;
    public void load() {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                panel = new Panel();
            }
        });
    }
    public Panel get() {
        return panel;
    }
}

这是正确的吗?这样做有什么最佳做法吗?

最佳答案

如果您想使用“加载程序”,您应该实现 com.google.inject.Provider。查看 http://code.google.com/p/google-guice/wiki/InjectingProviders 中的示例

您不需要自己注入(inject)提供者,您可以配置模块以注入(inject)由提供者创建的对象:

public class PanelModule extends AbstractModule {

@Override
protected void configure() {
    bind(Panel1.class).toProvider(Panel1Provider.class);
}

private static class Panel1Provider implements Provider<Panel1> {

    private Panel1 panel1;

    @Override
    public Panel1 get() {
        try {
            EventQueue.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    panel1 = new Panel1();
                }
            });
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e); // should not happen
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    return panel1;
}

或者,如果每个组件只需要一个实例,您可以将实例直接绑定(bind)到类型:

public class PanelModule extends AbstractModule {

Panel1 panel1;
Panel2 panel2;

@Override
protected void configure() {

    try {
        EventQueue.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                panel1 = new Panel1();
                panel2 = new Panel2();
            }
        });
    } catch (InvocationTargetException e) {
        throw new RuntimeException(e); // should not happen
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }

    bind(Panel1.class).toInstance(panel1);
    bind(Panel2.class).toInstance(panel2);
}

关于java - 使用 Guice 注入(inject) Swing 组件的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10613914/

相关文章:

java - 尝试设置 $JAVA_HOME (linux) 时出错

java - Tomcat 服务器已启动,但未从 Controller 访问 URL

java - JLabel 并通过 JLabel 的 setText(...) 方法交换其保存的文本

ios - 按钮、标签和文本字段隐藏在图像后面

qt - 用于创建视觉状态机的 GUI

python - pyside QTextEdit 选定文本事件

java - 在 Jar 文件中设置图标图像

java - 在 java 中接受 ArrayList 中的字符串作为 ReturnType

java - 如何使 JPanel 在移动时显示在另一个 JPanel 上?

java - 在另一个透明物体上绘制一个透明物体