On Fri, 20 Aug 2021 05:15:49 GMT, Michael Strauß <mstra...@openjdk.org> wrote:

>> This PR adds the `Node.focusVisible` and `Node.focusWithin` properties, as 
>> well as the corresponding `:focus-visible` and `:focus-within` CSS 
>> pseudo-classes.
>
> Michael Strauß has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   fixed undeterministic test failures

thanks for taking a closer look :) 

> > might also need a test that verifies the focusWithin of a parent added 
> > somewhere above the focused node? hmm .. or maybe not, that would require 
> > to re-arrange a complete subtree ..
> 
> Inserting a parent into a scene graph such that the existing subtree at that 
> position becomes a subtree of the newly inserted parent can't be done as an 
> atomic operation. First, you'll need to remove the subtree at the insertion 
> point from the existing scene graph (otherwise you'll get an exception saying 
> that a node can only appear once in a scene graph). Then you can add the new 
> parent with the removed subtree as its child.

yeah that's true, but might happen behind the scenes - we can move a focused 
node from one parent to another by simply adding it the new. 

So I'm not sure I would agree: 

> I'm inclined to think that this behavior is a bug.

arguable, though :) Below is an example of moving a focused node (button 
"Moving", the other is just for having something else that might get the focus) 
between 2 parents by F1: the button keeps its focused state in its new parent 
(and scene's focusOwner doesn't change) - I think that's what a user would 
expect also when dragging a focused node around (s/he might not even be aware 
of the hierarchy). I suspect that changing the behavior would break existing 
applications - except if it could be done completely transparently.

The example:

    private Parent createContent() {
        first = new VBox();
        first.setBackground(new Background(new BackgroundFill(Color.ALICEBLUE, 
null, null)));
        first.getChildren().add(new Label("label on first"));
        second = new VBox();
        second.setBackground(new Background(new BackgroundFill(Color.LAVENDER, 
null, null)));
        second.getChildren().add(new Label("label on second"));

        moving = new Button("moving");
        first.getChildren().add(moving);
        Button move = new Button("move");
        move.setOnAction(e -> {
            move();
        });
        move.setDefaultButton(true);
        HBox content = new HBox(10, first, second, move);
        content.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
            if (e.getCode() == KeyCode.F1) {
                move();
            }
        });
        return content;
    }

    private void move() {
        Parent parent = moving.getParent();
        Pane target = parent == first ? second : first;
        target.getChildren().add(moving);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Scene scene = new Scene(createContent(), 300, 300);
        scene.focusOwnerProperty().addListener((scr, ov, nv) -> {
            System.out.println("focusOwner: " + nv);
        });
        stage.setScene(scene);
        stage.show();
    }

    private VBox first;
    private VBox second;
    private Button moving;

-------------

PR: https://git.openjdk.java.net/jfx/pull/475

Reply via email to