Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -991,10 +991,13 @@ boolean isPerformingLayout() {
private double minHeightCache = -1;

void setLayoutFlag(LayoutFlags flag) {
// Needs to be set before needsLayout is updated, as otherwise a listener that
// calls isNeedsLayout() might see the old value.
layoutFlag = flag;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the right change, but I suspect it might cause regression.

The JavaFX entities which call isNeedsLayout():

VirtualFlow::layoutChildren
VirtualFlow::setCellIndex

We may need to focus on List/Table/Tree/TableViews during testing.

(Anecdata: I've seen continuous layout calls in the TableView before)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's very unlikely to cause regressions, because needsLayoutProperty() is not used anywhere in JavaFX. The only thing that is different now is that a listener added to this property will see the correct value when calling isNeedsLayout().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are probably right, re:javafx. applications might listen to this property, though it's rather unlikely.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I don't think there's anything we can do about it short of not fixing the bug...


if (needsLayout != null) {
needsLayout.set(flag == LayoutFlags.NEEDS_LAYOUT);
}
layoutFlag = flag;
}

private void markDirtyLayout(boolean local, boolean forceParentLayout) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -45,6 +45,10 @@ public static <E extends Node> List<E> getManagedChildren(Parent p) {
return p.getManagedChildren();
}

public static void setNeedsLayout(Parent p, boolean value) {
p.setNeedsLayout(value);
}

public static List<Node> test_getRemoved(Parent p) {
return p.test_getRemoved();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertThrows;

Expand Down Expand Up @@ -520,6 +521,23 @@ public void needsLayoutPropertyIsReadOnly() {
() -> { var _ = (Property<Boolean>)new Group().needsLayoutProperty(); });
}

@Test
public void isNeedsLayoutReturnsCorrectValueInListener() {
var g = new Group();
g.layout();
assertFalse(g.isNeedsLayout());

boolean[] flags = new boolean[2];
g.needsLayoutProperty().subscribe(value -> {
flags[0] = value;
flags[1] = g.isNeedsLayout();
});

ParentShim.setNeedsLayout(g, true);
assertTrue(flags[0]);
assertTrue(flags[1]);
}

private static class LGroup extends Group {

private boolean layoutCalled;
Expand Down