【问题标题】:Why javafx8 UI thread is behaving strangely inside a change listner?为什么 javafx UI 线程在更改侦听器中表现异常?
【发布时间】:2017-05-25 19:37:09
【问题描述】:

我正在根据通过选择框提供的用户输入创建条形图。在选择框更改侦听器中,我首先创建了一个数据系列,然后创建了条形图。但是,图表无法正确呈现,即有时没有柱状图,有时柱状图的长度与数据不同。但是,当我通过让 UI 线程进入睡眠状态来在数据创建和图表创建之间添加一个短暂的延迟时,它可以正常工作。

我的问题是,为什么会这样?为什么 UI 线程在创建图表之前不等待数据创建过程完成?有没有办法在不增加延迟的情况下做到这一点?下面是更改监听器的代码 sn-p。

numberOfBars.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
   createData(newValue);
   // It works fine if I add Thread.sleep(1000) here. Why?
   createBarChart();
});

完整代码如下:

public class Main extends Application {
    private XYChart.Series<String, Number> data = new XYChart.Series<>();
    private VBox vBox = new VBox();
    private Pane bcContainer = new Pane();
    @Override public void start(Stage stage){
        ChoiceBox<Integer> numberOfBars = new ChoiceBox<>();
        ObservableList<Integer> items = FXCollections.observableArrayList(5, 10);
        numberOfBars.setItems(items);
        vBox.getChildren().addAll(new Label("Number of bars: "), numberOfBars, new Separator(), bcContainer);
        numberOfBars.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            createData(newValue);
            // It works fine if I add Thread.sleep(1000) here. Why?
            createBarChart();
        });
        Scene scene  = new Scene(vBox,800,600);
        stage.setScene(scene);
        stage.show();
    }
    private void createData(int bars){
        ObservableList<XYChart.Data<String, Number>> observableList = FXCollections.observableArrayList();
        for (int i=0; i<bars; i++) {
            observableList.add(new XYChart.Data<>("bar" + Integer.toString(i), i+1));
        }
        data.setData(observableList);
    }
    private void createBarChart(){
        BarChart<String, Number> barChart= new BarChart<>(new CategoryAxis(), new NumberAxis());
        barChart.setLegendVisible(false);
        barChart.setPrefSize(800, 500);
        barChart.getData().add(data);
        bcContainer.getChildren().clear();
        bcContainer.getChildren().add(barChart);
    }
    public static void main(String[] args) {
        launch(args);
    }
}

【问题讨论】:

    标签: java multithreading javafx javafx-8


    【解决方案1】:

    这看起来像一个错误...(在 Chart API 中,我并不完全感到惊讶)。

    如果您关闭动画,它似乎可以正常工作。打电话

    barChart.setAnimated(false);
    

    创建条形图后立即。

    【讨论】:

    • 感谢 James_D,你让我开心。我花了两天时间弄清楚为什么这到底是行不通的。非常感谢。
    猜你喜欢
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 2015-01-08
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多