private void initTableColumns() {
        // Select Column
        final Column<TaskProgress, TickBoxState> checkBoxColumn = new Column<TaskProgress, TickBoxState>(
                TickBoxCell.create(false, false)) {
            @Override
            public TickBoxState getValue(final TaskProgress taskProgress) {
                if (TaskProgressUtil.DEAD_TASK_NAME.equals(taskProgress.getTaskName())) {
                    // Dead tasks cannot be deleted so don't show a checkbox
                    // They are only there to show that an orphaned child task was a child of something
                    return null;
                } else {
                    return TickBoxState.fromBoolean(selectedTaskProgress.contains(taskProgress));
                }
            }
        };

        dataGrid.addColumn(checkBoxColumn, "", ColumnSizeConstants.CHECKBOX_COL);

        // Expander column.
        expanderColumn = new Column<TaskProgress, Expander>(new ExpanderCell()) {
            @Override
            public Expander getValue(final TaskProgress row) {
                return buildExpander(row);
            }
        };
        dataGrid.addColumn(expanderColumn, "");

        expanderColumn.setFieldUpdater((index, row, value) -> {
            treeAction.setRowExpanded(row, !value.isExpanded());
            // As we get data async from all nodes we can't be sure when we have finished so
            // need to clear the expandAllRequestState prior to fetching
            treeAction.resetExpandAllRequestState();
            updateButtonStates();
            internalRefresh();
        });

        final InfoColumn<TaskProgress> furtherInfoColumn = new InfoColumn<TaskProgress>() {
            @Override
            protected void showInfo(final TaskProgress row, final PopupPosition popupPosition) {
                final SafeHtml tooltipHtml = buildTooltipHtml(row);
                tooltipPresenter.show(tooltipHtml, popupPosition);
            }
        };
        dataGrid.addColumn(furtherInfoColumn, "<br/>", ColumnSizeConstants.ICON_COL);

        // Add Handlers
        checkBoxColumn.setFieldUpdater((index, object, value) -> {
            if (value.toBoolean()) {
                selectedTaskProgress.add(object);
            } else {
                // De-selecting one and currently matching all ?
                selectedTaskProgress.remove(object);
            }
//            setButtonsEnabled();
        });

        // Node.
        dataGrid.addResizableColumn(
                DataGridUtil.htmlColumnBuilder(getColouredCellFunc(this::getNodeName))
                        .withSorting(FindTaskProgressCriteria.FIELD_NODE)
                        .build(),
                FindTaskProgressCriteria.FIELD_NODE,
                150);

        // Name.
        dataGrid.addResizableColumn(
                DataGridUtil.htmlColumnBuilder(getWrapableColouredCellFunc(TaskProgress::getTaskName))
                        .withSorting(FindTaskProgressCriteria.FIELD_NAME)
                        .build(),
                FindTaskProgressCriteria.FIELD_NAME,
                250);

        // User.
        dataGrid.addResizableColumn(
                DataGridUtil.userRefColumnBuilder(
                                TaskProgress::getUserRef, getEventBus(), securityContext, DisplayType.AUTO)
                        .enabledWhen(taskProgress -> NullSafe
                                .getOrElse(taskProgress, TaskProgress::getUserRef, UserRef::isEnabled, false))
                        .withSorting(FindTaskProgressCriteria.FIELD_USER)
                        .build(),
                FindTaskProgressCriteria.FIELD_USER,
                100);

        // Submit Time.
        dataGrid.addResizableColumn(
                DataGridUtil.htmlColumnBuilder(getColouredCellFunc(taskProgress ->
                                dateTimeFormatter.format(taskProgress.getSubmitTimeMs())))
                        .withSorting(FindTaskProgressCriteria.FIELD_SUBMIT_TIME)
                        .build(),
                FindTaskProgressCriteria.FIELD_SUBMIT_TIME,
                ColumnSizeConstants.DATE_COL);

        // Age.
        dataGrid.addResizableColumn(
                DataGridUtil.htmlColumnBuilder(getColouredCellFunc(taskProgress ->
                                ModelStringUtil.formatDurationString(taskProgress.getAgeMs())))
                        .withSorting(FindTaskProgressCriteria.FIELD_AGE)
                        .build(),
                FindTaskProgressCriteria.FIELD_AGE,
                ColumnSizeConstants.SMALL_COL);

        // Info
        dataGrid.addAutoResizableColumn(
                DataGridUtil.htmlColumnBuilder(getWrapableColouredCellFunc(TaskProgress::getTaskInfo))
                        .withSorting(FindTaskProgressCriteria.FIELD_INFO)
                        .build(),
                FindTaskProgressCriteria.FIELD_INFO,
                200);

        dataGrid.addEndColumn(new EndColumn<>());
    }
Add the columns to the table.
stroom-core-client/src/main/java/stroom/task/client/presenter/TaskManagerListPresenter.java