我想弄清楚这一点,但我想我错过了一些东西。我已经了解How to Chart real time streaming data using AreaChart in JAVAFX 2 - Concurrency, Animation, Charting中提供的解决方案。但我真的尝试使用Task http://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html来完成实时图表。
我按照上面提到的javadoc中的示例,但是我没有得到数据生成(PartialResultsTask)和图表绘制之间的联系。目前我有以下设置:
控制器:
import javafx.scene.chart.XYChart;
public class FXMLDocumentController implements Initializable {
@FXML
private AreaChart<?, ?> areaChart;
private XYChart.Series serie;
@FXML
private void handleButtonAction(ActionEvent event) {
PartialResultsTask task = new PartialResultsTask();
serie = new XYChart.Series(task.getPartialResults());
areaChart.getData().clear();
areaChart.getData().add(serie);
Thread t = new Thread(task);
t.setDaemon(true);
t.start();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}
FXML
<?import java.lang.*?>
<?import javafx.scene.chart.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxconcurrenttest.FXMLDocumentController">
<children>
<AreaChart fx:id="areaChart" >
<xAxis>
<NumberAxis />
</xAxis>
<yAxis>
<NumberAxis side="LEFT" />
</yAxis>
</AreaChart>
<Button mnemonicParsing="false" onAction="#handleButtonAction" text="Button" />
</children>
</VBox>
应用
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class FXConcurrentTest extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
任务
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.scene.chart.XYChart;
public class PartialResultsTask extends Task<ObservableList<XYChart.Data>> {
// Uses Java 7 diamond operator
private ReadOnlyObjectWrapper<ObservableList> partialResults
= new ReadOnlyObjectWrapper<>(this, "partialResults",
FXCollections.observableArrayList(new ArrayList()));
public final ObservableList getPartialResults() {
return partialResults.get();
}
public final ReadOnlyObjectProperty partialResultsProperty() {
return partialResults.getReadOnlyProperty();
}
@Override
protected ObservableList call() throws Exception {
for (int i = 0; i < 100; i++) {
if (isCancelled()) {
break;
}
final Double latency = Math.random() * 100;
final Integer count = i;
Platform.runLater(() -> {
partialResults.get().add(new XYChart.Data<>(count, latency));
System.out.println("adding new Data:" +count +":" + latency);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(PartialResultsTask.class.getName()).log(Level.SEVERE, null, ex);
}
});
updateProgress(i, 100);
//didn't make a change
//updateValue(getPartialResults());
}
return partialResults.get();
}
}
我在System.out()
中添加了call()
,以便您可以看到ObservableList
正确更新,但图表仅在循环后绘制。我想要实现的是立即绘制新值&#34;。
非常感谢任何帮助。
提前致谢!
答案 0 :(得分:0)
您正在Thread.sleep()
内执行Platform.runLater()
。这意味着您将阻止FX应用程序线程,并且在整个循环完成之前不会给它重绘图表的机会。 (你在工作中睡觉:)。
你需要这个:
protected ObservableList<XYChart.Data<Number, Number>> call() throws Exception {
for (int i = 0; i < 100; i++) {
if (isCancelled()) {
break;
}
final Double latency = Math.random() * 100;
final Integer count = i;
Platform.runLater(() -> {
partialResults.get().add(new XYChart.Data<>(count, latency));
System.out.println("adding new Data:" +count +":" + latency);
});
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(PartialResultsTask.class.getName()).log(Level.SEVERE, null, ex);
}
updateProgress(i, 100);
//didn't make a change
//updateValue(getPartialResults());
}
return partialResults.get();
}