// TODO try to use a binding
 private void updateSkills() {
   skillsTableView.getItems().clear();
   Official selectedMember = officialsFilteredTableView.getSelectionModel().getSelectedItem();
   if (selectedMember != null) {
     skillsTableView.getItems().addAll(selectedMember.getSkillLevels().values());
     Collections.sort(
         skillsTableView.getItems(),
         new Comparator<SkillLevel>() {
           @Override
           public int compare(SkillLevel arg0, SkillLevel arg1) {
             return arg0.getSkill().getName().compareTo(arg1.getSkill().getName());
           }
         });
   }
 }
  private void initializeFilteredPersonnelTableView() {
    personnelNameColumn.setCellValueFactory(new PropertyValueFactory<Official, String>("name"));
    personnelRankColumn.setCellValueFactory(
        new Callback<TableColumn.CellDataFeatures<Official, String>, ObservableValue<String>>() {
          @Override
          public ObservableValue<String> call(CellDataFeatures<Official, String> arg0) {
            final Official official = arg0.getValue();
            final StringExpression concat =
                Bindings.selectString(official.rankProperty(), "designation");
            return concat;
          }
        });
    Bindings.bindContent(officialsFilteredTableView.getItems(), officialFilteredList);
    gameData
        .getOfficials()
        .addListener(
            new ListChangeListener<Official>() {
              @Override
              public void onChanged(Change<? extends Official> arg0) {
                updateOfficialFiltersResult();
              }
            });

    // TODO initialize assignOfficialMenuItem to be sure that it's not
    // enable if not correct values are selected
  }
 private void deleteSelectedSkillFilter() {
   SkillFilter selectedItem = skillFiltersTableView.getSelectionModel().getSelectedItem();
   if (selectedItem != null) {
     skillFiltersTableView.getItems().remove(selectedItem);
     skillFiltersTableView.getSelectionModel().clearSelection();
     updateOfficialFiltersResult();
   }
 }
 public void addSkillFilter(ActionEvent event) {
   final Skill skill = skillFilterComboBox.getSelectionModel().getSelectedItem();
   SkillFilter skillFilter = new SkillFilter();
   skillFilter.setSkill(skill);
   String minValueText = skillFilterMinValueComponent.getText();
   skillFilter.setMinValue(
       (minValueText == null || minValueText.isEmpty()) ? null : Integer.parseInt(minValueText));
   String maxValueText = skillFilterMaxValueComponent.getText();
   skillFilter.setMaxValue(
       (maxValueText == null || maxValueText.isEmpty()) ? null : Integer.parseInt(maxValueText));
   skillFiltersTableView.getItems().add(skillFilter);
   // We don't need to update #skillFiltersMatcher because of the biding
   // betwen skillFiltersMatcher' matchers and the items of
   // skillFiltersTableView
   updateOfficialFiltersResult();
 }
  private void initializeSkillFilterTab() {
    skillFilterComboBox.getItems().addAll(skills);
    PropertyListCellFactory<Skill> propertyListCellFactory =
        new PropertyListCellFactory<>("name", null);
    skillFilterComboBox.setButtonCell(
        new ListCell<Skill>() {
          @Override
          protected void updateItem(Skill arg0, boolean arg1) {
            super.updateItem(arg0, arg1);
            if (arg1 || arg0 == null) {
              this.setText(null);
            } else {
              this.setText(arg0.getName());
            }
          }
        });
    skillFilterComboBox.setCellFactory(propertyListCellFactory);
    skillFiltersNameColumn.setCellValueFactory(
        new Callback<CellDataFeatures<SkillFilter, String>, ObservableValue<String>>() {
          @Override
          public ObservableValue<String> call(CellDataFeatures<SkillFilter, String> arg0) {
            return Bindings.selectString(arg0.getValue().skillProperty(), "name");
          }
        });

    skillFilterMinValueColumn.setCellValueFactory(
        new PropertyValueFactory<SkillFilter, Integer>("minValue"));
    skillFilterMaxValueColumn.setCellValueFactory(
        new PropertyValueFactory<SkillFilter, Integer>("maxValue"));
    skillFiltersTableView
        .getItems()
        .addListener(
            new ListChangeListener<SkillFilter>() {
              @Override
              public void onChanged(Change<? extends SkillFilter> arg0) {
                while (arg0.next()) {
                  for (SkillFilter skillFilter : arg0.getAddedSubList()) {
                    final Skill skill = skillFilter.getSkill();
                    TableColumn<Official, Number> skillColumn = new TableColumn<>(skill.getName());
                    skillColumn.setCellValueFactory(
                        new Callback<
                            CellDataFeatures<Official, Number>, ObservableValue<Number>>() {
                          @Override
                          public ObservableValue<Number> call(
                              CellDataFeatures<Official, Number> arg0) {
                            Official official = arg0.getValue();
                            IntegerBinding selectInteger =
                                Bindings.selectInteger(
                                    official.skillLevelsProperty().valueAt(skill), "level");
                            selectInteger.addListener(
                                new ChangeListener<Number>() {
                                  @Override
                                  public void changed(
                                      ObservableValue<? extends Number> arg0,
                                      Number arg1,
                                      Number arg2) {
                                    updateOfficialFiltersResult();
                                  }
                                });
                            return selectInteger;
                          }
                        });
                    officialsFilteredTableView.getColumns().add(skillColumn);
                    skillFiltersColumn.put(skill, skillColumn);
                  }

                  for (SkillFilter skillFilter : arg0.getRemoved()) {
                    final Skill skill = skillFilter.getSkill();
                    TableColumn<Official, Number> column = skillFiltersColumn.remove(skill);

                    if (column != null) {
                      officialsFilteredTableView.getColumns().remove(column);
                    }
                  }
                }
              }
            });
    Bindings.bindContent(skillFiltersMatcher.getMatchers(), skillFiltersTableView.getItems());
  }