Skip to content

Commit a71ced6

Browse files
authored
Take padding into account when scrolling (#111)
Otherwise last item in content isn't scrolled fully into view when using the scrollbar thumb.
1 parent 3b45c92 commit a71ced6

1 file changed

Lines changed: 12 additions & 7 deletions

File tree

src/main/java/org/fxmisc/flowless/VirtualizedScrollPane.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66
import javafx.beans.DefaultProperty;
77
import javafx.beans.NamedArg;
88
import javafx.beans.Observable;
9-
import javafx.beans.binding.Bindings;
109
import javafx.beans.binding.DoubleBinding;
1110
import javafx.beans.value.ChangeListener;
1211
import javafx.css.PseudoClass;
1312
import javafx.geometry.Bounds;
13+
import javafx.geometry.Insets;
1414
import javafx.geometry.Orientation;
15-
import javafx.scene.Node;
1615
import javafx.scene.control.ScrollBar;
1716
import javafx.scene.control.ScrollPane;
1817
import javafx.scene.layout.Region;
@@ -21,7 +20,7 @@
2120
import org.reactfx.value.Var;
2221

2322
@DefaultProperty("content")
24-
public class VirtualizedScrollPane<V extends Node & Virtualized> extends Region implements Virtualized {
23+
public class VirtualizedScrollPane<V extends Region & Virtualized> extends Region implements Virtualized {
2524

2625
private static final PseudoClass CONTENT_FOCUSED = PseudoClass.getPseudoClass("content-focused");
2726

@@ -84,12 +83,14 @@ public VirtualizedScrollPane(
8483
hPosEstimate = Val.combine(
8584
content.estimatedScrollXProperty(),
8685
Val.map(content.layoutBoundsProperty(), Bounds::getWidth),
86+
Val.map(content.paddingProperty(), p -> p.getLeft() + p.getRight()),
8787
content.totalWidthEstimateProperty(),
8888
VirtualizedScrollPane::offsetToScrollbarPosition)
8989
.asVar(this::setHPosition);
9090
vPosEstimate = Val.combine(
9191
content.estimatedScrollYProperty(),
9292
Val.map(content.layoutBoundsProperty(), Bounds::getHeight),
93+
Val.map(content.paddingProperty(), p -> p.getTop() + p.getBottom()),
9394
content.totalHeightEstimateProperty(),
9495
VirtualizedScrollPane::offsetToScrollbarPosition)
9596
.orElseConst(0.0)
@@ -320,17 +321,21 @@ protected void layoutChildren() {
320321
}
321322

322323
private void setHPosition(double pos) {
324+
Insets padding = content.getPadding();
323325
double offset = scrollbarPositionToOffset(
324326
pos,
325327
content.getLayoutBounds().getWidth(),
328+
padding.getLeft() + padding.getRight(),
326329
content.totalWidthEstimateProperty().getValue());
327330
content.estimatedScrollXProperty().setValue((double) Math.round(offset));
328331
}
329332

330333
private void setVPosition(double pos) {
334+
Insets padding = content.getPadding();
331335
double offset = scrollbarPositionToOffset(
332336
pos,
333337
content.getLayoutBounds().getHeight(),
338+
padding.getTop() + padding.getBottom(),
334339
content.totalHeightEstimateProperty().getValue());
335340
// offset needs rounding otherwise thin lines appear between cells,
336341
// usually only visible when cells have dark backgrounds/borders.
@@ -353,16 +358,16 @@ protected double computeValue() {
353358
}
354359

355360
private static double offsetToScrollbarPosition(
356-
double contentOffset, double viewportSize, double contentSize) {
361+
double contentOffset, double viewportSize, double padding, double contentSize) {
357362
return contentSize > viewportSize
358-
? contentOffset / (contentSize - viewportSize) * contentSize
363+
? contentOffset / (contentSize - viewportSize + padding) * contentSize
359364
: 0;
360365
}
361366

362367
private static double scrollbarPositionToOffset(
363-
double scrollbarPos, double viewportSize, double contentSize) {
368+
double scrollbarPos, double viewportSize, double padding, double contentSize) {
364369
return contentSize > viewportSize
365-
? scrollbarPos / contentSize * (contentSize - viewportSize)
370+
? scrollbarPos / contentSize * (contentSize - viewportSize + padding)
366371
: 0;
367372
}
368373
}

0 commit comments

Comments
 (0)