# HG changeset patch # User vadim # Date 1432661061 -10800 # Tue May 26 20:24:21 2015 +0300 # Node ID 510782e27bd61a8e3776fc017aea7e8abf068d91 # Parent 1c937f41f7a626df70999102d6225f7a43841007 RT-46086: StackedAreaChart doesn't fade out removed series diff --git a/modules/controls/src/main/java/javafx/scene/chart/AreaChart.java b/modules/controls/src/main/java/javafx/scene/chart/AreaChart.java --- a/modules/controls/src/main/java/javafx/scene/chart/AreaChart.java +++ b/modules/controls/src/main/java/javafx/scene/chart/AreaChart.java @@ -425,28 +425,7 @@ seriesYMultiplierMap.remove(series); // remove all symbol nodes if (shouldAnimate()) { - // create list of all nodes we need to fade out - final List nodes = new ArrayList(); - nodes.add(series.getNode()); - if (getCreateSymbols()) { // RT-22124 - // done need to fade the symbols if createSymbols is false - for (Data d: series.getData()) nodes.add(d.getNode()); - } - // fade out old and symbols - KeyValue[] startValues = new KeyValue[nodes.size()]; - KeyValue[] endValues = new KeyValue[nodes.size()]; - for (int j=0; j < nodes.size(); j++) { - startValues[j] = new KeyValue(nodes.get(j).opacityProperty(),1); - endValues[j] = new KeyValue(nodes.get(j).opacityProperty(),0); - } - Timeline tl = new Timeline(); - tl.getKeyFrames().addAll( - new KeyFrame(Duration.ZERO,startValues), - new KeyFrame(Duration.millis(400), actionEvent -> { - getPlotChildren().removeAll(nodes); - removeSeriesFromDisplay(series); - },endValues) - ); + Timeline tl = new Timeline(createSeriesRemoveTimeLine(series, 400)); tl.play(); } else { getPlotChildren().remove(series.getNode()); diff --git a/modules/controls/src/main/java/javafx/scene/chart/LineChart.java b/modules/controls/src/main/java/javafx/scene/chart/LineChart.java --- a/modules/controls/src/main/java/javafx/scene/chart/LineChart.java +++ b/modules/controls/src/main/java/javafx/scene/chart/LineChart.java @@ -448,28 +448,7 @@ // remove all symbol nodes seriesYMultiplierMap.remove(series); if (shouldAnimate()) { - // create list of all nodes we need to fade out - final List nodes = new ArrayList(); - nodes.add(series.getNode()); - if (getCreateSymbols()) { // RT-22124 - // done need to fade the symbols if createSymbols is false - for (Data d: series.getData()) nodes.add(d.getNode()); - } - // fade out old and symbols - KeyValue[] startValues = new KeyValue[nodes.size()]; - KeyValue[] endValues = new KeyValue[nodes.size()]; - for (int j=0; j < nodes.size(); j++) { - startValues[j] = new KeyValue(nodes.get(j).opacityProperty(),1); - endValues[j] = new KeyValue(nodes.get(j).opacityProperty(),0); - } - seriesRemoveTimeline = new Timeline(); - seriesRemoveTimeline.getKeyFrames().addAll( - new KeyFrame(Duration.ZERO,startValues), - new KeyFrame(Duration.millis(900), actionEvent -> { - getPlotChildren().removeAll(nodes); - removeSeriesFromDisplay(series); - },endValues) - ); + seriesRemoveTimeline = new Timeline(createSeriesRemoveTimeLine(series, 900)); seriesRemoveTimeline.play(); } else { getPlotChildren().remove(series.getNode()); diff --git a/modules/controls/src/main/java/javafx/scene/chart/StackedAreaChart.java b/modules/controls/src/main/java/javafx/scene/chart/StackedAreaChart.java --- a/modules/controls/src/main/java/javafx/scene/chart/StackedAreaChart.java +++ b/modules/controls/src/main/java/javafx/scene/chart/StackedAreaChart.java @@ -389,37 +389,8 @@ seriesYMultiplierMap.remove(series); // remove all symbol nodes if (shouldAnimate()) { - // create list of all nodes we need to fade out - final List nodes = new ArrayList(); - nodes.add(series.getNode()); - for (Data d: series.getData()) nodes.add(d.getNode()); - // fade out old and symbols - if (getCreateSymbols()) { - KeyValue[] startValues = new KeyValue[nodes.size()]; - KeyValue[] endValues = new KeyValue[nodes.size()]; - for (int j=0; j < nodes.size(); j++) { - startValues[j] = new KeyValue(nodes.get(j).opacityProperty(),1); - endValues[j] = new KeyValue(nodes.get(j).opacityProperty(),0); - } - Timeline tl = new Timeline(); - tl.getKeyFrames().addAll( - new KeyFrame(Duration.ZERO,startValues), - new KeyFrame(Duration.millis(400), actionEvent -> { - getPlotChildren().removeAll(nodes); - removeSeriesFromDisplay(series); - },endValues) - ); - tl.play(); - } else { - Timeline tl = new Timeline(); - tl.getKeyFrames().addAll( - new KeyFrame(Duration.millis(400), actionEvent -> { - getPlotChildren().removeAll(nodes); - removeSeriesFromDisplay(series); - }) - ); - tl.play(); - } + Timeline tl = new Timeline(createSeriesRemoveTimeLine(series, 400)); + tl.play(); } else { getPlotChildren().remove(series.getNode()); for (Data d:series.getData()) getPlotChildren().remove(d.getNode()); diff --git a/modules/controls/src/main/java/javafx/scene/chart/XYChart.java b/modules/controls/src/main/java/javafx/scene/chart/XYChart.java --- a/modules/controls/src/main/java/javafx/scene/chart/XYChart.java +++ b/modules/controls/src/main/java/javafx/scene/chart/XYChart.java @@ -925,6 +925,36 @@ } /** + * Creates an array of KeyFrames for fading out nodes representing a series + * + * @param series The series to remove + * @param fadeOutTime Time to fade out, in milliseconds + * @return array of two KeyFrames from zero to fadeOutTime + */ + protected final KeyFrame[] createSeriesRemoveTimeLine(Series series, long fadeOutTime) { + final List nodes = new ArrayList<>(); + nodes.add(series.getNode()); + for (Data d : series.getData()) { + if (d.getNode() != null) { + nodes.add(d.getNode()); + } + } + // fade out series node and symbols + KeyValue[] startValues = new KeyValue[nodes.size()]; + KeyValue[] endValues = new KeyValue[nodes.size()]; + for (int j = 0; j < nodes.size(); j++) { + startValues[j] = new KeyValue(nodes.get(j).opacityProperty(), 1); + endValues[j] = new KeyValue(nodes.get(j).opacityProperty(), 0); + } + return new KeyFrame[] { + new KeyFrame(Duration.ZERO, startValues), + new KeyFrame(Duration.millis(fadeOutTime), actionEvent -> { + getPlotChildren().removeAll(nodes); + removeSeriesFromDisplay(series); + }, endValues) + }; + } + /** * The current displayed data value plotted on the X axis. This may be the same as xValue or different. It is * used by XYChart to animate the xValue from the old value to the new value. This is what you should plot * in any custom XYChart implementations. Some XYChart chart implementations such as LineChart also use this diff --git a/modules/controls/src/test/java/javafx/scene/chart/AreaChartTest.java b/modules/controls/src/test/java/javafx/scene/chart/AreaChartTest.java --- a/modules/controls/src/test/java/javafx/scene/chart/AreaChartTest.java +++ b/modules/controls/src/test/java/javafx/scene/chart/AreaChartTest.java @@ -25,23 +25,15 @@ package javafx.scene.chart; - import com.sun.javafx.scene.control.infrastructure.ControlTestUtils; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Group; +import javafx.scene.Node; +import javafx.scene.shape.Path; +import static org.junit.Assert.assertEquals; +import org.junit.Ignore; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import javafx.collections.*; - - -import javafx.scene.Node; -import javafx.scene.Group; -import javafx.scene.shape.*; -import static org.junit.Assert.assertTrue; - -import org.junit.Ignore; - public class AreaChartTest extends XYChartTestBase { AreaChart ac; @@ -95,20 +87,55 @@ } return sb; } - + @Test public void testSeriesRemove() { startApp(); ac.getData().addAll(series1); pulse(); - if (!ac.getData().isEmpty()) { + // 5 symbols and 1 area group + assertEquals(6, ac.getPlotChildren().size()); + ac.getData().remove(0); + pulse(); + assertEquals(0, ac.getPlotChildren().size()); + } + + @Test + public void testSeriesRemoveWithoutSymbols() { + startApp(); + ac.setCreateSymbols(false); + ac.getData().addAll(series1); + pulse(); + // 1 area group + assertEquals(1, ac.getPlotChildren().size()); + ac.getData().remove(0); + pulse(); + assertEquals(0, ac.getPlotChildren().size()); + } + + @Test + public void testSeriesRemoveWithoutSymbolsAnimated_rt_22124() { + startApp(); + ac.setCreateSymbols(false); + ac.getData().addAll(series1); + pulse(); + // 1 area group + assertEquals(1, ac.getPlotChildren().size()); + + ac.setAnimated(true); + Thread.UncaughtExceptionHandler exceptionHandler = ControlTestUtils.setHandler(); + try { ac.getData().remove(0); - pulse(); - StringBuffer sb = getSeriesLineFromPlot(); - assertEquals(sb.toString(), ""); + } finally { + ControlTestUtils.resetHandler(exceptionHandler); } + toolkit.setAnimationTime(200); + assertEquals(1, ac.getPlotChildren().size()); + assertEquals(0.5, ac.getPlotChildren().get(0).getOpacity(), 0.0); + toolkit.setAnimationTime(400); + assertEquals(0, ac.getPlotChildren().size()); } - + @Test @Ignore public void testDataItemRemove() { startApp(); @@ -128,7 +155,7 @@ startApp(); useCategoryAxis = false; } - + @Test public void testCreateSymbols() { startApp(); ac.getData().clear(); diff --git a/modules/controls/src/test/java/javafx/scene/chart/LineChartTest.java b/modules/controls/src/test/java/javafx/scene/chart/LineChartTest.java --- a/modules/controls/src/test/java/javafx/scene/chart/LineChartTest.java +++ b/modules/controls/src/test/java/javafx/scene/chart/LineChartTest.java @@ -25,31 +25,16 @@ package javafx.scene.chart; -/** - * - * @author paru - */ +import com.sun.javafx.scene.control.infrastructure.ControlTestUtils; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.shape.Path; +import static org.junit.Assert.assertEquals; +import org.junit.Ignore; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import javafx.collections.*; - -import com.sun.javafx.pgstub.StubToolkit; -import com.sun.javafx.tk.Toolkit; - -import javafx.scene.Node; -import javafx.scene.Scene; -import javafx.scene.Group; -import javafx.stage.Stage; -import javafx.scene.shape.*; - -import org.junit.Ignore; - public class LineChartTest extends XYChartTestBase { - private Scene scene; - private StubToolkit toolkit; - private Stage stage; LineChart lineChart; final XYChart.Series series1 = new XYChart.Series(); @@ -81,38 +66,72 @@ } return sb; } - - @Test - public void testSeriesRemoveWithCreateSymbolsFalse() { + + @Test + public void testSeriesRemove() { startApp(); lineChart.getData().addAll(series1); pulse(); + // 5 symbols and 1 line node + assertEquals(6, lineChart.getPlotChildren().size()); + lineChart.getData().remove(0); + pulse(); + assertEquals(0, lineChart.getPlotChildren().size()); + } + + @Test + public void testSeriesRemoveWithoutSymbols() { + startApp(); lineChart.setCreateSymbols(false); - System.out.println("Line Path = "+getSeriesLineFromPlot()); - if (!lineChart.getData().isEmpty()) { + lineChart.getData().addAll(series1); + pulse(); + // 1 line node + assertEquals(1, lineChart.getPlotChildren().size()); + lineChart.getData().remove(0); + pulse(); + assertEquals(0, lineChart.getPlotChildren().size()); + } + + @Test + public void testSeriesRemoveWithoutSymbolsAnimated_rt_22124() { + startApp(); + lineChart.setCreateSymbols(false); + lineChart.getData().addAll(series1); + pulse(); + // 1 line node + assertEquals(1, lineChart.getPlotChildren().size()); + + lineChart.setAnimated(true); + Thread.UncaughtExceptionHandler exceptionHandler = ControlTestUtils.setHandler(); + try { lineChart.getData().remove(0); - pulse(); - StringBuffer sb = getSeriesLineFromPlot(); - assertEquals(sb.toString(), ""); + } finally { + ControlTestUtils.resetHandler(exceptionHandler); } + toolkit.setAnimationTime(450); + assertEquals(1, lineChart.getPlotChildren().size()); + assertEquals(0.5, lineChart.getPlotChildren().get(0).getOpacity(), 0.0); + toolkit.setAnimationTime(900); + assertEquals(0, lineChart.getPlotChildren().size()); } - - @Test public void testCreateSymbols() { - startApp(); - lineChart.setCreateSymbols(false); - pulse(); - lineChart.getData().addAll(series1); - pulse(); - assertEquals(0, countSymbols(lineChart, "chart-line-symbol")); - - lineChart.getData().clear(); - pulse(); - lineChart.setCreateSymbols(true); - pulse(); - lineChart.getData().addAll(series1); - assertEquals(5, countSymbols(lineChart, "chart-line-symbol")); - } - + + @Test + public void testCreateSymbols() { + startApp(); + lineChart.setCreateSymbols(false); + pulse(); + lineChart.getData().addAll(series1); + pulse(); + assertEquals(0, countSymbols(lineChart, "chart-line-symbol")); + + lineChart.getData().clear(); + pulse(); + lineChart.setCreateSymbols(true); + pulse(); + lineChart.getData().addAll(series1); + assertEquals(5, countSymbols(lineChart, "chart-line-symbol")); + } + @Test public void testDataItemAdd() { startApp(); diff --git a/modules/controls/src/test/java/javafx/scene/chart/StackedAreaChartTest.java b/modules/controls/src/test/java/javafx/scene/chart/StackedAreaChartTest.java --- a/modules/controls/src/test/java/javafx/scene/chart/StackedAreaChartTest.java +++ b/modules/controls/src/test/java/javafx/scene/chart/StackedAreaChartTest.java @@ -25,23 +25,15 @@ package javafx.scene.chart; - import com.sun.javafx.scene.control.infrastructure.ControlTestUtils; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Group; +import javafx.scene.Node; +import javafx.scene.shape.Path; +import static org.junit.Assert.assertEquals; +import org.junit.Ignore; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import javafx.collections.*; - - -import javafx.scene.Node; -import javafx.scene.Group; -import javafx.scene.shape.*; -import static org.junit.Assert.assertTrue; - -import org.junit.Ignore; - public class StackedAreaChartTest extends XYChartTestBase { StackedAreaChart ac; @@ -106,20 +98,55 @@ assertEquals("L219.0 58.0 L263.0 173.0 L438.0 173.0 L700.0 289.0 ", sb.toString()); } - + @Test public void testSeriesRemove() { startApp(); ac.getData().addAll(series1); pulse(); - if (!ac.getData().isEmpty()) { + // 5 symbols and 1 area group + assertEquals(6, ac.getPlotChildren().size()); + ac.getData().remove(0); + pulse(); + assertEquals(0, ac.getPlotChildren().size()); + } + + @Test + public void testSeriesRemoveWithoutSymbols() { + startApp(); + ac.setCreateSymbols(false); + ac.getData().addAll(series1); + pulse(); + // 1 area group + assertEquals(1, ac.getPlotChildren().size()); + ac.getData().remove(0); + pulse(); + assertEquals(0, ac.getPlotChildren().size()); + } + + @Test + public void testSeriesRemoveWithoutSymbolsAnimated_rt_22124() { + startApp(); + ac.setCreateSymbols(false); + ac.getData().addAll(series1); + pulse(); + // 1 area group + assertEquals(1, ac.getPlotChildren().size()); + + ac.setAnimated(true); + Thread.UncaughtExceptionHandler exceptionHandler = ControlTestUtils.setHandler(); + try { ac.getData().remove(0); - pulse(); - StringBuffer sb = getSeriesLineFromPlot(); - assertEquals(sb.toString(), ""); + } finally { + ControlTestUtils.resetHandler(exceptionHandler); } + toolkit.setAnimationTime(200); + assertEquals(1, ac.getPlotChildren().size()); + assertEquals(0.5, ac.getPlotChildren().get(0).getOpacity(), 0.0); + toolkit.setAnimationTime(400); + assertEquals(0, ac.getPlotChildren().size()); } - + @Test @Ignore public void testDataItemRemove() { startApp();