0

Я пишу обобщенный класс Java для отображения списка элементов фильтра, которые могут быть удалены/отмечены, и затем полученный выбор затем передается контроллеру для фильтрации коллекции первичных объектов для дисплей. Я использую два элемента управления ControlsFX: PopOver, чтобы содержать список фильтров и CheckListView для отображения и управления отдельными элементами.JavaFX ListChangedListeners не запускаются с помощью ControlsFX PopOver и CheckListView

Поток состоит в том, что класс фильтра PopOver создается в конструкторе контроллера, и исходные данные перезагружаются каждый раз, когда он отображается.

На первый взгляд, код работает. Добавлены исходные элементы, правильность проверки и снятия флажка и количество элементов в списке отмеченных элементов. Однако я добавил слушателей в наблюдаемые списки как для исходных данных, так и для списка отмеченных элементов, и ни один из них не запускается.

Я пробовал записывать слушателей в режиме онлайн и как отдельные методы (как в примере), и я пробовал писать их в традиционных onChanged и лямбда-стилях. Ничего не изменилось. Я также попытался использовать почти идентичный код, просто используя CheckListView в качестве узла панели. Это работало точно так, как ожидалось.

Я также просмотрел журнал проблем ControlsFX и не нашел ничего непосредственно релевантного (за исключением подтверждения того, что код, который я использовал, выглядел нормально).

Это класс фильтра:

package debuglogger; 

import javafx.collections.FXCollections; 
import javafx.collections.ListChangeListener; 
import javafx.collections.ObservableList; 
import javafx.scene.layout.BorderPane; 
import org.controlsfx.control.CheckListView; 
import org.controlsfx.control.PopOver; 

public class FilterPopOverSO<T> extends PopOver { 

private ObservableList<T> sourceData; 

private BorderPane popoverNode; 

private CheckListView<T> filterList; 

/** 
* ============================================================================================ 
* Constructor 
* ============================================================================================ 
*/ 

public FilterPopOverSO() { 

    super(); 

    sourceData = FXCollections.observableArrayList(); 

    popoverNode = new BorderPane(); 

    filterList = new CheckListView<>(); 
    filterList.setPrefWidth(600D); 
    filterList.setMaxWidth(600D); 

    popoverNode.setCenter(filterList); 
    setContentNode(popoverNode); 

    filterList.getItems().addListener(sourceItemsListener); 

    filterList.getCheckModel().getCheckedItems().addListener(checkedItemsListener); 

    filterList.getCheckModel().checkAll(); 
} 

/** 
* ============================================================================================ 
* Listeners 
* ============================================================================================ 
*/ 

ListChangeListener<T> sourceItemsListener = (change) -> { 

    System.out.println("Start of Change Listener 'sourceItemsListener'"); 

    while(change.next()) { 

     System.out.println("  Added:  " + change.wasAdded()); 
     System.out.println("  Permutated: " + change.wasPermutated()); 
     System.out.println("  Removed: " + change.wasRemoved()); 
     System.out.println("  Updated: " + change.wasUpdated()); 

    } 

    System.out.println("End of of Change Listener 'sourceItemsListener'"); 
}; 

ListChangeListener<T> checkedItemsListener = (change) -> { 

    System.out.println("Start of Change Listener 'checkedItemsListener'"); 

    while(change.next()) { 

     System.out.println("  Added:  " + change.wasAdded()); 
     System.out.println("  Permutated: " + change.wasPermutated()); 
     System.out.println("  Removed: " + change.wasRemoved()); 
     System.out.println("  Updated: " + change.wasUpdated()); 

    } 

    System.out.println("End of of Change Listener 'checkedItemsListener'"); 
}; 

public void setSourceData(ObservableList<T> sourceData) { 
    filterList.setItems(sourceData); 
} 
} 

И это испытание заглушки:

package scratchpad; 

import debuglogger.FilterPopOverSO; 
import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.AnchorPane; 
import javafx.stage.Stage; 

public class FilterPopOverTest extends Application { 

@Override 
public void start(Stage primaryStage) { 

    ObservableList<String> sourceList = FXCollections.observableArrayList("Item 1", "Item 2", "Item 3"); 
    FilterPopOverSO<String> p = new FilterPopOverSO<>();   

    AnchorPane root = new AnchorPane(); 

    Button btn = new Button("Click Me!"); 

    btn.setOnAction(event -> { 

     System.out.println("Just to show that I was here!"); 
     p.setSourceData(sourceList); 
     p.show(btn); 

    }); 

    root.getChildren().add(btn); 
    AnchorPane.setTopAnchor(btn, 50D); 
    AnchorPane.setLeftAnchor(btn, 50D); 

    primaryStage.setTitle("Filter PopOver Test"); 
    primaryStage.setScene(new Scene(root, 500, 500)); 
    primaryStage.show(); 
} 

public static void main(String[] args) { 
    launch(args); 
} 
} 

ответ

1

Проблема решена. Сборщик мусора удалял слушателей каждый раз, когда popover был скрыт. Я просто переместил оператор «добавить слушателя» в точку, где я показал popover.