Подтвердить что ты не робот

Указатель указателя на указатель мыши

Мы пытаемся реорганизовать проект с помощью Guice. Идея состоит в том, чтобы связать весь интерфейс языка с конкретизирующим объектом, таким как французский или польский.

У нас есть модуль для привязки:

public class StandardModule extends AbstractModule {

    @Override
    protected void configure() {

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

    }
 }

И classe (AboutDialog.java), которые используют этот инъецируемый объект:

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

И мы имеем результат:

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

Линия 67:

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

Наш интерфейс:

public interface Language {

    public ResourceBundle getLanguageInUse();
}

И польский класс:

public class Polish implements Language {

    private ResourceBundle languageInUse;

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

    public ResourceBundle getLanguageInUse() {
        return languageInUse;
    }


}

Мы потерялись...

4b9b3361

Ответ 1

Я предполагаю, что вы не создаете свой AboutDialog с помощью Guice.

Что вы можете сделать, это использовать injector.injectMembers(this), где this - это AboutDialog.

Лучшим способом будет то, что AboutDialog будет создан Guice, поэтому все члены будут введены.

Ответ 2

Вы используете "инъекцию поля". Это затруднит использование введенных значений в конструкторе; даже если Guice должен был создать объект (который сейчас не происходит), или вы должны использовать injector.injectMembers(aboutDialog), конструктор будет работать до того, как инжектор получит возможность ввести нужное вам поле.

Немного сложнее создать класс, который принимает переменный параметр, а также введенный параметр. Это оставляет вам несколько вариантов:

  • Вставьте JFrame. Если вы знаете, что JFrame вы собираетесь использовать при создании конструктора, просто используйте bind(JFrame.class).toInstance(myJFrame); в своем модуле. Затем Guice может полностью создать оглавление.

  • Создайте Factory вручную. Таким образом, вы можете ввести AboutDialog.Factory и просто вызвать create, чтобы получить AboutDialog. Это будет выглядеть примерно так:

    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
      }
    }
    
  • Создайте Factory, и пусть Guice подключится к нему с помощью с поддержкой импорта.

    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 return type [AboutDialog] based on
        // the parameters (like JFrame) and the bindings (like Language)
        install(new FactoryModuleBuilder().build(AboutDialog.Factory.class));
      }
    }
    

Как отмечено в комментариях к вопросу, убедитесь, что вы получаете свой AboutDialog (или AboutDialog.Factory через конструктор/поле @Inject ed) или из самого Injector, иначе Guice не будет знать, чтобы вводить параметры.