--- old/modules/graphics/src/main/java/com/sun/javafx/css/StyleManager.java 2014-05-12 16:56:02.000000000 -0400 +++ new/modules/graphics/src/main/java/com/sun/javafx/css/StyleManager.java 2014-05-12 16:56:01.000000000 -0400 @@ -552,6 +552,27 @@ stylesheetRemoved(parent, fname); } } + + Iterator containerIterator = stylesheetContainerMap.values().iterator(); + while (containerIterator.hasNext()) { + StylesheetContainer container = containerIterator.next(); + container.parentUsers.remove(parent); + if (container.parentUsers.list.isEmpty()) { + + containerIterator.remove(); + + if (container.selectorPartitioning != null) { + container.selectorPartitioning.reset(); + } + + + // clean up image cache by removing images from the cache that + // might have come from this stylesheet + final String fname = container.fname; + cleanUpImageCache(fname); + } + } + // Do not iterate over children since this method will be called on each from Parent#scenesChanged } --- old/modules/graphics/src/test/java/com/sun/javafx/css/StyleManagerTest.java 2014-05-12 16:56:03.000000000 -0400 +++ new/modules/graphics/src/test/java/com/sun/javafx/css/StyleManagerTest.java 2014-05-12 16:56:03.000000000 -0400 @@ -127,7 +127,7 @@ sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css"); - assertEquals(0,index); + assertEquals(0, index); } @Test @@ -291,6 +291,25 @@ } @Test + public void testForgetParent_withStylesheets() { + + Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); + + StyleManager sm = StyleManager.getInstance(); + sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); + + int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); + assertEquals(0,index); + + sm.forget(scene.getRoot()); + + // forgetting the scene should not affect the platform user-agent stylesheets + index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); + assertEquals(0,index); + + } + + @Test public void testForgetParent_withSceneUAStylesheet() { Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); @@ -346,7 +365,7 @@ assertEquals(-1, index); index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); - assertEquals(0,index); + assertEquals(0, index); index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); assertEquals(-1, index); @@ -455,7 +474,7 @@ sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); - assertEquals(0,index); + assertEquals(0, index); index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); assertEquals(-1, index); @@ -551,7 +570,7 @@ sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); - assertEquals(0,index); + assertEquals(0, index); index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); assertEquals(-1, index); @@ -888,4 +907,55 @@ } + @Test + public void testRT_37025() { + + // + // The issue in RT-37025 was that the stylesheet container wasn't getting removed even + // though the parent had been forgotten. The StyleManager#forget(Parent) method didn't + // look to see if _any_ stylesheet container had the parent as a reference. + // + final StyleManager sm = StyleManager.getInstance(); + + // This test needs a bit more complexity to the scene-graph + Group group = null; + Pane pane = new Pane( + new Group( + new Pane( + // I want these to be a Parent, not a Node + new Group(new Pane(){{ getStyleClass().add("rect"); }}), + group = new Group(new Pane(){{ getStyleClass().add("rect"); }}) + ) + ) + ); + pane.getStylesheets().add("/com/sun/javafx/css/ua0.css"); + group.getStylesheets().add("/com/sun/javafx/css/ua1.css"); + + Group root = new Group(pane); + Scene scene = new Scene(root); + + root.applyCss(); + + assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css")); + StyleManager.StylesheetContainer container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua0.css"); + assertEquals(7, container.parentUsers.list.size()); + + assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css")); + container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua1.css"); + assertEquals(2, container.parentUsers.list.size()); + + ((Pane)group.getParent()).getChildren().remove(group); + + assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css")); + assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css")); + container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua0.css"); + assertEquals(5, container.parentUsers.list.size()); + + scene.setRoot(new Group()); + assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css")); + assertFalse(StyleManager.cacheContainerMap.containsKey(root)); + assertTrue(StyleManager.cacheContainerMap.containsKey(scene.getRoot())); + + } + }