不使用ControlsFX PopOver和CheckListView

时间:2015-05-12 14:19:23

标签: javafx-8 observablecollection popover controlsfx listchanged

我正在编写一个通用Java类来显示可以取消/检查的过滤器项列表,然后将结果选择传递给控制器​​以过滤主要对象的集合以供显示。我正在使用两个ControlsFX控件:PopOver包含过滤器列表,CheckListView用于显示和控制各个项目。

流程是过滤器PopOver类在控制器的构造函数中实例化,每次显示时都会重新加载源数据。

从表面上看,代码似乎有效。添加源项目,检查和取消选中工作以及已检查项目列表中的项目数是否正确。但是我已经为源数据和已检查项列表添加了Observable Lists的监听器,并且都没有被触发。

我尝试在线编写监听器,并作为单独的方法(如示例中所示),我尝试用传统的onChanged和lambda样式编写它们。两者都没有区别。 我也尝试使用几乎完全相同的代码,只使用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 个答案:

答案 0 :(得分:1)

问题解决了。每次隐藏弹出窗口时,垃圾收集器都会删除侦听器。我只是移动了添加监听器&#39;陈述到我展示弹出窗口的地步。