RFR: 8340852: ScrollPane should not consume navigation keys when it doesn't have direct focus [v3]
Kevin Rushforth
kcr at openjdk.org
Thu Oct 31 00:02:37 UTC 2024
On Sun, 20 Oct 2024 21:55:54 GMT, John Hendrikx <jhendrikx at openjdk.org> wrote:
>> John Hendrikx has updated the pull request incrementally with one additional commit since the last revision:
>>
>> Add information about how ScrollPane acts on key presses.
>
> For users to get back to old behavior, some calculations need to be done as `ScrollPane` doesn't offer any helpful programmatic methods to scroll the pane (which is perhaps something that could be addressed in a separate issue, I filed https://bugs.openjdk.org/browse/JDK-8342654).
>
> The most useful helper is one that scroll by a fraction, shown below:
>
> 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);
> }
> }
>
> Then to get something similar to the old behavior back is to install an event handler:
>
> scrollPane.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
> double x = 0;
> double y = 0;
>
> switch(e.getCode()) {
> case KeyCode.LEFT -> x = -0.1;
> case KeyCode.RIGHT -> x = 0.1;
> case KeyCode.UP -> y = -0.1;
> case KeyCode.DOWN -> y = 0.1;
> case KeyCode.PAGE_UP -> y = -0.9;
> case KeyCode.PAGE_DOWN -> y = 0.9;
> case KeyCode.SPACE -> y = 0.9;
> case KeyCode.HOME -> x = y = Double.NEGATIVE_INFINITY;
> case KeyCode.END -> x = y = Double.POSITIVE_INFINITY;
> default -> {}
> }
>
> if (x != 0 || y != 0) {
> scrollByFraction(scrollPane, x, y);
> e.consume();
> }
> });
>
> Note that this doesn't exactly replicate the old behavior, but is probably a much more useful implementation than what was provided as standard before.
@hjohn In case you missed the notification, this is ready to integrate.
-------------
PR Comment: https://git.openjdk.org/jfx/pull/1582#issuecomment-2448697737
More information about the openjfx-dev
mailing list