FXMisc / Flowless

Efficient VirtualFlow for JavaFX
BSD 2-Clause "Simplified" License
185 stars 38 forks source link

Expandable cell problem #71

Closed pkrysztofiak closed 4 years ago

pkrysztofiak commented 5 years ago

I'm trying to create list having expandable component inside cell. Everyting works great except from few last items on the list. Sometimes trying to expand/collapse has no effect. ActionEvent is never brought to handler as completly different button seems to be focused. Is there any chance I can get my feature working correctly? To reproduce please expand some element in the begining of the list, then scroll down to the bottom of the list and try to expand/collapse item using "Expand" button. Sometimes it takes few tries to reproduce.

import org.fxmisc.flowless.Cell;
import org.fxmisc.flowless.VirtualFlow;
import org.fxmisc.flowless.VirtualizedScrollPane;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class App extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        ObservableList<Employee> employees = FXCollections.observableArrayList();
        for (int i = 0; i < 100; i++) {
            employees.add(new Employee("John " + i));
        }

        VirtualFlow<Employee, Cell<Employee, EmployeeView>> virtualFlow = VirtualFlow.createVertical(employees, employee -> Cell.wrapNode(new EmployeeView(employee)));
        VirtualizedScrollPane<VirtualFlow<Employee, Cell<Employee, EmployeeView>>> virtualizedScrollPane = new VirtualizedScrollPane<>(virtualFlow);
        Scene scene = new Scene(virtualizedScrollPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

}

class Employee {
    private boolean expanded;
    private final String name;

    public Employee(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public boolean isExpanded() {
        return expanded;
    }

    public void setExpanded(boolean expanded) {
        this.expanded = expanded;
    }
}

class EmployeeView extends VBox {

    private final Button button = new Button("Expand");
    private final TextField textField = new TextField();
    private final HBox headerPane = new HBox(button, textField);

    private final StackPane contentPane = new StackPane();

    {
        contentPane.setStyle("-fx-background-color: red;");
        contentPane.setPrefHeight(100);
        getChildren().addAll(headerPane, contentPane);
    }

    public EmployeeView(Employee employee) {
        textField.setText(employee.getName());
        contentPane.setVisible(employee.isExpanded());
        contentPane.setManaged(employee.isExpanded());

        button.setOnAction(actionEvent -> {
            employee.setExpanded(!employee.isExpanded());
            contentPane.setVisible(employee.isExpanded());
            contentPane.setManaged(employee.isExpanded());
        });
    }
}
bwcsemaj commented 4 years ago

I'm no expert on this library but it is expected that all Cells are same size. Just the way it was designed. Try to have different cell lengths and then try showing a certain index if you want to see it in action...

With this being noted, with the little tests I have run, regarding your code, I have noticed that the bottom cells are getting recreated when you press the button (because changing size of the cells); well really any where (I'd assume css settings when clicking things (probably regarding focus) changes the sizes of the nodes ever so slightly which is causing the bottom cell to be recreated). So you press the button, triggers events, those events are causing it to recreate the bottom cell(s), the node that was going to get the event is now off the scene graph thus it is not getting the event to toggle expanded.

newtingz commented 3 years ago

Hello,but How Do you Get Clicked Item Or Cell ?