2014-04-04 37 views
14

Vorrei utilizzare le funzionalità di spring-boot-starter-data-jpa per creare un'applicazione non web. Nella documentazione 52,4 dice:Come configurare spring-boot con applicazione swing

codice dell'applicazione che si desidera eseguire come la logica di business può essere implementato come un CommandLineRunner e si lasciò cadere il contesto come una definizione @Bean .

mio AppPrincipalFrame assomiglia:

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

E avvio classe di applicazione assomiglia:

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

Ma non funziona. Qualcuno ha un esempio su questo?

Modificato e aggiunto.

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 

Cordiali saluti.

+0

Che cosa "non funziona"? C'è un'eccezione? Log? –

+0

@DaveSyer Sì, aggiunta eccezione riepilogativa. – Dapaldo

+0

Spring ha chiamato il costruttore e se non è riuscito. Sembra che il costruttore verrà chiamato due volte (una volta in Spring per creare il tuo '@ Component' e una volta nel suo metodo' run() '). Leggermente bizzarro, quindi forse non intendevi uno di quelli? –

risposta

25

È passato un po 'di tempo da quando hai postato la domanda, ma ho esaurito lo stesso problema in un vecchio progetto che sto migrando e ho trovato un modo diverso, penso che sia più chiaro, per far funzionare le cose.

Invece di utilizzare SpringApplication.run(Application.class, args); è possibile utilizzare: new SpringApplicationBuilder(Main.class).headless(false).run(args); e non è necessario rendere la classe dell'applicazione giocattolo estesa da JFrame. Quindi il codice potrebbe essere:

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

Grazie per la risposta @Rumal Proverò la tua soluzione – Dapaldo

+1

+1 per la nota su '.headless (false)'. Stavo ricevendo un 'java.awt.HeadlessException'. Mi ci è voluto un po 'per scoprire che questo è dovuto all'applicazione di avvio a molla. – axiopisty

+0

Anche io sto correndo con la stessa eccezione. Ho integrato l'applicazione di avvio Spring con Swings. ho provato quasi tutte le opzioni ma nessuna ha funzionato. Hai trovato una soluzione per questo. – Renukeswar

1

L'applicazione Swing deve essere posizionata sulla coda eventi di swing. Non farlo è un grave errore.

Quindi il modo corretto per farlo:

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

Inoltre, possiamo semplicemente usare il @SpringBootApplication annotazione.

@SpringBootApplication 
public class SwingApp extends JFrame { 

Vedi il mio Spring Boot Swing integration tutorial per un esempio di lavoro completo.