Griffon在尝试调用loadFromFXML

时间:2019-02-15 21:22:19

标签: javafx dependency-injection guice griffon

我有一系列弹出窗口,可在其中编辑或查看特定对象。我使用这些弹出窗口来编辑由ORM(ORMLite)处理的各种对象,我试图实现的目的是拥有一个通用/抽象类,该类通过封装方法实现类似的行为。因为我不想所有的都具有相同的FXML 我想到的弹出对话框是创建一个“模板” FXML,通过Griffon提供的loadFXML()函数加载它,并将其存储在Node对象中,以作为Abstract Class中创建的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

更新

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

1 个答案:

答案 0 :(得分:0)

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

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

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