Hi Oliver,
Natalia is right, but you still can have all subclasses in a single browser with some manual coding.
First, create a database view that selects the superclass together with all subclasses. You can define it in 30.create-db.sql
file to create automatically on database initialization:
create view DEMO_IDENTITY_VIEW as
select i.*, u.SUR_NAME, u.PRE_NAME, g.GROUP_CODE
from DEMO_IDENTITY i
left join DEMO_USER u on u.ID = i.ID
left join DEMO_GROUP g on g.ID = i.ID;
Then create an entity and map it to the database view:
@DbView
@Table(name = "DEMO_IDENTITY_VIEW")
@Entity(name = "demo_IdentityView")
public class IdentityView extends StandardEntity {
private static final long serialVersionUID = -5860138124974857670L;
@Column(name = "DTYPE")
private String identityType; // this field helps to distinguish types
@Column(name = "ACCOUNT_NAME")
private String accountName;
@Column(name = "SUR_NAME")
private String surName;
@Column(name = "PRE_NAME")
private String preName;
@Column(name = "GROUP_CODE")
private String groupCode;
// getters and setters
}
Create a browser screen for IdentityView
entity and editor screens for concrete classes User
and Group
.
In the browser screen, create separate actions for creating Users and Groups:
<groupTable id="identityViewsTable" ...>
<actions>
<action id="createUser" type="create" caption="Create User"/>
<action id="createGroup" type="create" caption="Create Group"/>
...
</actions>
<buttonsPanel id="buttonsPanel" ...>
<button id="createUserBtn" action="identityViewsTable.createUser"/>
<button id="createGroupBtn" action="identityViewsTable.createGroup"/>
...
</buttonsPanel>
In the screen descriptor, override action handlers to dispatch to editor screens of concrete entities:
@UiController("demo_IdentityView.browse")
@UiDescriptor("identity-view-browse.xml")
@LookupComponent("identityViewsTable")
@LoadDataBeforeShow
public class IdentityViewBrowse extends StandardLookup<IdentityView> {
@Inject
private GroupTable<IdentityView> identityViewsTable;
@Inject
private ScreenBuilders screenBuilders;
@Inject
private DataManager dataManager;
@Inject
private CollectionLoader<IdentityView> identityViewsDl;
@Subscribe("identityViewsTable.createUser")
public void onIdentityViewsTableCreateUser(Action.ActionPerformedEvent event) {
screenBuilders.editor(User.class, this)
.withScreenClass(UserEdit.class)
.newEntity(dataManager.create(User.class))
.withAfterCloseListener(userEditAfterScreenCloseEvent -> refresh())
.build()
.show();
}
@Subscribe("identityViewsTable.createGroup")
public void onIdentityViewsTableCreateGroup(Action.ActionPerformedEvent event) {
screenBuilders.editor(Group.class, this)
.withScreenClass(GroupEdit.class)
.newEntity(dataManager.create(Group.class))
.withAfterCloseListener(userEditAfterScreenCloseEvent -> refresh())
.build()
.show();
}
@SuppressWarnings("unchecked")
@Subscribe("identityViewsTable.edit")
public void onIdentityViewsTableEdit(Action.ActionPerformedEvent event) {
IdentityView identityView = identityViewsTable.getSingleSelected();
if (identityView == null)
return;
Identity identity;
Class editorClass;
if (identityView.getIdentityType().equals("demo_User")) {
identity = dataManager.load(User.class).id(identityView.getId()).one();
editorClass = UserEdit.class;
} else {
identity = dataManager.load(Group.class).id(identityView.getId()).one();
editorClass = GroupEdit.class;
}
screenBuilders.editor(Identity.class, this)
.withScreenClass(editorClass)
.editEntity(identity)
.withAfterCloseListener(afterScreenCloseEvent -> refresh())
.build()
.show();
}
@Subscribe("identityViewsTable.remove")
public void onIdentityViewsTableRemove(Action.ActionPerformedEvent event) {
IdentityView identityView = identityViewsTable.getSingleSelected();
if (identityView == null)
return;
if (identityView.getIdentityType().equals("demo_User")) {
dataManager.remove(Id.of(identityView.getId(), User.class));
} else {
dataManager.remove(Id.of(identityView.getId(), Group.class));
}
refresh();
}
private void refresh() {
identityViewsDl.load();
}
}
See the whole project attached:
demo.zip (86.9 KB)