Skip to content

Commit

Permalink
Refactor PagingListView to improve list handling
Browse files Browse the repository at this point in the history
Reorganized list handling by introducing InnerListViewSkin usage in PagingListView and reducing redundancy in PagingListViewSkin. Moved functionality to PagingListView, ensuring cleaner code structure and better separation of concerns. Added support for multiple selection mode and improved the update mechanism with a weak listener.
  • Loading branch information
dlemmermann committed Dec 3, 2024
1 parent 4e6f452 commit 2f7f192
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 23 deletions.
33 changes: 33 additions & 0 deletions gemsfx/src/main/java/com/dlsc/gemsfx/PagingListView.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.dlsc.gemsfx;

import com.dlsc.gemsfx.skins.InnerListViewSkin;
import com.dlsc.gemsfx.skins.PagingListViewSkin;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.WeakInvalidationListener;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
Expand All @@ -15,6 +18,7 @@
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MultipleSelectionModel;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.Skin;
import javafx.util.Callback;

Expand All @@ -30,9 +34,23 @@ public class PagingListView<T> extends PagingControlBase {

private final ObservableList<T> unmodifiableItems = FXCollections.unmodifiableObservableList(items);

private final ListView<T> listView = new ListView<>(items);

private final InnerListViewSkin<T> innerListViewSkin;

private final InvalidationListener updateListener = (Observable it) -> updateItems();

private final WeakInvalidationListener weakUpdateListener = new WeakInvalidationListener(updateListener);

public PagingListView() {
getStyleClass().add("paging-list-view");

listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
listView.cellFactoryProperty().bind(cellFactoryProperty());

innerListViewSkin = new InnerListViewSkin<>(listView, this);
listView.setSkin(innerListViewSkin);

loadingService.setOnSucceeded(evt -> {
List<T> newList = loadingService.getValue();
if (newList != null) {
Expand Down Expand Up @@ -60,6 +78,13 @@ protected void updateItem(T item, boolean empty) {
}
}
});

getUnmodifiableItems().addListener(weakUpdateListener);
pageSizeProperty().addListener(weakUpdateListener);
pageProperty().addListener(weakUpdateListener);
cellFactoryProperty().addListener(weakUpdateListener);

updateItems();
}

@Override
Expand All @@ -72,6 +97,10 @@ public String getUserAgentStylesheet() {
return Objects.requireNonNull(PagingListView.class.getResource("paging-list-view.css")).toExternalForm();
}

public final ListView<T> getListView() {
return listView;
}

private class LoadingService extends Service<List<T>> {

@Override
Expand Down Expand Up @@ -219,4 +248,8 @@ public final ObjectProperty<Callback<ListView<T>, ListCell<T>>> cellFactoryPrope
}
return cellFactory;
}

private void updateItems() {
innerListViewSkin.updateItems();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,16 @@ public Orientation getContentBias() {
}
};

private final InvalidationListener updateListener = (Observable it) -> updateItems();

private final WeakInvalidationListener weakUpdateListener = new WeakInvalidationListener(updateListener);

private final InnerListViewSkin<T> innerListViewSkin;

private final ListView<T> innerListView;

public PagingListViewSkin(PagingListView<T> pagingListView) {
super(pagingListView);

innerListView = new ListView<>();
innerListView.setPrefHeight(Region.USE_COMPUTED_SIZE);
innerListView.cellFactoryProperty().bind(pagingListView.cellFactoryProperty());
innerListView.setItems(pagingListView.getUnmodifiableItems());
innerListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
innerListView = pagingListView.getListView();

pagingListView.selectionModelProperty().bindBidirectional(innerListView.selectionModelProperty());

innerListViewSkin = new InnerListViewSkin<>(innerListView, pagingListView);
innerListView.setSkin(innerListViewSkin);

pagingControls.pageProperty().bindBidirectional(pagingListView.pageProperty());
pagingControls.totalItemCountProperty().bindBidirectional(pagingListView.totalItemCountProperty());
pagingControls.pageSizeProperty().bind(pagingListView.pageSizeProperty());
Expand All @@ -84,19 +72,13 @@ public PagingListViewSkin(PagingListView<T> pagingListView) {
// when the underlying data list changes, then we have to recreate the binding for the placeholder
pagingListView.getUnmodifiableItems().addListener((Observable it) -> bindPlaceholder(null, pagingListView.getPlaceholder()));

pagingListView.getUnmodifiableItems().addListener(weakUpdateListener);
pagingListView.pageSizeProperty().addListener(weakUpdateListener);
pagingListView.pageProperty().addListener(weakUpdateListener);
pagingListView.cellFactoryProperty().addListener(weakUpdateListener);

pagingListView.usingScrollPaneProperty().addListener(it -> updateView());
pagingListView.placeholderProperty().addListener(it -> updateView());

getChildren().setAll(stackPane);

updateStyleClass();
updateView();
updateItems();
}

private void updateStyleClass() {
Expand Down Expand Up @@ -150,8 +132,4 @@ private Node wrapInScrollPane(Node node) {
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
return scrollPane;
}

private void updateItems() {
innerListViewSkin.updateItems();
}
}

0 comments on commit 2f7f192

Please sign in to comment.