如何使用swing应用程序配置spring-boot

Dap*_*ldo 21 java swing spring-boot

我想使用spring-boot-starter-data-jpa功能来创建非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();
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

启动应用程序类的样子:

@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);
  }
}
Run Code Online (Sandbox Code Playgroud)

但是不起作用.有人有这方面的样品吗?

编辑和例外添加.

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 
Run Code Online (Sandbox Code Playgroud)

问候.

Rum*_*mal 36

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

而不是使用SpringApplication.run(Application.class, args);你可以使用:new SpringApplicationBuilder(Main.class).headless(false).run(args);并没有必要使玩具Application类从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);
}
Run Code Online (Sandbox Code Playgroud)


Jan*_*nar 10

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);
    });
}
Run Code Online (Sandbox Code Playgroud)

另外,我们可以使用@SpringBootApplication注释.

@SpringBootApplication
public class SwingApp extends JFrame {
Run Code Online (Sandbox Code Playgroud)

有关完整的工作示例,请参阅我的Spring Boot Swing集成教程.

  • 有一个方法可以测试我们是否处于 EDT:`EventQueue.isDispatchThread()`。我已经对其进行了测试,对于我的示例,它返回“true”。 (2认同)

Geo*_* Z. 5

另一个简单而优雅的解决方案是禁用无头属性,如下所示 但是,您必须在创建/显示 JFrame 之前执行此操作。

System.setProperty("java.awt.headless", "false"); //Disables headless
Run Code Online (Sandbox Code Playgroud)

所以,对我有用的东西:

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);
});
Run Code Online (Sandbox Code Playgroud)

MyClass.class 中的注释(我不知道它们是否起作用):

@SpringBootApplication
@EnableWebMvc
Run Code Online (Sandbox Code Playgroud)