Я ищу компонент для древовидного представления поля таблицы.
То, что я ищу, это таблица со столбцами, но с возможностью сворачивания ячеек, таких как дерево.
Я ищу компонент для древовидного представления поля таблицы.
То, что я ищу, это таблица со столбцами, но с возможностью сворачивания ячеек, таких как дерево.
В Scout нет встроенной таблицы дерева, но можно неправильно использовать таблицу, чтобы она выглядела как таблица дерева. Я только что предложил реализацию в этом Gist.
AbstractTreeTable
— это шаблон таблицы, который добавляет в таблицу 2 столбца:
KeyColumn
: первичный ключ для таблицыParentKeyColumn
: ключ родительской строки или ноль, если строка находится в корне дерева.AbstractTreeTable
обрабатывает свернутое состояние каждой строки узла. Он также украшает первый столбец (отступ и маркер [+]
&[-]
на узлах). Он обрабатывает действие строки (execRowAction(..)
).
Если вы используете это на странице таблицы, рекомендуется использовать TablePageData, а не Object[][]
. Если вы используете это в полях таблицы, это работает только в том случае, если поле таблицы использует компонент . на основе табличных данных.
Мой прототип можно улучшить:
@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");
}
}
}
}
@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 отсутствует представление для древовидных таблиц на уровне модели. Если бы было что-то подобное, можно было бы использовать виджеты таблицы реального дерева в разных пользовательских интерфейсах.
@FormData
всегда предназначена для класса TableField
(можно определить что-то на каждом уровне иерархии). Первый уровень — AbstractTableField
(в скаутской банке). TableField
в вашей форме напрямую расширяет этот класс, или у вас есть другой абстрактный класс (он же шаблон) в графе наследования классов. Нет необходимости иметь @FormData
в классе Table
; SDK не читает его. В зависимости от вашего случая параметры аннотации не совпадают. Несколько примеров приведены на странице вики. Не стесняйтесь открыть другой вопрос, чтобы обсудить это подробно.
- person Jmini; 06.02.2015