ScrollPane currently offers the hvalue and vvalue properties to do programmatic scrolling, but changing these values to do common scroll actions like exactly one page to the left/right or up/down requires some non-trivial calculations.
I think therefore it could be a good idea to offer some convenience methods to scroll a scroll pane by a specific fraction, and perhaps also by a specific number of units. In this way, the user can much more easily get the effect they desire. Below is code that could be used as the implementation for such methods.
Suggested is to add the methods:
void scrollByFraction(double x, double y);
Where x and y are expressed as fractions of the viewport area (ie. 1.0 = scroll exactly one visible area down or right, and -0.5 would for example represent scroll half a visible area left or up).
And:
void scrollByUnit(double x, double y);
Where x and y represent pixels.
Here is the implementation as static methods:
static void scrollByFraction(ScrollPane scrollPane, double x, double y) {
Node content = scrollPane.getContent();
if (content == null) {
return;
}
Bounds viewportBounds = scrollPane.getViewportBounds();
Bounds layoutBounds = content.getLayoutBounds();
if (x != 0) {
double visibleFraction = viewportBounds.getWidth() / layoutBounds.getWidth();
double range = scrollPane.getHmax() - scrollPane.getHmin();
double scrollFactor = range * visibleFraction / (1 - visibleFraction);
scrollPane.setHvalue(scrollPane.getHvalue() + x * scrollFactor);
}
if (y != 0) {
double visibleFraction = viewportBounds.getHeight() / layoutBounds.getHeight();
double range = scrollPane.getVmax() - scrollPane.getVmin();
double scrollFactor = range * visibleFraction / (1 - visibleFraction);
scrollPane.setVvalue(scrollPane.getVvalue() + y * scrollFactor);
}
}
static void scrollByUnit(ScrollPane scrollPane, double x, double y) {
Node content = scrollPane.getContent();
if (content == null) {
return;
}
Bounds viewportBounds = scrollPane.getViewportBounds();
Bounds layoutBounds = content.getLayoutBounds();
if (x != 0) {
double range = scrollPane.getHmax() - scrollPane.getHmin();
double scrollFactor = range / (layoutBounds.getWidth() - viewportBounds.getWidth());
scrollPane.setHvalue(scrollPane.getHvalue() + x * scrollFactor);
}
if (y != 0) {
double range = scrollPane.getVmax() - scrollPane.getVmin();
double scrollFactor = range / (layoutBounds.getHeight() - viewportBounds.getHeight());
scrollPane.setVvalue(scrollPane.getVvalue() + y * scrollFactor);
}
}
I think therefore it could be a good idea to offer some convenience methods to scroll a scroll pane by a specific fraction, and perhaps also by a specific number of units. In this way, the user can much more easily get the effect they desire. Below is code that could be used as the implementation for such methods.
Suggested is to add the methods:
void scrollByFraction(double x, double y);
Where x and y are expressed as fractions of the viewport area (ie. 1.0 = scroll exactly one visible area down or right, and -0.5 would for example represent scroll half a visible area left or up).
And:
void scrollByUnit(double x, double y);
Where x and y represent pixels.
Here is the implementation as static methods:
static void scrollByFraction(ScrollPane scrollPane, double x, double y) {
Node content = scrollPane.getContent();
if (content == null) {
return;
}
Bounds viewportBounds = scrollPane.getViewportBounds();
Bounds layoutBounds = content.getLayoutBounds();
if (x != 0) {
double visibleFraction = viewportBounds.getWidth() / layoutBounds.getWidth();
double range = scrollPane.getHmax() - scrollPane.getHmin();
double scrollFactor = range * visibleFraction / (1 - visibleFraction);
scrollPane.setHvalue(scrollPane.getHvalue() + x * scrollFactor);
}
if (y != 0) {
double visibleFraction = viewportBounds.getHeight() / layoutBounds.getHeight();
double range = scrollPane.getVmax() - scrollPane.getVmin();
double scrollFactor = range * visibleFraction / (1 - visibleFraction);
scrollPane.setVvalue(scrollPane.getVvalue() + y * scrollFactor);
}
}
static void scrollByUnit(ScrollPane scrollPane, double x, double y) {
Node content = scrollPane.getContent();
if (content == null) {
return;
}
Bounds viewportBounds = scrollPane.getViewportBounds();
Bounds layoutBounds = content.getLayoutBounds();
if (x != 0) {
double range = scrollPane.getHmax() - scrollPane.getHmin();
double scrollFactor = range / (layoutBounds.getWidth() - viewportBounds.getWidth());
scrollPane.setHvalue(scrollPane.getHvalue() + x * scrollFactor);
}
if (y != 0) {
double range = scrollPane.getVmax() - scrollPane.getVmin();
double scrollFactor = range / (layoutBounds.getHeight() - viewportBounds.getHeight());
scrollPane.setVvalue(scrollPane.getVvalue() + y * scrollFactor);
}
}