Hi,
I have been essaying to migrate parts of a legacy application to CUBA, and find the environment and solution very promising. I am however facing a very basic problem, to which I am not being able to find good answers.
I am building complex use cases which span beyond 2 or 3 entities in depth, and the problem arises when selecting an entity from a browser and navigating to an editor to work on the topmost entity.
The point is that when I launch en editor usecase the platform throws and IllegalStateException: Current Item is null.
I simply navigate by clicking on a row in a browser screen to its primary editor screen. If I check the status of the InstanceContainer in the editor screen (at the onBeforeShow() subscribed method, the item property is null.
If I add the follwing lines in the onBeforeShow(BeforeShowEvent) method in the controller, it gets solved:
Subscribe
private void onBeforeShow(BeforeShowEvent event) {
this.setEntityToEdit(dataManager.reload(this.getEditedEntity(), "contratoInquilino-view"));
contratoInquilinoDc.setItem(this.getEditedEntity());
}
Basically I ask the dataManager to reload the EntityToEdit in the controller to the desired view for the screen, and then set it to the main InstanceContainer in the editor screen.
My question is, shouldn’t this piece of code be unnecessary if I already have the following annotation in the editorscreen controller?:
@EditedEntityContainer(“contratoInquilinoDc”)
I expect the platform to handle that automatically.
I have to say, I override the edit action call from the browser table by calling an utility method like this:
ScreenLaunchUtil.launchEditEntityScreen(contratoInquilinoesTable.getSingleSelected(), null, null,
screenBuilders, this, OpenMode.NEW_TAB, null, null);
This is a utility method in a class of my own (ScreenLaunchUtil) I use to pass to the EditorBuilder 1)the entity being edited, 2) the screen id (null if primary), 3)the listcomponent (null, coming from a browser screen), 4) screenBuilders, 5) origin, 6) OpenMode, 6) dataContext (null coming from a browser screen) and 7) an AfterCloseEvent consumer which is unnecessary, so please ommit it. I attach the full code of the method at the end.
The point is that I see myself in the need of initializing the main InstanceContainer in the editor screen for it to work, when I have already supplied all the information to the platform for it to know:
. the edited entity
. the view I need in the editorscreen via de InstanceContainer
.the InstanceContainer holding the edited entity via the annotation in the controller @EditedEntityContainer(“contratoInquilinoDc”)
For the time being by @subscribing the onBeforeShow() method in the controller I can get through, and all the behavior in the editorusecase, although being complex through the subsequent InstancePropertyContainer instances down the 3 level entity depth, is working properly. So I believe I have managed to understand the expected logic of operation with the CUBA platform.
But this silly problem is driving me mad. Am I doint things right? I don’t think so. Subscribing that method is definetely a sympton that I am missing something very relevant.
Please advise. Any hints are greatly appreciated.
Here the code of my utility method:
public static <T extends StandardEntity> void launchEditEntityScreen(T e, String screenId, ListComponent listComponent, ScreenBuilders screenBuilders, FrameOwner origin, OpenMode openMode, DataContext parentDataContext, ScreenLaunchUtilCloseListener scl){
EditorBuilder eb = screenBuilders.editor(e.getClass(), origin)
.withLaunchMode(openMode);
if (parentDataContext!=null){
eb.withParentDataContext(parentDataContext);
}
if (screenId!=null){
eb.withScreenId(screenId);
}
if (listComponent!=null){
eb.withListComponent(listComponent);
}
eb.editEntity(e);
Screen s = eb.build();
s.show();
s.addAfterCloseListener(event2->{
StandardCloseAction ac = (StandardCloseAction) event2.getCloseAction();
if (ac.getActionId().compareTo("commit")==0){
if (scl!=null){
scl.screenClosed(s);
}
}
int y = 2;
});
}
Thanks for your attention.
Carlos.