Java 如何使用swing应用程序配置spring引导

Java 如何使用swing应用程序配置spring引导,java,swing,spring-boot,Java,Swing,Spring Boot,我想使用SpringBootStarterDataJPA特性来创建一个非web应用程序。 在52.4文件中,说明: 希望作为业务逻辑运行的应用程序代码可以是 作为CommandLineRunner实现,并作为 @Bean定义 我的AppPrincipalFrame看起来像: @Component public class AppPrincipalFrame extends JFrame implements CommandLineRunner{ private JPanel contentPa

我想使用SpringBootStarterDataJPA特性来创建一个非web应用程序。 在52.4文件中,说明:

希望作为业务逻辑运行的应用程序代码可以是 作为CommandLineRunner实现,并作为 @Bean定义

我的AppPrincipalFrame看起来像:

@Component
public class AppPrincipalFrame extends JFrame implements CommandLineRunner{

private JPanel contentPane;

@Override
public void run(String... arg0) throws Exception {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                AppPrincipalFrame frame = new AppPrincipalFrame();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {  
  public static void main(String[] args) {
   ApplicationContext context = SpringApplication.run(Application.class, args);
   AppPrincipalFrame appFrame = context.getBean(AppPrincipalFrame.class);
  }
}
启动应用程序类的外观如下所示:

@Component
public class AppPrincipalFrame extends JFrame implements CommandLineRunner{

private JPanel contentPane;

@Override
public void run(String... arg0) throws Exception {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                AppPrincipalFrame frame = new AppPrincipalFrame();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {  
  public static void main(String[] args) {
   ApplicationContext context = SpringApplication.run(Application.class, args);
   AppPrincipalFrame appFrame = context.getBean(AppPrincipalFrame.class);
  }
}
但是不起作用。有人有这方面的样本吗

编辑并添加异常

Exception in thread "main" org.springframework.beans.factory.BeanCreationException:      Error creating bean with name 'appPrincipalFrame'.

Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [es.adama.swing.ui.AppPrincipalFrame]: Constructor threw exception; nested exception is java.awt.HeadlessException 

问候。

你发布这个问题已经有一段时间了,但我在一个旧项目中遇到了同样的问题,我正在迁移,并想出了一种不同的方法,我认为这更清楚,使事情顺利进行

而不是使用
SpringApplication.run(Application.class,args)您可以使用:
新建SpringApplicationBuilder(Main.class).headless(false).run(args)并且不需要使toy应用程序类从JFrame扩展。因此,代码可能如下所示:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {  
    public static void main(String[] args) {
    ConfigurableApplicationContext context = new SpringApplicationBuilder(Application.class).headless(false).run(args);
    AppPrincipalFrame appFrame = context.getBean(AppPrincipalFrame.class);
}

Swing应用程序必须放在Swing事件队列上。 不这样做是一个严重的错误

因此,正确的方法是:

public static void main(String[] args) {

    ConfigurableApplicationContext ctx = new SpringApplicationBuilder(SwingApp.class)
            .headless(false).run(args);

    EventQueue.invokeLater(() -> {
        SwingApp ex = ctx.getBean(SwingApp.class);
        ex.setVisible(true);
    });
}
此外,我们可以只使用
@SpringBootApplication
注释

@SpringBootApplication
public class SwingApp extends JFrame {

有关完整的工作示例,请参阅我的教程。

另一个简单而优雅的解决方案是禁用headless属性,如图所示 但是,在创建/显示JFrame之前,您必须这样做

System.setProperty("java.awt.headless", "false"); //Disables headless
所以,对我有效的事情是:

SpringApplication.run(MyClass.class, args);
System.setProperty("java.awt.headless", "false");
SwingUtilities.invokeLater(() -> {
    JFrame f = new JFrame("myframe");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
});
MyClass.class中的注释(我不知道它们是否起任何作用):

我发现解决方案非常简单(先运行spring服务器,然后运行swing)
/@组件
公共类SwingApp扩展了JFrame{
vv。。。
}
@SpringBoot应用程序
公共类应用程序{
公共静态void main(字符串[]args){
ConfigurableApplicationContext ctx=新的SpringApplicationBuilder(Application.class)
.无头(错误)。运行(args);
SwingApp sw=新的SwingApp();
sw.setVisible(真);
}
}
先运行swing,然后调用spring服务器运行
/@组件
公共类SwingApp扩展了JFrame{
vv。。。
私有void jButtonRunSpringServer(java.awt.event.ActionEvent evt){
字符串[]args={“abc”,“xyz”};
Application.runSpringServer(args);
}
}
@SpringBoot应用程序
公共类应用程序{
公共静态void main(字符串[]args){
SwingApp sw=新的SwingApp();
sw.setVisible(真);
}
公共静态void runSpringServer(字符串[]args){
/*
ConfigurableApplicationContext ctx=新的SpringApplicationBuilder(Application.class)
.无头(错误)。运行(args);
*/
SpringApplication.run(Application.class,args);
}
}

什么东西“不起作用”?有例外吗?日志?@DaveSyer是的,添加了摘要异常。Spring调用了您的构造函数,如果失败。看起来该构造函数将被调用两次(一次是由Spring创建
@组件
,一次是在它自己的
run()
方法中)。有点奇怪,所以也许你不打算这样做?不确定,但当我只扩展swing JComponent时就会发生这种情况,如果删除它,它会像正常的自动连接类一样正常工作。我试图传递JVM参数-Djava.awt.headless=true,但没有成功。我想我已经解决了。应用程序类还必须继承自JFrameThank for reply@Rumal我将尝试您的解决方案+1,以获取关于
.headless(false)
的注释。我得到了一个
java.awt.HeadlessException
。我花了一段时间才发现这是因为spring boot应用程序。就连我也在运行同样的异常。我将spring boot应用程序与Swigs集成。我尝试了所有的选择,但都没有成功。你找到解决方案了吗?我正在使用Swing的遗留系统,我已经习惯了使用Spring Boot。我想把它们结合起来。EDT的东西我很难掌握。我找到了几个swing+spring引导示例,但他们没有使用EDT进行swing,或者他们使用了不同的方法。像这个,就是。此外,您的示例还获得了对由容器创建的SwingApp allready的引用,因此在我看来,只有setVisible(true)在EDT中运行。但是,这可能是正确的。有一种方法可以测试我们是否在EDT中:
EventQueue.isDispatchThread()
。我已经测试过了,它返回了
true
作为我的例子。请原谅我的无知,但是这个答案与其他答案有什么不同?