Cancelling current entity edit upon selecting a new item in browse screen DataGrid

I’m using the MasterDetailScreen for an entity and would like to change the entity shown in the editor detail screen when selecting a new item from the DataGrid on the browse side. Currently, when an entity is being edited you cannot select a new entity from the DataGrid until the cancel button is pressed. Ideally, I’d like to be able to automatically cancel a current edit when selecting a new Entity from the browse DataGrid. I’ve attempted to accomplish this by experimenting with enabling and disabling edit controls in a method, onTableSelection(), but without any success.

@Subscribe("table")
    public void onTableSelection(DataGrid.SelectionEvent<DataSource> event) {
        if (this.editing) {
            disableEditControls();
        }

        Entity selected = table.getSingleSelected();
        if (selected != null) {
            this.initEditComponents(true);
        }
    }

Any help would be much appreciated.

Was able to achieve visually what I was looking for with the below code in my java screen controller class.

@ParametersAreNonnullByDefault
    public void initMasterDetailScreen(InitEvent event) {
        super.initMasterDetailScreen(event);

        table.addSelectionListener(selectionEvent -> {
            discardChanges();
            if (DataSourceManager.this.editing) {
                disableEditControls();
                DataSourceManager.this.editing = false;
            }

            DataSource selected = table.getSingleSelected();
            if (selected != null) {
                initEditComponentsWithBrowseFunctionality(true);
                DataSourceManager.this.editing = true;
            }
        });
    }

    protected void initEditComponentsWithBrowseFunctionality(boolean enabled) {
        TabSheet tabSheet = getTabSheet();
        if (tabSheet != null) {
            ComponentsHelper.walkComponents(tabSheet, (component, name) -> {
                if (component instanceof Form) {
                    ((Form) component).setEditable(enabled);
                } else if (component instanceof Table) {
                    ((Table<DataSource>) component).getActions().forEach(action -> action.setEnabled(enabled));
                } else if (!(component instanceof ComponentContainer)) {
                    component.setEnabled(enabled);
                }
            });
        }
        getForm().setEditable(enabled);
        getActionsPane().setVisible(enabled);
    }

Unfortunately, it caused some bugs with the Create action functionality. Attempting to create a new entity, in this case DataSource, and then selecting an item from the browse list and saving instead creates a new item in the DataGrid that is always selected with its duplicate item. Signing in and out clears the duplicate item.

Hello!

In the table selection listener, you can set this.creating flag to false. It affects whether the item will be added or replaced in the items collection. Also, you have to handle the InitEntityEvent because CreateAction sends selection event with empty items, and listener code may prevent creating new item.

public boolean isInitEvent = false;

table.addSelectionListener(selectionEvent -> {
    discardChanges();
    if (DataSourceManager.this.editing) {
        disableEditControls();
        DataSourceManager.this.editing = false;
    }

    DataSource selected = table.getSingleSelected();
    if (selected != null) {
        initEditComponentsWithBrowseFunctionality(true);
        DataSourceManager.this.editing = true;
    }
});

@Subscribe
public void onInitEntity(InitEntityEvent<Project> event) {
    isInitEvent = true;
}

@ParametersAreNonnullByDefault
public void initMasterDetailScreen(InitEvent event) {
    super.initMasterDetailScreen(event);

    table.addSelectionListener(selectionEvent -> {
        if (table.getSingleSelected() == null && isInitEvent) {
            isInitEvent = false;
            return;
        }

        discardChanges();
        
        this.creating = false;
        
        if (this.editing) {
            disableEditControls();
            this.editing = false;
        }
        Project selected = table.getSingleSelected();
        if (selected != null) {
            initEditComponentsWithBrowseFunctionality(true);
            this.editing = true;
        }
    });
}

Also, take a look at code example, it has a little less code:

Code example
public class ProjectMaster extends MasterDetailScreen<Project> {
    
    @Inject
    private DataGrid<Project> table;

    public boolean isInitEvent = false;

    @Subscribe("table")
    public void onTableSelection(DataGrid.SelectionEvent<Project> event) {
        if (table.getSingleSelected() == null && isInitEvent) {
            isInitEvent = false;
            return;
        }

        discardChanges();

        if (editing) {
            disableEditControls();
        }

        Project selected = table.getSingleSelected();
        if (selected != null) {
            enableEditControls(false);
        }
    }

    @Override
    protected void initEditComponents(boolean enabled) {
        super.initEditComponents(enabled);

        getLookupBox().setEnabled(true);
    }

    @Subscribe
    public void onInitEntity(InitEntityEvent<Project> event) {
        isInitEvent = true;
    }
}

Thank you, the provided code fixed the bugs I was experiencing in my version!