JavaFX - ListView- Дженерики - CellFactory - PullRequest
0 голосов
/ 14 мая 2018

У меня есть:

public abstract class V {}

public class PV extends V {}

public class TV extends V {}

У меня также есть:

ListView<? extends V> listView = new ListView<>();

Когда я пытаюсь:

listView.setCellFactory(new Callback<ListView<? extends V>, ListCell<? extends V>>() {
        @Override
        .............
    });

Я получаю предупреждение об ошибке:

Incompatible types: 
anonymous Callback<ListView<? extends V>, ListCell<? extends V>>
cannot be converted to Callback<ListView<CAP#1>, ListCell<CAP#!>>
where CAP#1 is fresh type-variable:
CAP#1 extends V from capture of ? extends V

Я пытался:

new Callback<ListView<V>, ListCell<V>>() 

Это не решило эту проблему.

Почему я получаю это сообщение и есть ли способ его решить?

1 Ответ

0 голосов
/ 14 мая 2018

Для cellFactory требуется Callback<ListView<T>, ListCell<T>>, где T - параметр типа ListView.

Используя подстановочный знак, вы не можете указать точный параметр типа. Кроме того, так как ваш подстановочный знак ограничивает T супертипами V, вы не можете использовать ListCell<? extends V> (даже если точный тип не будет требоваться, updateItem получает значение, соответствующее параметру типа ListCell, это нет гарантии, что тип может быть назначен (точный параметр типа ListView может быть Object, а параметр ListView может быть PV)).

Вы можете создать метод для создания Callback, хотя для предотвращения проблемы с подстановочными знаками, однако ограничение super все еще не имеет большого смысла, так как ListCell действует как потребитель.

public static <T> Callback<ListView<T>, ListCell<T>> forListView() {
    return new Callback<ListView<T>, ListCell<T>>() {
        @Override
        public ListCell<T> call(ListView<T> lv) {
            return new ListCell<T>() {

                @Override
                protected void updateItem(T item, boolean empty) {
                    super.updateItem(item, empty);
                    setText((empty || item == null) ? "" : item.toString());
                }

            };
        }
    };
}
ListView<? super V> lv = ...;
lv.setCellFactory(forListView());

(Вы также можете наложить ограничения на T статического метода: public static <T super V> Callback<ListView<T>, ListCell<T>> forListView())

...