我有一系列弹出窗口,可在其中编辑或查看特定对象。我使用这些弹出窗口来编辑由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。
答案 0 :(得分:0)
AST转换仅在您编译Groovy代码时才适用,而这可能并不是您正在做的。 loadFromFXML()
方法通过使用以下值转换匹配给定参数,期望类路径上的资源可用
arg.replaceAll('.', '/') + ".fxml"
这意味着您的代码将"com.softgan.viewPopUp"
解析为"com/softgan/viewPopUp.fxml"
。该文件是否存在于src/main/resources
或griffon-app/resources
中?