javafxports / openjdk-jfx

The openjfx repo has moved to:
https://github.com/openjdk/jfx
GNU General Public License v2.0
1.01k stars 145 forks source link

Openjfx10 chart unrefresh in subscene #89

Open robbiezl opened 6 years ago

robbiezl commented 6 years ago

I write a JavaFX Demo to add a bar chart in Subscene and change the bar chart series value in KeyFrame in Timeline.

In JDK8, the bar chart graphic refresh correct,But in JDK 10,the bar chart graphic do not refresh.

I tried Platform.requestNextPulse,but it donot useful.

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Rectangle2D;
import javafx.scene.*;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.util.Duration;

public class HMIBrowserDemoTest extends Application {

private Scene backScene=new Scene(new Group());

SubScene subScene =null;

private Group picGroup=null;

public HMIBrowserDemoTest(){
    super();
}

private void initUI(Stage primaryStage) {

    Rectangle2D screenBounds=Screen.getPrimary().getBounds();
    primaryStage.setWidth(screenBounds.getWidth());
    primaryStage.setHeight(screenBounds.getHeight());
    primaryStage.centerOnScreen();

    primaryStage.setTitle("hmi.browser.title");

    primaryStage.setScene(backScene);

    Group rootGroup=(Group) backScene.getRoot();

    Group aa=new Group();
    aa.getChildren().add(createContent1());
    subScene =new SubScene(aa,800,700);
    subScene.setFill(Color.BEIGE);
    subScene.setManaged(false);

    rootGroup.getChildren().add(subScene);
}

@Override
public void start(Stage primaryStage) throws Exception {
    initUI(primaryStage);
    primaryStage.show();

    init1();
}

public static void main(String[] args) {
    System.out.println(System.getProperty("java.library.path"));
    launch(args);
}

private void init1(){
    Timeline tl = new Timeline();
    tl.getKeyFrames().add(
            new KeyFrame(Duration.millis(150),
                    new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent actionEvent) {
                            XYChart.Series series= (XYChart.Series) chart.getData().get(0);
                            int value= (int) (Math.random() * 5000);
                            XYChart.Data<String, Number> data= (XYChart.Data<String, Number>) series.getData().get(0);
                            System.out.println(value+"-----------");
                            data.setYValue(value);
                            subScene.toFront();
                        }
                    }
            ));
    tl.setCycleCount(Animation.INDEFINITE);
    tl.setAutoReverse(true);
    tl.play();
}

private BarChart chart;
private CategoryAxis xAxis;
private NumberAxis yAxis;
public Parent createContent1() {
    String[] years = {"2007", "2008", "2009"};
    xAxis = new CategoryAxis();
    xAxis.setCategories(FXCollections.<String>observableArrayList(years));
    yAxis = new NumberAxis("Units Sold", 0.0d, 3000.0d, 1000.0d);
    ObservableList<BarChart.Series> barChartData = FXCollections.observableArrayList(
            new BarChart.Series("Apples", FXCollections.observableArrayList(
                    new BarChart.Data(years[0], 567d),
                    new BarChart.Data(years[1], 1292d),
                    new BarChart.Data(years[2], 1292d)
            )),
            new BarChart.Series("Lemons", FXCollections.observableArrayList(
                    new BarChart.Data(years[0], 956),
                    new BarChart.Data(years[1], 1665),
                    new BarChart.Data(years[2], 2559)
            )),
            new BarChart.Series("Oranges", FXCollections.observableArrayList(
                    new BarChart.Data(years[0], 1154),
                    new BarChart.Data(years[1], 1927),
                    new BarChart.Data(years[2], 2774)
            ))
    );
    chart = new BarChart(xAxis, yAxis, barChartData, 25.0d);
    chart.setLayoutX(0);
    chart.setLayoutY(0);
    chart.setPrefSize(300,300);
    return chart;
}
}
kevinrushforth commented 6 years ago

This might be related to an issue that I discovered a while ago, but didn't get around to filing a bug against. I'll put this on my list to track down this week. If it turns out to be the same bug, then I'll create a bug in JBS with both this test program and mine attached. Otherwise, I'll create two bugs in JBS.

robbiezl commented 6 years ago

Dear @kevinrushforth,the bug still exist in OpenJFX Build 21 (2018/8/1) ,may I get the link of this bug report in JBS,so I can concen on it?

kevinrushforth commented 6 years ago

Sorry for the delay. This got buried in my queue, and I haven't filed a new bug yet. I see that you filed a bug via bugs.java.com with ID 9056532. As soon as it is transfered to the JDK project in JBS (probably tomorrow), it will be publicly visible and can be linked to this issue.

kevinrushforth commented 6 years ago

I wrote above:

This might be related to an issue that I discovered a while ago, but didn't get around to filing a bug against.

Since the chart refresh problem is in SubScene, it is probably not related to this other issue I mentioned above (that one affects ProgressIndicator in a Scene).

robbiezl commented 6 years ago

Thank you for your great work.

Now I temp used "chart.requestLayout()" after the chart data changed,it can refresh in SubScene.

kevinrushforth commented 6 years ago

The bug is now visible in JBS as JDK-8209172. I can update it to add the workaround you suggested above.