Как при создании Table в контроллере экрана распределить столбцы по моему усмотрению

Здравствуйте.
Jmix version: 1.5.5.

Я создаю таблицу и добавляю контейнер в зависимости от условия, но в итоге названия колонок создаются в своем каком-то порядке (например age, sex, name, weight) а мне нужно (name, age, sex, weight) как отсортировать колонки по своему усмотрению?

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<fragment xmlns="http://jmix.io/schema/ui/fragment">
    <data readOnly="true">
        <collection id="dogDc"
                    class="com.consyst.isopas.entity.Dog">
            <loader id="dogDl">
                <query>
                    <![CDATA[select i from Dog i]]>
                </query>
            </loader>
        </collection>
        <collection id="catDc"
                    class="com.consyst.isopas.entity.Cat">
            <loader id="catDl">
                <query>
                    <![CDATA[select i from Cat i]]>
                </query>
            </loader>
        </collection>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
    </facets>
    <layout>
        <vbox id="tables"/>
    </layout>
</fragment>
@UiController("Animal")
@UiDescriptor("Animal.xml")
public class Animal extends ScreenFragment {

    @Autowired
    private UiComponents uiComponents;

    @Autowired
    private CollectionContainer<IK8tKlnAes> dogDc;
    @Autowired
    private CollectionContainer<IK8tKurAes> catDc;
    @Autowired
    private VBoxLayout tables;

    @Subscribe
    public void onInit(final InitEvent event) {
        createTable();
    }


    private void createTable() {
        Table table = uiComponents.create(Table.class);

        if (currentStation.getShortName().equals("Собака")) {
            table.setItems(new ContainerTableItems<>(dogDc));
        }else if (currentStation.getShortName().equals("Кошка")) {
            table.setItems(new ContainerTableItems<>(catDc));
        }

        table.setWidthFull();
        tables.add(table);
    }
    
}

Добрый день,

Если вы програмно создаете таблицу можно просто удалить сгенерированные столбцы (все) после того, как вы проставили к таблице контейнер, после чего в в ручную добавить столбцы


    public void createTable() {
       Table table = uiComponents.create(Table.class);

        if (currentStation.getShortName().equals("Собака")) {
            table.setItems(new ContainerTableItems<>(dogDc));
            removeAllColumns(table);
            addColumns(table, IK8tKlnAes, "name", "sex", "etc")
        }else if (currentStation.getShortName().equals("Кошка")) {
            table.setItems(new ContainerTableItems<>(catDc));
            removeAllColumns(table);
            addColumns(table, IK8tKlnAes, "name", "sex", "etc")
        }
    }

    public <T> void  removeAllColumns(Table<T> table) {
        table.getColumns().forEach(table::removeColumn);
    }

    public <T> void addColumns(Table<T> table, Class<T> cls, String... propertyNames) {
        MetaClass metaClass = metadata.getClass(cls);
        for (String propertyName : propertyNames) {
            addColumn(table, metaClass, propertyName);
        }
    }

    public <T> void addColumn(Table<T> table, MetaClass metaClass, String propertyName) {
        table.addColumn(Objects.requireNonNull(metaClass.findProperty(propertyName)));
    }

Однако, как я вижу у вас схожие данные - потому настоятельно рекомендую вместо этого использовать маппинг в 1 общий тип и применять к данным просто сортировку, тогда не придется динамически создавать таблицу с разными колонками

То есть

у вас есть собака и кошка и они могуть иметь DTO (JmixEntity), вот именно этот дата контейнер вы заполняете и обновляете в зависимости от условий, а даблица тянет данные именно из сортированного нового контейнера

С уважением,
Дмитрий

Спасибо. А если у меня есть схожие данные и есть те, которые различаются?

при вызове этого метода

 public <T> void  removeAllColumns(Table<T> table) {
        table.getColumns().forEach(table::removeColumn);
    }

появляется ошибка java.util.ConcurrentModificationException

Лучше отображать 2 разных таблицы

Извиняюсь, привык к Jmix 2, там можно так

public void onBeforeShow(final BeforeShowEvent event) {
        addColumns(usersTable, User.class, "id");
        List.of("username", "firstName", "lastName", "email", "timeZoneId", "active")
                        .forEach(e -> usersTable.removeColumn(usersTable.getColumn(e)));
        addColumns(usersTable, User.class, "username", "version");
    }

    public <T> void  removeAllColumns(Table<T> table) {
        table.getColumns().forEach(table::removeColumn);
    }

    public <T> void addColumns(Table<T> table, Class<T> cls, String... propertyNames) {
        MetaClass metaClass = metadata.getClass(cls);
        for (String propertyName : propertyNames) {
            addColumn(table, metaClass, propertyName);
        }
    }

    public <T> void addColumn(Table<T> table, MetaClass metaClass, String propertyName) {
        table.addColumn(Objects.requireNonNull(metaClass.getPropertyPath(propertyName)));
    }

Обновленный пример, рабочий

  1. надо чтобы хотя бы 1 свойство оставалось в таблице (потом можете удалить)
  2. там не MetaProperty, a MetaPropertyPath, потому addColumn чуть другой

как видите, код с изменением таблицы выглядит немного неуместным. Потому я и сказал про data-based подход при работе с таблицами когда у нас все в общем представлении и мы уже его сортируем. Либо просто имеем 2 разные таблицы