4.5.2.1. Displaying Images in a Table Column

To amplify the previous task, let’s add pictures to the table as employees' icons on the Employee browse screen.

The pictures can be displayed in a separate column or inside any existing column. In both cases the Table.ColumnGenerator interface is used.

Below is a fragment of the Employee browse screen XML descriptor:

<groupTable id="employeesTable"
            width="100%">
    <actions>
        <action id="create"/>
        <action id="edit"/>
        <action id="remove"/>
    </actions>
    <columns>
        <column id="name"/>
    </columns>
    <rows datasource="employeesDs"/>
    <rowsCount/>
    <buttonsPanel id="buttonsPanel"
                  alwaysVisible="true">
        <button id="createBtn"
                action="employeesTable.create"/>
        <button id="editBtn"
                action="employeesTable.edit"/>
        <button id="removeBtn"
                action="employeesTable.remove"/>
    </buttonsPanel>
</groupTable>

To display pictures inline with an employee’s name in the name column, let’s change the standard representation of data in this column. We will use the HBoxLayout container and place the Image component into it:

import com.haulmont.cuba.core.entity.FileDescriptor;
import com.haulmont.cuba.gui.components.*;
import com.company.employeeimages.entity.Employee;
import com.haulmont.cuba.gui.xml.layout.ComponentsFactory;

import javax.inject.Inject;
import java.util.Map;

import static com.haulmont.cuba.gui.components.Image.*;

public class EmployeeBrowse extends AbstractLookup {

    @Inject
    private ComponentsFactory componentsFactory;

    @Inject
    private GroupTable<Employee> employeesTable;

    @Override
    public void init(Map<String, Object> params) {

        employeesTable.addGeneratedColumn("name", entity -> {
            Image image = componentsFactory.createComponent(Image.class);
            image.setScaleMode(ScaleMode.CONTAIN);
            image.setHeight("40");
            image.setWidth("40");

            FileDescriptor userImageFile = entity.getImageFile();
            image.setSource(FileDescriptorResource.class).setFileDescriptor(userImageFile);

            Label userLogin = componentsFactory.createComponent(Label.class);
            userLogin.setValue(entity.getName());
            userLogin.setAlignment(Alignment.MIDDLE_LEFT);

            HBoxLayout hBox = componentsFactory.createComponent(HBoxLayout.class);
            hBox.setSpacing(true);
            hBox.add(image);
            hBox.add(userLogin);

            return hBox;
        });
    }
}
  • The init() method invokes the addGeneratedColumn() method that takes two parameters: an identifier of the column and an implementation of the Table.ColumnGenerator interface. The latter is used to define the custom representation of data in the name column.

  • Inside this method we create an Image component using the ComponentsFactory interface. We set the scale mode of the component (CONTAIN) and its size parameters.

  • Then we get the FileDescriptor instance with the picture stored in the File Storage. The link to this picture is stored in the imageFile attribute of the Employee entity. The FileDescriptorImageResource resource type is used to set the source for the Image component.

  • We will display the name attribute in the Label component alongside the picture.

  • We will wrap both Image and Label components into the HBoxLayout container, and make the addGeneratedColumn() method return this container as the new table cell layout.

image recipe

You can also use a more declarative approach with the generator XML attribute.