Как использовать Set в качестве базы для TableView - PullRequest
1 голос
/ 13 июня 2019

Я разработал некоторый код, и у меня есть Set из User s:

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

Затем в другом классе я разрабатываю GUI и TableView User s. Проблема в том, что я не могу создать ObervableList из Set. И мне бы хотелось, чтобы изменения на ParkCentral.users отразились на TableView.

Это можно сделать без изменения ParkCentral реализации, без изменения Set на List?

Почему TableView работает только с ObservableList, а не с ObservableSet или ObservableMap?

Ответы [ 2 ]

5 голосов
/ 13 июня 2019

Почему TableView работает только с ObservableList, а не с ObservableSet или ObservableMap?

A 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());
0 голосов
/ 13 июня 2019

Вы можете попробовать с пользовательскими столбцами:

 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;
       });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...