wake-up-neo.com

So konfigurieren Sie den Spring-Boot mit der Swing-Anwendung

Ich möchte mit Spring-Boot-Starter-Data-JPA-Funktionen eine Nicht-Web-Anwendung erstellen. In der 52.4-Dokumentation heißt es:

Anwendungscode, den Sie als Geschäftslogik ausführen möchten, kann Als CommandLineRunner implementiert und als @ .Bean-Definition In den Kontext gestellt werden.

Mein AppPrincipalFrame sieht folgendermaßen aus:

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

Und Boot-Anwendungsklasse sieht wie folgt aus:

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

Funktioniert aber nicht. Hat jemand eine Probe darüber?

Editiert und Ausnahme hinzugefügt.

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 

Grüße.

20
Dapaldo

Es ist eine Weile her, seit Sie die Frage gestellt haben, aber ich bin mit dem gleichen Problem in einem alten Projekt, das ich migriere, ausgegangen und habe einen anderen Weg gefunden, ich denke, das ist klarer, um die Dinge zum Laufen zu bringen.

Anstelle von SpringApplication.run(Application.class, args); können Sie Folgendes verwenden: new SpringApplicationBuilder(Main.class).headless(false).run(args);, und es ist nicht erforderlich, dass die Klasse für Spielzeuganwendungen von JFrame erweitert wird. Daher könnte der Code so aussehen:

@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

Die Swing-Anwendung muss in die Swing-Ereigniswarteschlange gestellt werden. 

Also der richtige Weg, es zu tun:

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

Außerdem können wir einfach die Annotation @SpringBootApplication verwenden.

@SpringBootApplication
public class SwingApp extends JFrame {

Ein ausführliches Funktionsbeispiel finden Sie in meinem Spring Boot Swing-Integration -Tutorial.

5
Jan Bodnar

Eine andere einfache und elegante Lösung ist das Deaktivieren der headless-Eigenschaft wie gezeigt hier. Sie müssen dies jedoch tun, bevor Sie den JFrame erstellen/anzeigen.

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

Also das, was für mich funktioniert hat:

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

Anmerkungen in MyClass.class (Ich weiß nicht, ob sie eine Rolle spielen):

@SpringBootApplication
@EnableWebMvc
1
George Z.