Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetFirstVisibleIndex returns same values before and after scrolling #123

Open
PavelTurk opened this issue Oct 12, 2024 · 1 comment
Open

Comments

@PavelTurk
Copy link

PavelTurk commented Oct 12, 2024

This is my test code:

public class FlawTest extends Application {

    private static class FlowRow implements Cell<Integer, Node> {

        private Integer rowIndex;

        private final Label label = new Label();

        private final HBox hBox = new HBox(label);

        public FlowRow(Integer rowIndex) {
            this.rowIndex = rowIndex;
            label.setText(String.valueOf(rowIndex));
        }

        @Override
        public void updateItem(Integer item) {
            rowIndex = item;
            if (item == null) {
                label.setText("");
            } else {
                label.setText(String.valueOf(rowIndex));
            }
        }

        @Override
        public Node getNode() {
            return hBox;
        }

        @Override
        public boolean isReusable() {
            return true;
        }
    }

    private VirtualFlow<Integer, FlowRow> flow;

    private ObservableList<Integer> rows;

    @Override
    public void start(Stage primaryStage) throws Exception {
        List<Integer> list = new ArrayList<>();
        for (var i = 0; i < 100000; i++) {
            list.add(i);
        }
        rows = FXCollections.observableList(list);

        flow = VirtualFlow.createVertical(rows, row -> new FlowRow(row));
		VirtualizedScrollPane<VirtualFlow<Integer, FlowRow>> scrollPane = new VirtualizedScrollPane<>(flow);
        VBox.setVgrow(scrollPane, Priority.ALWAYS);

        var scrollButton = new Button("Scroll");
        scrollButton.setOnAction(e -> {
            System.out.println("Before scrolling first cell index: " + flow.getFirstVisibleIndex());
            flow.scrollYBy(flow.getHeight());
            System.out.println("After scrolling first cell index: " + flow.getFirstVisibleIndex());
        });

        VBox root = new VBox(scrollPane, new HBox(scrollButton));
        Scene scene = new Scene(root, 400, 300);
        primaryStage.setTitle("Flaw Test");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}

If you push button you will get the following output:

Before scrolling first cell index: 0
After scrolling first cell index: 0
Before scrolling first cell index: 17
After scrolling first cell index: 17

I tried:

scrollButton.setOnAction(e -> {
    System.out.println("Before scrolling first cell index: " + flow.getFirstVisibleIndex());
    flow.scrollYBy(flow.getHeight());
    Platform.runLater(() -> System.out.println("After scrolling first cell index: " + flow.getFirstVisibleIndex()));
});

but the result was the same.

@Jugen
Copy link
Contributor

Jugen commented Oct 15, 2024

Yeah, at least one layout pulse must occur for the value to update. What happens is that "Platform.runLater" is bundled into the same layout pulse as "scrollYBy" so the value hasn't been updated yet. So you need something like the following:

scrollButton.setOnAction(e -> {
    System.out.println("Before scrolling first cell index: " + flow.getFirstVisibleIndex());
    flow.scrollYBy(flow.getHeight());
    scene.addPostLayoutPulseListener( new WaitForScrollYPulse( scene ) );
});
private class WaitForScrollYPulse implements Runnable
{
    private Scene scene;
    private int pulseCount = 0;

    public WaitForScrollYPulse( Scene scene )
    {
        this.scene = scene;
    }

    @Override
    public void run()
    {
        if ( ++pulseCount > 1 )
        {
            scene.removePostLayoutPulseListener( this );
            System.out.println("After scrolling first cell index: " + flow.getFirstVisibleIndex());
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants