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