Skip to content

Commit

Permalink
Fix cells larger than viewport layout efficiency (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jugen authored Sep 8, 2020
1 parent 8b82d59 commit 9db3eca
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/main/java/org/fxmisc/flowless/Navigator.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,24 @@ void showLengthRegion(int itemIndex, double fromY, double toY) {

@Override
public void visit(StartOffStart targetPosition) {
placeStartAtMayCrop(targetPosition.itemIndex, targetPosition.offsetFromStart);
cropToNeighborhoodOf( targetPosition.itemIndex ); // Fix for issue #70 (!)
positioner.placeStartAt( targetPosition.itemIndex, targetPosition.offsetFromStart );
fillViewportFrom(targetPosition.itemIndex);
}

@Override
public void visit(EndOffEnd targetPosition) {
placeEndOffEndMayCrop(targetPosition.itemIndex, targetPosition.offsetFromEnd);
cropToNeighborhoodOf( targetPosition.itemIndex ); // Related to issue #70 (?)
positioner.placeEndFromEnd( targetPosition.itemIndex, targetPosition.offsetFromEnd );
fillViewportFrom(targetPosition.itemIndex);
}

private void cropToNeighborhoodOf( int itemIndex ) {
int begin = Math.max( 0, getFirstVisibleIndex() );
int end = Math.max( itemIndex, getLastVisibleIndex() );
positioner.cropTo( Math.min( begin, itemIndex ), end+1 );
}

@Override
public void visit(MinDistanceTo targetPosition) {
Optional<C> cell = positioner.getCellIfVisible(targetPosition.itemIndex);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.fxmisc.flowless;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class BigCellCreationAndLayoutEfficiencyTest extends FlowlessTestBase {

private ObservableList<String> items;
private Counter cellCreations = new Counter();
private VirtualFlow<String, ?> flow;

@Override
public void start(Stage stage) {
// set up items
items = FXCollections.observableArrayList();
items.addAll("red", "green", "blue", "purple");

// set up virtual flow
flow = VirtualFlow.createVertical(
items,
color -> {
cellCreations.inc();
Region reg = new Region();
reg.setStyle("-fx-background-color: " + color);
if ( color.equals( "purple" ) ) reg.setPrefHeight(500.0);
else reg.setPrefHeight(100.0);
return Cell.wrapNode(reg);
});

StackPane stackPane = new StackPane(flow);
stage.setScene(new Scene(stackPane, 200, 400));
stage.show();
}

@Test // Relates to issue #70
public void having_a_very_tall_item_in_viewport_only_creates_and_lays_out_cell_once() {
// if this fails then it's probably because the very big purple cell is being created multiple times
assertEquals(4, cellCreations.get());
}

}

0 comments on commit 9db3eca

Please sign in to comment.