All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.palexdev.materialfx.controls.MFXFlowlessListView Maven / Gradle / Ivy

There is a newer version: 11.17.0
Show newest version
/*
 *     Copyright (C) 2021 Parisi Alessandro
 *     This file is part of MaterialFX (https://github.com/palexdev/MaterialFX).
 *
 *     MaterialFX is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     MaterialFX is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with MaterialFX.  If not, see .
 */

package io.github.palexdev.materialfx.controls;

import io.github.palexdev.materialfx.MFXResourcesLoader;
import io.github.palexdev.materialfx.controls.base.AbstractMFXFlowlessListView;
import io.github.palexdev.materialfx.controls.cell.MFXFlowlessListCell;
import io.github.palexdev.materialfx.selection.ListSelectionModel;
import io.github.palexdev.materialfx.selection.base.IListSelectionModel;
import io.github.palexdev.materialfx.skins.MFXFlowlessListViewSkin;
import javafx.beans.property.MapProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableMap;
import javafx.scene.control.Skin;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;

/**
 * Implementation of a list view based on Flowless.
 * 

* Extends {@link AbstractMFXFlowlessListView}. *

* Default cell: {@link MFXFlowlessListCell}. *

* Default selection model: {@link ListSelectionModel}. *

* Default skin: {@link MFXFlowlessListViewSkin}. */ public class MFXFlowlessListView extends AbstractMFXFlowlessListView, IListSelectionModel> { //================================================================================ // Properties //================================================================================ private final String STYLE_CLASS = "mfx-list-view"; private final String STYLESHEET = MFXResourcesLoader.load("css/mfx-flowless-listview.css"); //================================================================================ // Constructors //================================================================================ public MFXFlowlessListView() { this(List.of()); } public MFXFlowlessListView(List items) { super(items); initialize(); } //================================================================================ // Methods //================================================================================ protected void initialize() { super.initialize(); getStyleClass().setAll(STYLE_CLASS); items.addListener((ListChangeListener) change -> { if (getSelectionModel().getSelectedItems().isEmpty()) { return; } if (change.getList().isEmpty()) { getSelectionModel().clearSelection(); return; } getSelectionModel().setUpdating(true); Map addedOffsets = new HashMap<>(); Map removedOffsets = new HashMap<>(); while (change.next()) { if (change.wasAdded()) { int from = change.getFrom(); int to = change.getTo(); int offset = to - from; addedOffsets.put(from, offset); } if (change.wasRemoved()) { int from = change.getFrom(); int offset = change.getRemovedSize(); IntStream.range(from, from + offset) .filter(getSelectionModel()::containSelected) .forEach(getSelectionModel()::clearSelectedItem); removedOffsets.put(from, offset); } } updateSelection(addedOffsets, removedOffsets); }); } protected void updateSelection(Map addedOffsets, Map removedOffsets) { MapProperty selectedItems = getSelectionModel().selectedItemsProperty(); ObservableMap updatedMap = FXCollections.observableHashMap(); selectedItems.forEach((key, value) -> { int sum = addedOffsets.entrySet().stream() .filter(entry -> entry.getKey() <= key) .mapToInt(Map.Entry::getValue) .sum(); int diff = removedOffsets.entrySet().stream() .filter(entry -> entry.getKey() < key) .mapToInt(Map.Entry::getValue) .sum(); int shift = sum - diff; updatedMap.put(key + shift, value); }); if (!selectedItems.equals(updatedMap)) { selectedItems.set(updatedMap); } getSelectionModel().setUpdating(false); } //================================================================================ // Override Methods //================================================================================ @Override protected void setDefaultCellFactory() { setCellFactory(item -> new MFXFlowlessListCell<>(this, item)); } @Override protected void setDefaultSelectionModel() { IListSelectionModel selectionModel = new ListSelectionModel<>(); setSelectionModel(selectionModel); } @Override protected Skin createDefaultSkin() { return new MFXFlowlessListViewSkin<>(this); } @Override public String getUserAgentStylesheet() { return STYLESHEET; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy