package moe.tristan.easyfxml.model.components.listview;

import org.springframework.context.ApplicationContext;
import moe.tristan.easyfxml.api.FxmlController;

import javafx.fxml.FXML;
import javafx.scene.control.ListView;

import java.util.function.Supplier;

@SuppressWarnings("WeakerAccess")
public abstract class CustomListViewBase<T> implements FxmlController {

    @FXML
    protected ListView<T> listView;

    protected final ApplicationContext applicationContext;
    protected final Supplier<CustomListViewCellBase<T>> cellSupplier;

    public CustomListViewBase(
        ApplicationContext applicationContext,
        Class<? extends CustomListViewCellBase<T>> customCellClass
    ) {
        this.applicationContext = applicationContext;
        this.cellSupplier = () -> applicationContext.getBean(customCellClass);
    }

    @Override
    public void initialize() {
        setCustomCellFactory();
    }

    private void setCustomCellFactory() {
        listView.setCellFactory(list -> cellSupplier.get());
    }

}

@@ -81,16 +81,182 @@
 ork.
-context.
+beans.factory.config.ConfigurableBeanFactory;%0Aimport org.springframework.beans.factory.config.ConfigurableListableBeanFactory;%0Aimport org.springframework.context.Configurable
 Appl
@@ -318,16 +318,73 @@
 troller;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Aimport
@@ -437,24 +437,99 @@
 .ListView;%0A%0A
+import java.util.Arrays;%0Aimport java.util.concurrent.atomic.AtomicBoolean;%0A
 import java.
@@ -551,16 +551,48 @@
 upplier;
+%0Aimport java.util.stream.Stream;
 %0A%0A@Suppr
@@ -692,16 +692,197 @@
 ller %7B%0A%0A
+    private static final Logger LOG = LoggerFactory.getLogger(CustomListViewBase.class);%0A%0A    private static AtomicBoolean HAS_CHECKED_BEAN_DEFINITIONS = new AtomicBoolean(false);%0A%0A
     @FXM
@@ -940,16 +940,28 @@
 d final 
+Configurable
 Applicat
@@ -1101,16 +1101,28 @@
         
+Configurable
 Applicat
@@ -1360,16 +1360,1663 @@
 Class);%0A
+        ensureCorrectSpringScoping();%0A    %7D%0A%0A    /**%0A     * You should not need to care about this method.%0A     * In the unlikely case where you actually want all the cells of your ListView to actually%0A     * be the same one, it is left protected and not private so you can override it and avoid the%0A     * warnings being spouted at you.%0A     *%0A     * Else, the idea is that a set of cells is created and they share the elements one after%0A     * another during scrolling and JavaFX might generate more of them later so we should just%0A     * not make any assumption and expect all of them to be different and not singletons.%0A     */%0A    protected void ensureCorrectSpringScoping() %7B%0A        if (HAS_CHECKED_BEAN_DEFINITIONS.get()) return;%0A%0A        final ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();%0A        Stream.of(CustomListViewCellController.class, CustomListViewCellBase.class)%0A              .map(beanFactory::getBeanNamesForType)%0A              .flatMap(Arrays::stream)%0A              .forEach(pBean -%3E %7B%0A                  final String effectiveScope = beanFactory.getBeanDefinition(pBean).getScope();%0A                  if (ConfigurableBeanFactory.SCOPE_PROTOTYPE.equals(effectiveScope)) %7B%0A                      LOG.warn(%0A                              %22Custom ListView cells wrapper and controllers should be prototype-scoped bean. %22 +%0A                              %22See @Scope annotation.%5Cn%22 +%0A                              %22Faulty bean was named : %5C%22%7B%7D%5C%22%22,%0A                              pBean%0A                      );%0A                  %7D%0A              %7D);%0A        HAS_CHECKED_BEAN_DEFINITIONS.set(true);%0A
     %7D%0A%0A 

Add some runtime checks to ListView related components scoping.