public MasterDetailScreen() { addInitListener(this::initMasterDetailScreen); }
/** * Method invoked on the screen initialization. */ protected void initMasterDetailScreen(@SuppressWarnings("unused") InitEvent event) { initOkCancelActions(); initBrowseItemChangeListener(); initBrowseCreateAction(); initBrowseEditAction(); initShortcuts(); disableEditControls(); }
/** * Initializes OK/Cancel editor buttons. */ protected void initOkCancelActions() { ((BaseAction) getWindow().getActionNN("save")).withHandler(actionPerformedEvent -> saveChanges()); ((BaseAction) getWindow().getActionNN("cancel")).withHandler(actionPerformedEvent -> discardChanges()); }
/** * Method invoked when clicking the Cancel button, discards changes and disables controls for editing. */ public void discardChanges() { releaseLock(); getScreenData().getDataContext().evict(getEditContainer().getItem()); getEditContainer().setItem(null); T selectedItem = getBrowseContainer().getItemOrNull(); if (selectedItem != null) { View view = getEditContainer().getView(); boolean loadDynamicAttributes = getEditLoader().isLoadDynamicAttributes(); T reloadedItem = getBeanLocator().get(DataManager.class) .reload(selectedItem, view, null, loadDynamicAttributes); getBrowseContainer().setItem(reloadedItem); } disableEditControls(); }
ListComponent<T> table = getTable(); CreateAction createAction = (CreateAction) table.getActionNN("create"); createAction.withHandler(actionPerformedEvent -> { T entity = getBeanLocator().get(Metadata.class).create(getEntityClass()); T trackedEntity = getScreenData().getDataContext().merge(entity); DynamicAttributesGuiTools tools = getBeanLocator().get(DynamicAttributesGuiTools.NAME); String screenId = getScreenContext().getWindowInfo().getId(); InstanceContainer<T> editedEntityContainer = getEditContainer(); if (editedEntityContainer instanceof HasLoader) { if (((HasLoader) editedEntityContainer).getLoader() instanceof InstanceLoader) { instanceLoader = getEditLoader(); if (tools.screenContainsDynamicAttributes(editedEntityContainer.getView(), screenId)) { instanceLoader.setLoadDynamicAttributes(true); fireEvent(StandardEditor.InitEntityEvent.class, new StandardEditor.InitEntityEvent<>(this, trackedEntity)); getEditContainer().setItem(trackedEntity); refreshOptionsForLookupFields(); enableEditControls(true); table.setSelected(Collections.emptyList()); });
/** * Method invoked when clicking on the Ok button after editing an existing or creating a new record. */ public void saveChanges() { if (!editing) return; ValidationErrors validationErrors = validateEditorForm(); if (!validationErrors.isEmpty()) { ScreenValidation screenValidation = getBeanLocator().get(ScreenValidation.class); screenValidation.showValidationErrors(this, validationErrors); return; } getScreenData().getDataContext().commit(); T editedItem = getEditContainer().getItem(); if (creating) { getBrowseContainer().getMutableItems().add(0, editedItem); } else { getBrowseContainer().replaceItem(editedItem); } getTable().setSelected(editedItem); releaseLock(); disableEditControls(); }
/** * Adds an EditAction that enables controls for editing. */ protected void initBrowseEditAction() { ListComponent<T> table = getTable(); EditAction editAction = (EditAction) table.getActionNN("edit"); editAction.withHandler(actionPerformedEvent -> { if (table.getSelected().size() == 1) { if (lockIfNeeded(table.getSingleSelected())) { refreshOptionsForLookupFields(); enableEditControls(false); } } }); editAction.addEnabledRule(() -> table.getSelected().size() == 1 && getBeanLocator().get(Security.class).isEntityOpPermitted(getEntityClass(), EntityOp.UPDATE)); }
/** * Adds a listener that reloads the selected record and sets it to editCt. */ protected void initBrowseItemChangeListener() { getBrowseContainer().addItemChangeListener(e -> { if (e.getItem() != null) { InstanceLoader<T> editLoader = getEditLoader(); DynamicAttributesGuiTools tools = getBeanLocator().get(DynamicAttributesGuiTools.NAME); String screenId = getScreenContext().getWindowInfo().getId(); if (tools.screenContainsDynamicAttributes(getEditContainer().getView(), screenId)) { editLoader.setLoadDynamicAttributes(true); } editLoader.setEntityId(e.getItem().getId()); editLoader.load(); } else { if (!editing) { getEditContainer().setItem(null); } } }); }
/** * Initializes edit controls, depending on if they should be enabled or disabled. * @param enabled if true - enables edit controls and disables controls on the left side of the splitter * if false - vice versa */ protected void initEditComponents(boolean enabled) { TabSheet tabSheet = getTabSheet(); if (tabSheet != null) { ComponentsHelper.walkComponents(tabSheet, (component, name) -> { if (component instanceof FieldGroup) { ((FieldGroup) component).setEditable(enabled); } else if (component instanceof Table) { ((Table) component).getActions().forEach(action -> action.setEnabled(enabled)); } else if (!(component instanceof ComponentContainer)) { component.setEnabled(enabled); } }); } else { getForm().setEditable(enabled); } getActionsPane().setVisible(enabled); getLookupBox().setEnabled(!enabled); }
/** * Releases pessimistic lock if the entity was locked. */ public void releaseLock() { if (justLocked) { Entity entity = getEditContainer().getItemOrNull(); if (entity != null) { getBeanLocator().get(LockService.class).unlock(getLockName(), entity.getId().toString()); } } }
/** * Validates the cross-field rules if passed validation errors are empty. * * @param errors errors found during components validation */ protected void validateAdditionalRules(ValidationErrors errors) { // all previous validations return no errors if (isCrossFieldValidate() && errors.isEmpty()) { ScreenValidation screenValidation = getBeanLocator().get(ScreenValidation.NAME); ValidationErrors validationErrors = screenValidation.validateCrossFieldRules(this, getEditContainer().getItem()); errors.addAll(validationErrors); } }
/** * Pessimistic lock before start of editing, if it is configured for the entity. */ protected boolean lockIfNeeded(Entity entity) { LockService lockService = getBeanLocator().get(LockService.class); LockInfo lockInfo = lockService.lock(getLockName(), entity.getId().toString()); if (lockInfo == null) { justLocked = true; } else if (!(lockInfo instanceof LockNotSupported)) { Messages messages = getBeanLocator().get(Messages.class); DatatypeFormatter datatypeFormatter = getBeanLocator().get(DatatypeFormatter.class); Notifications notifications = getScreenContext().getNotifications(); notifications.create(NotificationType.HUMANIZED) .withCaption(messages.getMainMessage("entityLocked.msg")) .withDescription(String.format(messages.getMainMessage("entityLocked.desc"), lockInfo.getUser().getLogin(), datatypeFormatter.formatDateTime(lockInfo.getSince()))) .show(); return false; } return true; }
/** * Validates visible and enabled UI components. <br> * Can be overridden in subclasses. * * @return validation errors */ protected ValidationErrors validateUiComponents() { ScreenValidation screenValidation = getBeanLocator().get(ScreenValidation.NAME); return screenValidation.validateUiComponents(getForm().getComponents()); }
/** * Adds ESCAPE shortcut that invokes cancel() method. */ protected void initShortcuts() { ComponentContainer editBox = getEditBox(); if (editBox instanceof ShortcutNotifier) { ((ShortcutNotifier) editBox).addShortcutAction( new ShortcutAction(new KeyCombination(KeyCombination.Key.ESCAPE), shortcutTriggeredEvent -> discardChanges())); } }
/** * Returns the name of the pessimistic lock. */ protected String getLockName() { InstanceContainer<T> container = getEditContainer(); return getBeanLocator().get(ExtendedEntities.class) .getOriginalOrThisMetaClass(container.getEntityMetaClass()) .getName(); }
/** * Returns the loader of the edit form's data container. */ @SuppressWarnings("unchecked") protected InstanceLoader<T> getEditLoader() { DataLoader loader = ((HasLoader) getEditContainer()).getLoader(); if (loader == null) throw new IllegalStateException("Cannot find loader of editing container"); return (InstanceLoader<T>) loader; }
/** * Returns the entity meta-class. */ protected Class<T> getEntityClass() { return getBrowseContainer().getEntityMetaClass().getJavaClass(); }