如何使用Set作为TableView的基础

时间:2019-06-13 08:36:06

标签: javafx set tableview javafx-8

我已经开发了一些代码,并且有SetUser

public class ParkCentral{
    private Set<User> users = new HashSet<>();
}

然后,在不同的类中,我正在开发User s的GUI和TableView。 问题是我无法从ObervableList创建Set。我希望对ParkCentral.users更改会反映在TableView上。

是否可以在不更改ParkCentral实现的情况下,也可以将Set更改为List

为什么TableView仅适用于ObservableList,而不适用于ObservableSet或ObservableMap?

2 个答案:

答案 0 :(得分:5)

  

为什么TableView仅适用于ObservableList,而不适用于ObservableSet或ObservableMap?

TableView表示项目的有序集合。 Map都没有  Set也不满足这些要求(某些实现除外)。

虽然可以听Set中的更改并在List中进行适当的更改。不过,仅使用HashSet是不可能的;根本没有办法观察这个收藏;更改后,您始终需要手动更新列表。

使用ObservableSet可以使您添加一个监听器,该监听器可对列表进行更新。

public class SetContentBinding<T> {

    private final ObservableSet<T> source;
    private final Collection<? super T> target;
    private final SetChangeListener<T> listener;

    public SetContentBinding(ObservableSet<T> source, Collection<? super T> target) {
        if (source == null || target == null) {
            throw new IllegalArgumentException();
        }
        this.source = source;
        this.target = target;
        target.clear();
        target.addAll(source);
        this.listener = c -> {
            if (c.wasAdded()) {
                target.add(c.getElementAdded());
            } else {
                target.remove(c.getElementRemoved());
            }
        };
        source.addListener(this.listener);
    }

    /**
     * dispose the binding
     */
    public void unbind() {
        source.removeListener(listener);
    }

}

用法示例:

public class ParkCentral{
    private ObservableSet<User> users = FXCollections.observableSet(new HashSet<>());
}
new SetContentBinding(parkCentral.getUsers(), tableView.getItems());

答案 1 :(得分:0)

您可以尝试使用自定义列:

 TableColumn<ParkCentral, Void> myCol = new TableColumn<>("NameColumn");        
        myCol.setPrefWidth(150);    
        myCol.setCellFactory(col->{            
            TableCell<ParkCentral, Void> cell = new TableCell<ParkCentral, Void>()
             {
                @Override
                public void updateItem(Void item, boolean empty) 
                {
                    super.updateItem(item, empty);
                    if (empty) {
                        setGraphic(null);
                    } else {       
                       HBox h = new HBox();                  
                       ParckCentral myObj = getTableView().getItems().get(getIndex());

                       //call any method/variable from myObj that you need
                       //and put the info that you want show on the cell on labels, buttons, images, etc

                       h.getChildren().addAll(label, button, etc...);
                       setGraphic(h);
                    }
                }
            };
            return cell;
       });