JavaFX ListChangedListeners не запускается с помощью ControlsFX PopOver и CheckListView
Я пишу универсальный класс Java для отображения списка элементов фильтра, которые можно отключить / проверить, а затем полученный результат передается в контроллер для фильтрации коллекции первичных объектов для отображения. Я использую два элемента управления ControlsFX: PopOver
содержать список фильтров и CheckListView
отображать и контролировать отдельные элементы.
Поток в том, что фильтр PopOver
Класс создается в конструкторе контроллера, а исходные данные перезагружаются при каждом его отображении.
На первый взгляд, код работает. Добавлены исходные элементы, работает проверка и снятие отметки, и количество элементов в списке проверенных элементов является правильным. Однако я добавил слушателей в Наблюдаемые списки как для исходных данных, так и для списка проверенных элементов, и ни один из них не запущен.
Я попытался написать слушателей в строке и как отдельные методы (как в примере), и я попытался написать их в традиционном onChanged
и лямбда-стили. Ни один не сделал разницу. Я также попытался использовать практически идентичный код, просто используяCheckListView
как узел панели. Это сработало именно так, как и ожидалось.
Я также просмотрел журнал проблем ControlsFX и не нашел ничего напрямую релевантного (кроме как для подтверждения того, что код, который я использовал, выглядел нормально).
Это класс Filter:
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 ответ
Задача решена. Сборщик мусора удалял слушателей каждый раз, когда поповер скрывался. Я просто переместил оператор "добавить слушателя" в точку, где я показал поповер.