尝试调用loadFromFXML时,Griffon“错误注入构造函数”

问题描述 投票:0回答:1

我有一系列弹出窗口,用于编辑或查看特定对象。我使用这些弹出窗口来编辑由ORM(ORMLite)处理的各种对象,我想要实现的是通过封装方法实现类似行为的泛型/抽象类。因为我不想为所有弹出对话框提供相同的FXML,我想到的是创建一个“模板”FXML,通过Griffon提供的loadFXML()函数加载它并将其存储在Node对象中Abstract类中创建的Scene的根。我熟悉依赖注入,但我不知道框架的AST,所以我的Abstract类能够在我创建的Abstract类中调用loadFromFXML()。

我在这里发布我的代码:

实现我创建的抽象ViewPopUp类的具体类:

    @ArtifactProviderFor(GriffonView.class)
    public class VerConductoresView extends AbstractViewPopUp<ObservablePlanilla> {
    private VerConductoresController controller;
    private ConductoresModel model;

    VerConductoresView() {
        super(ObservablePlanilla.class, Conductor.class);
        nodeM = new GridPane();
        super.setController(controller);
    }


    @Override
    public void initUI() {
        Stage stage = (Stage) getApplication()
            .createApplicationContainer(Collections.<String,Object>emptyMap());
        stage.setTitle(getApplication().getConfiguration().getAsString("application.title"));
        stage.setScene(init());
        stage.sizeToScene();
        getApplication().getWindowManager().attach("ver-conductores", stage);
    }
}

我创建的抽象视图PopUp:

public abstract class AbstractViewPopUp<T> extends AbstractJavaFXGriffonView {
    protected Class klazz;
    protected Class<T> klazz2;
    protected Scene viewScene;
    protected ViewControllerPopUp viewController;
    protected TableView tableView;
    protected GridPane gridPane;
    protected String[] ignoredNames;
    protected String[] columnNames;
    protected IModel<T> viewModel;
    protected Node nodeM;

    @MVCMember
    public void setController(ViewControllerPopUp controller) {
        this.viewController = controller;
    }


    AbstractViewPopUp(Class<T> k1, Class k2, Node node){
        klazz = k2;
        klazz2 = k1;
        nodeM = node;
        nodeM = loadFromFXML("com.softgan.viewPopUp");
        nodeM = node;
    }

    AbstractViewPopUp(Class<T> k1, Class k2){
        klazz = k2;
        klazz2 = k1;
        nodeM = loadFromFXML("com.softgan.viewPopUp");
    }

    protected Scene init() {
        Scene scene = new Scene(new Group());

        if (nodeM instanceof Parent) {
            scene.setRoot((Parent) nodeM);
        } else {
            ((Group) scene.getRoot()).getChildren().addAll(nodeM);
        }

        connectActions(nodeM, viewController);
        connectMessageSource(nodeM);
        return scene;
    }
}

我想通过Abstract类加载FXML,然后将其存储,以便具体类可以访问加载的FXML,这样我就可以动态地操作其内容,添加标签和文本字段。问题似乎是loadFromFXML抛出NullPointerException,因为它无法从资源中解析FXML文件。我已经尝试使用AST转换来使其具有资源可识别性,但它似乎不是一种有效的方法,因为Guice无法解决我认为的ResourceHandler。

编辑

这是我得到的Stacktrace:

[griffon-pool-1-thread-2] WARN org.codehaus.griffon.runtime.core.controller.AbstractActionManager - An exception occurred when executing com.softgan.ConductoresController.view
griffon.exceptions.InstanceMethodInvocationException: An error occurred while invoking instance method com.softgan.ConductoresController.view()
    at griffon.util.GriffonClassUtils.invokeExactInstanceMethod(GriffonClassUtils.java:3186)
Caused by: griffon.exceptions.GriffonException: An error occurred while executing a task inside the UI thread
    at com.softgan.ConductoresController.view(ConductoresController.java:122)
    at griffon.util.MethodUtils.invokeExactMethod(MethodUtils.java:407)
    at griffon.util.MethodUtils.invokeExactMethod(MethodUtils.java:356)
    at griffon.util.GriffonClassUtils.invokeExactInstanceMethod(GriffonClassUtils.java:3182)
Caused by: java.util.concurrent.ExecutionException: griffon.exceptions.InstanceNotFoundException: Could not find an instance of type com.softgan.VerConductoresView
    ... 4 more
Caused by: griffon.exceptions.InstanceNotFoundException: Could not find an instance of type com.softgan.VerConductoresView
Caused by: com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, java.lang.NullPointerException
  at com.softgan.VerConductoresView.<init>(VerConductoresView.java:31)
  while locating com.softgan.VerConductoresView

1 error
    at com.google.inject.internal.InternalProvisionException.toProvisionException(InternalProvisionException.java:226)
    at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1053)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1086)
Caused by: java.lang.NullPointerException
    at com.softgan.AbstractViewPopUp.<init>(AbstractViewPopUp.java:72)
    at com.softgan.VerConductoresView.<init>(VerConductoresView.java:31)
    at com.softgan.VerConductoresView$$FastClassByGuice$$d0c2bde8.newInstance(<generated>)
    at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:89)
    at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:114)
    at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
    at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
    at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
    at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:120)
    at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
    at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
    ... 1 more
[griffon-pool-1-thread-2] ERROR griffon.core.GriffonExceptionHandler - Uncaught Exception. Stacktrace was sanitized. Set System property 'griffon.full.stacktrace' to 'true' for full report.
griffon.exceptions.InstanceMethodInvocationException: An error occurred while invoking instance method com.softgan.ConductoresController.view()
    at griffon.util.GriffonClassUtils.invokeExactInstanceMethod(GriffonClassUtils.java:3186)
Caused by: griffon.exceptions.GriffonException: An error occurred while executing a task inside the UI thread
    at com.softgan.ConductoresController.view(ConductoresController.java:122)
    at griffon.util.MethodUtils.invokeExactMethod(MethodUtils.java:407)
    at griffon.util.MethodUtils.invokeExactMethod(MethodUtils.java:356)
    at griffon.util.GriffonClassUtils.invokeExactInstanceMethod(GriffonClassUtils.java:3182)
Caused by: java.util.concurrent.ExecutionException: griffon.exceptions.InstanceNotFoundException: Could not find an instance of type com.softgan.VerConductoresView
    ... 4 more
Caused by: griffon.exceptions.InstanceNotFoundException: Could not find an instance of type com.softgan.VerConductoresView
Caused by: com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, java.lang.NullPointerException
  at com.softgan.VerConductoresView.<init>(VerConductoresView.java:31)
  while locating com.softgan.VerConductoresView

1 error
    at com.google.inject.internal.InternalProvisionException.toProvisionException(InternalProvisionException.java:226)
    at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1053)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1086)
Caused by: java.lang.NullPointerException
    at com.softgan.AbstractViewPopUp.<init>(AbstractViewPopUp.java:72)
    at com.softgan.VerConductoresView.<init>(VerConductoresView.java:31)
    at com.softgan.VerConductoresView$$FastClassByGuice$$d0c2bde8.newInstance(<generated>)
    at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:89)
    at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:114)
    at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32)
    at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98)
    at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112)
    at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:120)
    at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93)
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306)
    at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050)
    ... 1 more

UPDATE

我已经找到了问题所在。构造函数不知道loadFromFXML方法,因为在尚未加载UI的视图的构造函数中。我所做的只是将loadFromFXML()放在Abstract Class的init()方法中,并直接从Concrete View类中调用它。我通过从initUI方法调用loadFromFXML来发现这一点,该方法可以访问UI。

javafx dependency-injection guice griffon
1个回答
0
投票

只有在编译Groovy代码时,AST转换才适用,这可能不是您正在做的。 loadFromFXML()方法通过使用以下值转换匹配给定参数,期望资源在类路径上可用

arg.replaceAll('.', '/') + ".fxml"

这意味着您的代码将"com.softgan.viewPopUp"解析为"com/softgan/viewPopUp.fxml"。该文件是否存在于src/main/resourcesgriffon-app/resources中?

© www.soinside.com 2019 - 2024. All rights reserved.