diff --git a/gradle.properties b/gradle.properties index 1243ed23..3e51dd87 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ JPRO_VERSION = 2026.2.0 -JAVAFX_BUILD_VERSION = 17.0.18 +JAVAFX_BUILD_VERSION = 25.0.2 JAVAFX_EXAMPLES_VERSION = 23.0.2 JAVAFX_25_VERSION = 25.0.2 SIMPLEFX_VERSION = 3.3.3 @@ -34,7 +34,7 @@ ASSERTJ_VERSION = 3.27.7 HAMCREST_VERSION = 3.0 MOCKITO_VERSION = 5.21.0 TESTFX_VERSION = 4.0.18-jpms -MONOCLE_VERSION = jfx-21-sandec +MONOCLE_VERSION = jfx-25-sandec SLF4J_API_VERSION = 2.0.17 LOGBACK_VERSION = 1.5.32 diff --git a/jpro-routing/core-test/src/test/scala/one/jpro/platform/routing/crawl/TestMemoryTester.scala b/jpro-routing/core-test/src/test/scala/one/jpro/platform/routing/crawl/TestMemoryTester.scala index d15c3a2c..5c964a39 100644 --- a/jpro-routing/core-test/src/test/scala/one/jpro/platform/routing/crawl/TestMemoryTester.scala +++ b/jpro-routing/core-test/src/test/scala/one/jpro/platform/routing/crawl/TestMemoryTester.scala @@ -51,6 +51,25 @@ class TestMemoryTester { } + // Mirrors jpro-website CheckForLeaks.routeWithLeaf: same shape, only the "/x" leaf differs. + private def routeWithLeaf(leaf: () => javafx.scene.Node): () => Route = () => + Route.empty() + .and(Route.get("/", r => { + val link = new javafx.scene.control.Label("to x") + one.jpro.platform.routing.LinkUtil.setLink(link, "/x", "desc") + Response.node(new javafx.scene.layout.VBox(link)) + })) + .and(Route.get("/x", r => Response.node(leaf()))) + + private def crawlAndCheck(route: () => Route): Unit = { + val result = AppCrawler.crawlRoute("http://localhost", () => route()) + MemoryTester.testForLeaks(result, () => route()) + } + + @Test + def textFlowLeakTest(): Unit = + crawlAndCheck(routeWithLeaf(() => new javafx.scene.text.TextFlow(new javafx.scene.text.Text("hello world")))) + @Test def simpleFailingTest3(): Unit = { diff --git a/jpro-routing/core/src/main/scala/one/jpro/platform/routing/sessionmanager/SessionManagerDesktop.scala b/jpro-routing/core/src/main/scala/one/jpro/platform/routing/sessionmanager/SessionManagerDesktop.scala index c4795ce9..7ee3ea67 100644 --- a/jpro-routing/core/src/main/scala/one/jpro/platform/routing/sessionmanager/SessionManagerDesktop.scala +++ b/jpro-routing/core/src/main/scala/one/jpro/platform/routing/sessionmanager/SessionManagerDesktop.scala @@ -39,7 +39,12 @@ class SessionManagerDesktop(val webApp: RouteNode) extends SessionManager { THIS page.url = url isFullscreen = page.fullscreen + // JFX removed-children retention workaround: swap while the container is not tree-visible + // so Parent skips adding the old page to the NG peer's removed-list (which a broken/absent + // render pulse would otherwise never clear). + container.setVisible(false) container.children = List(page.realContent) + container.setVisible(true) scrollpane.vvalue = 0.0 if(oldView != null && oldView != page) { oldView.onClose()