Ваша проблема в основном такая же: Добавление EventHandler к ImageView, содержащемуся в метке . Все Cell
специализации, включая ListCell
, наследуются от Labeled
, а все их скины по умолчанию наследуются от LabeledSkinBase
, что является источником вашей проблемы. Для исправления ошибки (см. Другие вопросы и ответы), когда ImageView
используется в качестве графика c для Labeled
, он устанавливается прозрачным для мыши. Поскольку ImageView
прозрачен для мыши, ваш обработчик MOUSE_ENTERED
никогда не может быть вызван по очевидным причинам.
Если вы не знаете, фабрика ячеек по умолчанию ListView
возвращает реализацию ListCell
что, когда элемент является экземпляром Node
, для элемента устанавливается graphic
ячейки. Простое решение - использовать собственную реализацию ListCell
, которая оборачивает ImageView
в другой узел, такой как Pane
. Вот пример:
listView.setCellFactory(lv -> new ListCell<>() {
private final Pane imageViewContainer = new Pane();
@Override
protected void updateItem(ImageView item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
imageViewContainer.getChildren().clear();
setGraphic(null);
} else {
imageViewContainer.getChildren().setAll(item);
setGraphic(imageViewContainer);
}
}
});
Это не позволит ImageView
стать прозрачным для мыши.
В качестве примечания, обычно не рекомендуется использовать GUI объекты (например, ImageView
) в качестве элемента модели ListView
(или любого другого виртуализированного элемента управления). В этом случае это может быть еще худшая идея, поскольку эта настройка поощряет одновременное хранение в памяти каждого Image
, связанного с вашим приложением. В зависимости от количества изображений, а также от их размера, это может легко привести к OutOfMemoryError
или, по крайней мере, потреблению ненужного объема оперативной памяти ваших пользователей.
Возможно, вы захотите рассмотреть использование Card
в качестве элемента модели в сочетании с ограниченным объемом памяти объектов Image
(см. WeakReference
/ SoftReference
, хотя вы также можете искать третий библиотека кэширования партий). Класс Card
может содержать местоположение связанного с ним изображения, или кэш может получить местоположение на основе состояния Card
.
. Вы все равно будете использовать ImageView
в качестве графика c из вашего ListCell
, однако, вам все равно придется использовать обходной путь, упомянутый выше. Помогает использование кэш-памяти с ограничением памяти: если Card
не отображается в ListCell
, то связанный с ним Image
, возможно, становится пригодным для сбора мусора, что снижает требования к памяти вашего приложения.
Кэш также позволяет вам использовать один и тот же Image
везде в вашем приложении (один и тот же Image
может использоваться несколькими ImageView
с), что означает, что вы не всегда загружаете новый Image
когда нужен конкретный (так как он все еще может быть в памяти при запросе). Другими словами, типичная функциональность обеспечивается любым кешем.