@Override
    protected void onBind() {
        super.onBind();

        registerHandler(autoRefreshButton.addClickHandler(event -> {
            if ((event.getNativeButton() & NativeEvent.BUTTON_LEFT) != 0) {
                autoRefresh = !autoRefresh;
                if (autoRefresh) {
                    autoRefreshButton.setTitle(AUTO_REFRESH_ON_TITLE);
                    internalRefresh();
                } else {
                    autoRefreshButton.setTitle(AUTO_REFRESH_OFF_TITLE);
                }
            }
        }));

        // NodeLisPresenter may change a node
        registerHandler(getEventBus().addHandler(
                NodeChangeEvent.getType(), event -> {
                    // We are likely showing all jobs so just refresh
                    refreshNodeStates();
                }));

        // JobListPresenter may change a job
        registerHandler(getEventBus().addHandler(
                JobChangeEvent.getType(), event -> {
                    GWT.log("Handling JobChangeEvent " + event);
                    final String currentJobName = getJobNameCriteria();
                    final String affectedJobName = NullSafe.get(event, JobChangeEvent::getJob, Job::getName);
                    if (currentJobName != null && Objects.equals(currentJobName, affectedJobName)) {
                        internalRefresh();
                    }
                }));

        // NodeJobListPresenter may change a jobNode
        registerHandler(getEventBus().addHandler(
                JobNodeChangeEvent.getType(), event -> {
//                    GWT.log(JobNodeListPresenter.this.getClass().getSimpleName()
//                            + " - jobNodes changed: " + event.getJobNodes().size());
                    if (!Objects.equals(event.getSource().getClass(), JobNodeListPresenter.this.getClass())) {
                        final Set<String> affectedJobNames = event.getJobNodes()
                                .stream()
                                .map(JobNode::getJobName)
                                .collect(Collectors.toSet());
                        final String currentJobName = getJobNameCriteria();
                        if (currentJobName != null && affectedJobNames.contains(currentJobName)) {
                            internalRefresh();
                        }
                    }
                }));

        registerHandler(dataGrid.addColumnSortHandler(event -> internalRefresh()));
    }
Bottom pane of JobPresenter (Jobs tab). Lists jobNodes for a single parent job.
stroom-core-client/src/main/java/stroom/job/client/presenter/JobNodeListPresenter.java