Поле таблицы Eclipse scout Tree

Я ищу компонент для древовидного представления поля таблицы.

То, что я ищу, это таблица со столбцами, но с возможностью сворачивания ячеек, таких как дерево.


person Marko Zadravec    schedule 10.12.2014    source источник
comment
По умолчанию в модели Scout нет древовидной таблицы. В некоторых проектах удалось неправильно использовать виджет таблицы (для развертывания и свертывания строк, как в древовидной таблице). Я найду время, чтобы поделиться решением (потому что вопрос возникает снова и снова)   -  person Jmini    schedule 10.12.2014


Ответы (1)


В Scout нет встроенной таблицы дерева, но можно неправильно использовать таблицу, чтобы она выглядела как таблица дерева. Я только что предложил реализацию в этом Gist.

AbstractTreeTable — это шаблон таблицы, который добавляет в таблицу 2 столбца:

  • KeyColumn: первичный ключ для таблицы
  • ParentKeyColumn: ключ родительской строки или ноль, если строка находится в корне дерева.

AbstractTreeTable обрабатывает свернутое состояние каждой строки узла. Он также украшает первый столбец (отступ и маркер [+] &[-] на узлах). Он обрабатывает действие строки (execRowAction(..)).

Если вы используете это на странице таблицы, рекомендуется использовать TablePageData, а не Object[][]. Если вы используете это в полях таблицы, это работает только в том случае, если поле таблицы использует компонент . на основе табличных данных.

Мой прототип можно улучшить:

  • Нет поддержки сортировки (для одного столбца можно определить, как должна быть отсортирована строка: если у них разные родители -> сравнение двух родительских значений; если у них один и тот же родитель -> значение ячейки).
  • Я не проверял, как контент ведет себя, если вы пытаетесь применить к нему фильтр (также можно улучшить).
  • Необходимо проверить производительность с большим количеством строк.
  • execMethods не следует использовать на уровне шаблона

Примеры:

Cars TreeTable с Eclipse Scout

@Order(10.0)
@FormData(value = AbstractTableFieldBeanData.class, sdkCommand = SdkCommand.USE, defaultSubtypeSdkCommand = DefaultSubtypeSdkCommand.CREATE)
public class CarsTableField extends AbstractTableField<CarsTableField.Table> {

  @Override
  protected int getConfiguredGridH() {
    return 8;
  }

  @Override
  protected int getConfiguredGridW() {
    return 2;
  }

  @Override
  protected String getConfiguredLabel() {
    return TEXTS.get("Cars");
  }

  @Order(10.0)
  public class Table extends AbstractTreeTable {

    /**
     * @return the PriceFromColumn
     */
    public PriceFromColumn getPriceFromColumn() {
      return getColumnSet().getColumnByClass(PriceFromColumn.class);
    }

    /**
     * @return the NameColumn
     */
    public NameColumn getNameColumn() {
      return getColumnSet().getColumnByClass(NameColumn.class);
    }

    @Override
    protected boolean execIsNode(ITableRow row) {
      return getParentKeyColumn().getValue(row) == null;
    }

    @Override
    protected void execDecorateRow(ITableRow row) throws ProcessingException {
      if (execIsNode(row)) {
        row.setFont(FontSpec.parse("BOLD"));
      }
    }

    @Override
    public void importFromTableBeanData(AbstractTableFieldBeanData source) throws ProcessingException {
      super.importFromTableBeanData(source);

      toggleExpandedState(getRows());
    }

    @Order(10.0)
    public class NameColumn extends AbstractStringColumn {

      @Override
      protected String getConfiguredHeaderText() {
        return TEXTS.get("CarModel");
      }
    }

    @Order(20.0)
    public class PriceFromColumn extends AbstractIntegerColumn {

      @Override
      protected String getConfiguredHeaderText() {
        return TEXTS.get("PriceFrom");
      }
    }
  }
}

Таблица дерева файлов с Eclipse Scout

@Order(10.0)
@FormData(value = AbstractTableFieldBeanData.class, sdkCommand = SdkCommand.USE, defaultSubtypeSdkCommand = DefaultSubtypeSdkCommand.CREATE)
public class FilesTableField extends AbstractTableField<FilesTableField.Table> {

  @Override
  protected int getConfiguredGridH() {
    return 8;
  }

  @Override
  protected int getConfiguredGridW() {
    return 2;
  }

  @Override
  protected String getConfiguredLabel() {
    return TEXTS.get("Files");
  }

  @Order(10.0)
  public class Table extends AbstractTreeTable {

    @Override
    protected boolean execIsNode(ITableRow row) {
      Long type = getTypeColumn().getValue(row);
      return FileTypeCodeType.FolderCode.ID.equals(type);
    }

    @Override
    public void importFromTableBeanData(AbstractTableFieldBeanData source) throws ProcessingException {
      super.importFromTableBeanData(source);

      toggleExpandedState(getRows());
    }

    @Override
    protected void execDecorateRow(ITableRow row) throws ProcessingException {
      Long type = getTypeColumn().getValue(row);
      if (FileTypeCodeType.FolderCode.ID.equals(type)) {
        row.setIconId(Icons.FOLDER);
      }
      else if (FileTypeCodeType.FileCode.ID.equals(type)) {
        row.setIconId(Icons.DOCUMENT);
      }
      else if (FileTypeCodeType.EmailCode.ID.equals(type)) {
        row.setIconId(Icons.EMAIL);
      }
      else if (FileTypeCodeType.VCardCode.ID.equals(type)) {
        row.setIconId(Icons.VCARD);
      }
    }

    /**
     * @return the TypeColumn
     */
    public TypeColumn getTypeColumn() {
      return getColumnSet().getColumnByClass(TypeColumn.class);
    }

    /**
     * @return the ModifiedDateColumn
     */
    public ModifiedDateColumn getModifiedDateColumn() {
      return getColumnSet().getColumnByClass(ModifiedDateColumn.class);
    }

    /**
     * @return the NameColumn
     */
    public NameColumn getNameColumn() {
      return getColumnSet().getColumnByClass(NameColumn.class);
    }

    @Order(20.0)
    public class NameColumn extends AbstractStringColumn {

      @Override
      protected String getConfiguredHeaderText() {
        return TEXTS.get("Name");
      }

      @Override
      protected int getConfiguredWidth() {
        return 400;
      }
    }

    @Order(30.0)
    public class ModifiedDateColumn extends AbstractDateColumn {

      @Override
      protected String getConfiguredFormat() {
        return "dd.MM.yyyy hh:mm";
      }

      @Override
      protected String getConfiguredHeaderText() {
        return TEXTS.get("DateModified");
      }

      @Override
      protected int getConfiguredWidth() {
        return 200;
      }
    }

    @Order(40.0)
    public class TypeColumn extends AbstractSmartColumn<Long> {

      @Override
      protected Class<? extends ICodeType<?, Long>> getConfiguredCodeType() {
        return FileTypeCodeType.class;
      }

      @Override
      protected String getConfiguredHeaderText() {
        return TEXTS.get("Type");
      }

      @Override
      protected int getConfiguredWidth() {
        return 200;
      }
    }
  }
}

Конечно, это всего лишь обходной путь для реальной проблемы: в scout отсутствует представление для древовидных таблиц на уровне модели. Если бы было что-то подобное, можно было бы использовать виджеты таблицы реального дерева в разных пользовательских интерфейсах.

person Jmini    schedule 18.12.2014
comment
Очень важный вопрос. Я следую вашему примеру и скачиваю шаблоны, но теперь у меня есть одна проблема. Данные формы для AbstractTreeTable не генерируются, а в поле таблицы все остальные столбцы находятся внутри, кроме столбцов из таблицы дерева. Как это исправить? - person Marko Zadravec; 06.02.2015
comment
Это работает только в том случае, если поле таблицы использует табличные данные на основе компонента, потому что массив основанные на табличных данных не поддерживают наследование таблиц. - person Jmini; 06.02.2015
comment
Я не совсем понимаю это. Я думал, что если я использую данные формы, это данные таблицы на основе bean-компонентов. В моем поле таблицы у меня есть следующее: @FormData (значение = AbstractPurchasePriceHistoryTableData.class, sdkCommand = FormData.SdkCommand.USE, defaultSubtypeSdkCommand = FormData.DefaultSubtypeSdkCommand.CREATE), а в таблице дерева у меня есть @FormData (значение = AbstractTreeTableData.class, sdkCommand = FormData.SdkCommand.USE, defaultSubtypeSdkCommand = FormData.DefaultSubtypeSdkCommand.CREATE), но AbstractTreeTableData.class всегда пуст. - person Marko Zadravec; 06.02.2015
comment
Аннотация @FormData всегда предназначена для класса TableField (можно определить что-то на каждом уровне иерархии). Первый уровень — AbstractTableField (в скаутской банке). TableField в вашей форме напрямую расширяет этот класс, или у вас есть другой абстрактный класс (он же шаблон) в графе наследования классов. Нет необходимости иметь @FormData в классе Table; SDK не читает его. В зависимости от вашего случая параметры аннотации не совпадают. Несколько примеров приведены на странице вики. Не стесняйтесь открыть другой вопрос, чтобы обсудить это подробно. - person Jmini; 06.02.2015
comment
Я задаю другой вопрос stackoverflow.com/questions/28362697/ - person Marko Zadravec; 06.02.2015