java - 如何将 Swing JFrame 配置为 Spring bean?

标签 java spring swing

我有一个简单的 JFrame 作为 Java 桌面应用程序的主窗口,我想将其配置为 Spring bean。我想设置属性、注入(inject)依赖项并启动它。这是我的框架类:

public class MainFrame extends JFrame {
    public MainFrame() {
        setTitle("Static Title");
        setVisible(true);
    }
}

我的 Spring 应用程序上下文:

<bean class="com.example.MainFrame">
    <property name="title" value="Injected Title" />
</bean>

然后我把它全部点燃......

public static void main(String ... args) {
    new ClassPathXmlApplicationContext("applicationContext.xml");
}

...后面跟着这个java.beans.IntrospectionException:

type mismatch between indexed and non-indexed methods: location

框架实际上已显示,但有一个异常(exception),标题仍然是“静态标题”。所以我有几个问题...

我见过这个 done by IBM in a 2005 tutorial但是到了Spring 1.2,我什至不知道什么是JRE。那么我该如何处理这个异常呢?是否可以将 JFrame 配置为 Spring bean 还是我需要代理它或其他什么?

我还担心不从事件调度线程启动应用程序。因此,如果有一种更干净的方法可以做到这一点,我想知道。我可以轻松地调度所有内容,除了我不知道如何调度构造本身。

最后,请随意批评整体概念。我还没有遇到过很多 Spring 管理的 Swing 应用程序的示例。我正在使用 Spring-3.1 和 Java-1.6。

谢谢。

最佳答案

我也遇到了同样的问题,看来这实际上是 Spring 上的一个错误: https://jira.springsource.org/browse/SPR-8491

我想我会包装一个 FactoryBean围绕面板,看看它是否有效。我稍后会编辑这篇文章,以防它有效(或无效)

--编辑--

好吧,通过 FactoryBean 实例化它确实可以解决这个问题。该声明变得有点尴尬,但这是必须要做的,至少在上述错误得到修复之前是这样。

package com.ats.jnfe.swing;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.FactoryBean;

/**
 * Contorna, em caráter temporário, o bug apontado em:
 * https://jira.springsource.org/browse/SPR-8491
 * Quando o erro acima for resolvido, esta classe estará obsoleta.
 *
 * @author HaroldoOliveira
 */
public class SwingFactoryBean<T> implements FactoryBean<T> {

    private Class<T> beanClass;
    private Map<String, Object> injection;
    private String initMethod;

    private Map<String, PropertyDescriptor> properties;
    private BeanInfo beanInfo;
    private Method initMethodRef;

    public T getObject() throws Exception {
    T t = this.getBeanClass().newInstance();

    if (this.getInjection() != null) {
        for (Map.Entry<String, Object> en : this.getInjection().entrySet()) {
        try {
            this.properties.get(en.getKey()).getWriteMethod()
                .invoke(t, en.getValue());
        } catch (Exception e) {
            throw new BeanInitializationException(MessageFormat.format(
                "Error initializing property {0} of class {1}",
                en.getKey(), this.getBeanClass().getName()), e);
        }
        }
    }

    if (this.initMethodRef != null) {
        this.initMethodRef.invoke(t);
    }

    return t;
    }

    public Class<?> getObjectType() {
    return this.getBeanClass();
    }

    public boolean isSingleton() {
    return false;
    }

    public void initialize() {
    try {
        this.beanInfo = Introspector.getBeanInfo(this.getBeanClass());
        this.properties = new HashMap<String, PropertyDescriptor>();

        PropertyDescriptor[] descriptors = this.beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor pd : descriptors) {
        this.properties.put(pd.getName(), pd);
        }

        if (this.getInitMethod() != null) {
        this.initMethodRef = this.getBeanClass()
            .getMethod(this.getInitMethod());
        }
    } catch (Exception e) {
        throw new BeanInitializationException(
            "Error initializing SwingFactoryBean: " + e.getMessage(), e);
    }
    }

    public Class<T> getBeanClass() {
    if (this.beanClass == null) {
        throw new BeanInitializationException("Class not informed.");
    }
    return this.beanClass;
    }
    public void setBeanClass(Class<T> beanClass) {
    this.beanClass = beanClass;
    }

    public Map<String, Object> getInjection() {
    return injection;
    }
    public void setInjection(Map<String, Object> injection) {
    this.injection = injection;
    }

    public String getInitMethod() {
    return initMethod;
    }
    public void setInitMethod(String initMethod) {
    this.initMethod = initMethod;
    }

}

使用示例:

<bean id="certificadoNFeConfiguracaoDialog" class="com.ats.jnfe.swing.SwingFactoryBean" init-method="initialize" scope="prototype" lazy-init="true">
<property name="beanClass" value="com.ats.ecf.view.swing.util.dialog.OKCancelDialog" />
<property name="initMethod" value="inicializa" />
<property name="injection">
    <map>
    <entry key="selector">
        <bean class="com.ats.jnfe.swing.SwingFactoryBean" init-method="initialize">
        <property name="beanClass" value="com.ats.jnfe.swing.CertificadoNFeConfigPanel" />
        <property name="initMethod" value="inicializa" />
        <property name="injection">
            <map>
            <entry key="fachada" value-ref="certificadoNFeConfiguracaoFacade" />
            </map>
        </property>
        </bean>
    </entry>
    </map>
</property>
</bean>

关于java - 如何将 Swing JFrame 配置为 Spring bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7503123/

相关文章:

java - JList水平自动滚动到右侧

java - 对多个字符串输入中的元音进行计数的程序

java - 使用jsp从数据库检索数据(Hibernate + Spring + Maven)

java - spring 可以用不同的参数化两次注入(inject)样本 bean 吗?

java - 如何在 JOptionPane 消息中显示 JTextfield 输入?

java - 由于变量未初始化,将图像添加到 JPanel 时出错

Java split() 方法最后去除空字符串?

java - 如何让一个点上下移动

java - 将按钮链接到 XML 页面

web-services - 如何使@WebService Spring 感知