我有一个简单的JFrame作为我的Java桌面应用程序的主窗口,我想将它配置为Spring bean。我想设置属性,注入依赖项并启动它。这是我的框架类:
public class MainFrame extends JFrame {
public MainFrame() {
setTitle("Static Title");
setVisible(true);
}
}
My 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
实际显示的是框架,但是存在异常,标题仍为“静态标题”。所以我有几个问题......
我已经看到这是done by IBM in a 2005 tutorial但是使用Spring 1.2,我甚至不知道什么是JRE。那么我该如何处理这个异常呢?是否可以将JFrame配置为Spring bean,还是需要代理它或什么?
我也担心不从事件调度线程启动应用程序。所以,如果有一个更清洁的方式,我想知道它。除了我不知道如何派遣建筑本身之外,我可以轻松地派遣所有东西。
最后随意批评整体概念。我没有遇到很多Spring管理的Swing应用程序的例子。我正在使用带有Java-1.6的Spring-3.1。
感谢。
答案 0 :(得分:1)
我遇到了同样的问题,而且看起来它实际上是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>
答案 1 :(得分:1)
使用Spring 3.0.7.RELEASE,3.1.4.RELEASE和3.2.3.RELEASE运行。
这似乎是另一个答案中提到的错误。
答案 2 :(得分:0)
我的想法是让Swing脱离春天。过去任何微不足道的事情,使用别的东西连接GUI都会变得太乏味。相反,我会改变你正在做的事情,只需使用main()
来创建Spring内容,然后创建你的GUI。
如果您在Spring中所做的一切都是创建MainFrame并启动它,那么最简单的方法就是创建一个创建框架的FactoryBean
。工厂也可以通过setVisible()
来电拨打SwingUtilities.invokeLater()
。
答案 3 :(得分:0)
使用Spring 4.0.2.RELEASE确认运行。