66import javafx .beans .DefaultProperty ;
77import javafx .beans .NamedArg ;
88import javafx .beans .Observable ;
9- import javafx .beans .binding .Bindings ;
109import javafx .beans .binding .DoubleBinding ;
1110import javafx .beans .value .ChangeListener ;
1211import javafx .css .PseudoClass ;
1312import javafx .geometry .Bounds ;
13+ import javafx .geometry .Insets ;
1414import javafx .geometry .Orientation ;
15- import javafx .scene .Node ;
1615import javafx .scene .control .ScrollBar ;
1716import javafx .scene .control .ScrollPane ;
1817import javafx .scene .layout .Region ;
2120import 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