0

汎用 Java クラスを作成して、チェックを外したりチェックしたりできるフィルター項目のリストを表示し、結果の選択をコントローラーに渡して、表示用のプライマリ オブジェクトのコレクションをフィルター処理します。2 つの 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);
}
}
4

1 に答える 1

1

問題が解決しました。ガベージ コレクターは、ポップオーバーが非表示になるたびにリスナーを削除していました。「リスナーの追加」ステートメントを、ポップオーバーを表示するポイントに移動しただけです。

于 2015-05-12T20:10:27.190 に答える