Trying to get a Tree to refresh

I’m developing a proof of concept in Vaadin at the moment and am running into a fundamental barrier - I can’t seem to figure out how to get certain components to update. In my case I have a filter form and a tree that displays a list of locations. When I enter filter information and click a submit button, I have the button do the following with the tree:


    treeContainer.removeAllContainerFilters()
    treeContainer.addContainerFilter(filterByLocation)

I’ve checked to make sure that my filter form is doing what it is supposed to and that the filterByLocation is indeed producing the values that I would expect. The missing piece is figuring out how to trigger the tree to redraw itself. I know this must be simple - does anyone have any suggestions?

Let me know and best regards,

Steve

At least
this tree filtering example
seems to work OK.

Marko,
First, thanks for the help.

I’ve been trying to boil my code down to the bare essentials in order to get this to work. What I have is simply an application that shows a list of departments for a specific employer, under which are nodes for each employee in that department, under which are nodes for each employee’s dependents. I also have a filter button that filters a specific department. This is working to a degree - the only top level node that is shown is the department, but none of its child nodes appear. Here is the code that I’m using (it is Scala, but reads pretty similarly to Java at the moment).

For the tree’s container:



  private def employerDepartments: HierarchicalContainer = {
    val container = new HierarchicalContainer
    container.addContainerProperty("Department", classOf[Department]
, null)
    container.addContainerProperty("Employee", classOf[Employee]
, null)
    container.addContainerProperty("Person", classOf[Person]
, null)
    container.addContainerProperty("Name", classOf[String]
, "")
    val departments: List[Department]
 = Department.departments
    for (department <- departments) {
      val departmentId: AnyRef = addDepartment(container, department)
      for (employee <- department.getEmployees) {
        val employeeId: AnyRef = addEmployee(container, employee, departmentId)
        for (dependent <- employee.getDependents) {
          addDependent(container, dependent, employeeId)
        }
      }
    }
    container
  }

  private def addDependent(container: HierarchicalContainer, dependent: Person, employeeId: AnyRef): AnyRef = {
    val id: AnyRef = container.addItem()
    container.getContainerProperty(id, "Person").setValue(dependent)
    container.getContainerProperty(id, "Name").setValue(dependent.getName)
    container.setParent(id, employeeId)
    container.setChildrenAllowed(id, false)
    id
  }

  private def addEmployee(container: HierarchicalContainer, employee: Employee, departmentId: AnyRef): AnyRef = {
    val id: AnyRef = container.addItem()
    container.getContainerProperty(id, "Employee").setValue(employee)
    container.getContainerProperty(id, "Name").setValue(employee.getName)
    container.setParent(id, departmentId)
    container.setChildrenAllowed(departmentId, true)
    id
  }

  private def addDepartment(container: HierarchicalContainer, department: Department): AnyRef = {
    val id: AnyRef = container.addItem()
    container.getContainerProperty(id, "Department").setValue(department)
    container.getContainerProperty(id, "Name").setValue(department.getName)
    id
  }

For the filter:


class DepartmentFilter(departmentName: String) extends Filter {
    def passesFilter(itemId: AnyRef, item: Item) = {
      val p: Property = item.getItemProperty("Department");
      if(p != null && p.getValue != null) {
        p.getValue match {
          case department: Department =>
            val result = department.name == departmentName
            result
          case x =>
            true
        }
      }
      else
        false
    }
  
    def appliesToProperty(propertyId: AnyRef) = true
}

Any light that could be shed on this would be greatly appreciated.

I figured out that to get a tree with only the nodes I want, the best approach is to forego the filter altogether and make filtering an implicit part of the data source construction. So instead of this for building my tree of departments/employees/dependents:


  private def employerDepartments: HierarchicalContainer = {
    val container = new HierarchicalContainer
    container.addContainerProperty("Department", classOf[Department]
, null)
    container.addContainerProperty("Employee", classOf[Employee]
, null)
    container.addContainerProperty("Person", classOf[Person]
, null)
    container.addContainerProperty("Name", classOf[String]
, "")
    val departments: List[Department]
 = Department.departments
    for (department <- departments) {
      val departmentId: AnyRef = addDepartment(container, department)
      for (employee <- department.getEmployees) {
        val employeeId: AnyRef = addEmployee(container, employee, departmentId)
        for (dependent <- employee.getDependents) {
          addDependent(container, dependent, employeeId)
        }
      }
    }
    container
  }

I now do the following:


  private def employerDepartments(include: List[String]
 = Department.departments.map(d => d.name)): HierarchicalContainer = {
    val container = new HierarchicalContainer
    container.addContainerProperty("Department", classOf[Department]
, null)
    container.addContainerProperty("Employee", classOf[Employee]
, null)
    container.addContainerProperty("Person", classOf[Person]
, null)
    container.addContainerProperty("Name", classOf[String]
, "")
    val departments: List[Department]
 = Department.departments.filter(d => include.contains(d.name))
    for (department <- departments) {
      val departmentId: AnyRef = addDepartment(container, department)
      for (employee <- department.getEmployees) {
        val employeeId: AnyRef = addEmployee(container, employee, departmentId)
        for (dependent <- employee.getDependents) {
          addDependent(container, dependent, employeeId)
        }
      }
    }
    container
  }

This seems to work like a charm, and I imagine that it is also more performant as well.