treeeclipse-scout

Eclipse scout Tree table field


I am looking for component for tree representation of table field.

What I am looking for is table with columns but with option with collapsing of cell like tree.


Solution

  • There is no built in Tree Table in Scout, but it is possible to make misuse the Table to make it look like a tree table. I just proposed an implementation in this Gist.

    AbstractTreeTable is a table template that adds 2 columns in the table:

    AbstractTreeTable handles the collapsed state or not of each node row. It also decorates the first column (indentation and [+] &[-] marker on the nodes). It handle the row action (execRowAction(..)).

    If you use this in a table page, it is recommended to use a TablePageData and not Object[][]. If you use this in a table fields, it only works if the table field is using a bean based table data.

    My prototype could be improved:

    Examples:

    Cars TreeTable with 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");
          }
        }
      }
    }
    

    Files Tree Table with 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;
          }
        }
      }
    }
    

    Of course, this is only a workaround for the real problem: scout is missing a representation for tree-tables at model level. If there was something like that, it would be possible to use real tree table widgets in the different UIs.