2012-11-08 20 views
12

Próbujemy refakturować projekt za pomocą Guice. Chodzi o to, aby związać cały interfejs Język z konkretnym obiektem, takim jak Francuski lub Polski.Wskaźnik zerowania guice Guine

Mamy moduł do wiązania:

public class StandardModule extends AbstractModule { 

    @Override 
    protected void configure() { 

     bind(Language.class).to(Polish.class); 

    } 
} 

A Classe (AboutDialog.java), które wykorzystują tę wstrzykuje obiektu:

@Inject Language language; 

public AboutDialog(JFrame parent) { 
    super(parent, "", true); 
    this.language=language; 
    this.setTitle(language.getLanguageInUse().getString("AboutDialog.title")); 
    this.parent = parent; 
    try { 
     jbInit(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    pack(); 
} 

I mamy w wyniku:

java.lang.NullPointerException at net.sf.jmoney.gui.AboutDialog.<init>(AboutDialog.java:67) 

Linia 67 to:

this.setTitle(language.getLanguageInUse().getString("AboutDialog.title")); 

Nasz interfejs jest:

public interface Language { 

    public ResourceBundle getLanguageInUse(); 
} 

A polska klasa:

public class Polish implements Language { 

    private ResourceBundle languageInUse; 

    public Polish() { 
     languageInUse = ResourceBundle.getBundle(Constants.LANGUAGE_PL); 
    } 

    public ResourceBundle getLanguageInUse() { 
     return languageInUse; 
    } 


} 

Jesteśmy zgubieni ...

+0

należy zmienić kod trochę, aby zobaczyć gdzie jest wyrzucane NPE 'kod ResourceBundle bundle = language.getLanguageInUse();.. label String = bundle.getString ("AboutDialog.title"); ' –

+0

Obiektem zerowym jest język. Uważamy, że zastrzyk nie działa. – user1810567

+0

Jak utworzyć AboutDialog? Nie wydaje mi się, że tworzysz okno dialogowe z Guice, ponieważ Guice potrzebuje pustego konstruktora, czy też gdzieś zaciągasz jframe? –

Odpowiedz

8

Zakładam, że twój nie są tworzenia AboutDialog z pomocą Guice.

Co można zrobić, to użyć injector.injectMembers(this) gdzie this jest AboutDialog.

Najlepszym sposobem byłoby, aby AboutDialog został stworzony przez Guice, więc wszyscy członkowie zostaną wstrzyknięci.

7

Używasz "wtrysku polowego". To utrudni użycie wstrzykniętych wartości w konstruktorze; nawet jeśli Guice tworzy obiekt (co nie dzieje się teraz) lub użyjesz injector.injectMembers(aboutDialog), konstruktor będzie działał zanim wtryskiwacz będzie miał szansę wstrzyknąć pożądane pole.

Trochę trudniej jest utworzyć klasę, która ma zmienny parametr oraz parametr wstrzyknięty. Pozostawia to kilka opcji:

  • Wstrzyknij JFrame. Jeśli wiesz, czego JFrame użyjesz podczas tworzenia konstruktora, po prostu użyj bind(JFrame.class).toInstance(myJFrame); w swoim Module. Wtedy Guice może całkowicie utworzyć AboutDialog.

  • Utwórz fabrykę ręcznie. W ten sposób można wprowadzić AboutDialog.Factory i po prostu zadzwonić pod numer create, aby uzyskać numer AboutDialog. Będzie to wyglądać mniej więcej tak:

    public class AboutDialog extends JDialog { 
    
        /** Injectable factory. */ 
        public static class Factory { 
        @Inject private Language language; 
    
        public AboutDialog create(JFrame parent) { 
         return new AboutDialog(parent, language); 
        } 
        } 
    
        // no @Inject parameter; you're calling "new" yourself above! 
        public AboutDialog(JFrame parent, Language language) { 
        super(parent, "", true); 
        this.language = language; 
        // ... other initialization 
        } 
    } 
    
  • utworzyć fabrykę drutu i niech Guice go dla Ciebie za pośrednictwem assisted injection.

    public class AboutDialog extends JDialog { 
    
        public interface Factory { 
        public AboutDialog create(JFrame parent); 
        } 
    
        // you need the @Inject, and also the @Assisted to tell Guice to 
        // use the parameter instead of Guice bindings 
        @Inject 
        public AboutDialog(@Assisted JFrame parent, Language language) { 
        super(parent, "", true); 
        this.language = language; 
        // ... other initialization 
        } 
    } 
    
    public class StandardModule extends AbstractModule { 
        @Override protected void configure() { 
        bind(Language.class).to(Polish.class); 
    
        // here every method in AboutDialog.Factory will be implemented 
        // to create the method's return type [AboutDialog] based on 
        // the parameters (like JFrame) and the bindings (like Language) 
        install(new FactoryModuleBuilder().build(AboutDialog.Factory.class)); 
        } 
    } 
    

Jak zauważył w komentarzach pytanie, upewnij się, że coraz AboutDialog (lub AboutDialog.Factory poprzez @Inject ed konstruktora/pola lub od samego Injector, albo Guice nie będą wiedzieć, aby wstrzyknąć parametry

+0

Udało nam się wprowadzić obiekt i projekt działa idealnie. Dziękuję za pomoc ^^. – user1810567

+0

Nie ma za co! Jeśli problem zostanie rozwiązany, pamiętaj o [zaakceptuj odpowiedź] (http://stackoverflow.com/faq#howtoask). Powodzenia w projekcie! –

+1

To zdanie "konstruktor działa, zanim wtryskiwacz ma szansę wstrzyknąć pole, które chcesz" uratował mój dzień, ponieważ nie rozumiałem, dlaczego moje wstrzyknięte pola używane w moim domyślnym konstratorze były zawsze zerowe. Dzięki!!! – mljrg