web-dev-qa-db-fra.com

Comment configurer Spring-Boot avec l'application Swing

J'aimerais utiliser les fonctionnalités de spring-boot-starter-data-jpa pour créer une application non Web.

Le code d'application que vous souhaitez exécuter en tant que logique métier peut être implémenté en tant que CommandLineRunner et déposé dans le contexte en tant que @Bean definition.

Mon AppPrincipalFrame ressemble à:

@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();
            }
        }
    });
}

Et la classe d'application de démarrage ressemble à ceci:

@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);
  }
}

Mais ça ne marche pas. Quelqu'un a un échantillon à ce sujet?

Edité et exception ajoutée.

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 

Cordialement.

20
Dapaldo

Cela fait longtemps que vous n’avez pas posé la question, mais dans un vieux projet, le problème est le même que j’ai migré et j’ai imaginé une façon différente, je pense plus claire, de faire en sorte que les choses fonctionnent.

Au lieu d'utiliser SpringApplication.run(Application.class, args);, vous pouvez utiliser: new SpringApplicationBuilder(Main.class).headless(false).run(args); et il n'est pas nécessaire de faire en sorte que la classe Application toy s'étende à partir de JFrame. Par conséquent, le code pourrait ressembler à:

@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);
}
32
Rumal

L'application Swing doit être placée dans la file d'attente des événements Swing . Ne pas le faire est une grave erreur. 

Donc, la bonne façon de le faire:

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);
    });
}

De plus, nous pouvons simplement utiliser l'annotation @SpringBootApplication.

@SpringBootApplication
public class SwingApp extends JFrame {

Voir mon tutoriel d'intégration Spring Boot Swing pour un exemple de travail complet.

5
Jan Bodnar

Une autre solution simple et élégante consiste à désactiver la propriété sans tête comme indiqué ici. Cependant, vous devrez le faire avant de créer/afficher le cadre JFrame.

System.setProperty("Java.awt.headless", "false"); //Disables headless

Donc, la chose qui a fonctionné pour moi:

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);
});

Annotations dans MyClass.class (je ne sais pas si elles jouent un rôle quelconque):

@SpringBootApplication
@EnableWebMvc
1
George Z.