JavaFX - 从线程实时更新线图
JavaFX - Realtime lineChart update from thread
在我的 JavaFX 应用程序中,我想显示来自后台线程的实时数据。有谁知道如何从后台线程更新折线图?谢谢你。下面是一些示例代码。
TM
Preview image
示例控制器
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.chart.LineChart;
import javafx.scene.control.Button;
public class SampleController {
@FXML
Button btnStart;
@FXML
Button btnStop;
@FXML
LineChart myChart;
Process process;
@FXML
public void initialize() {
process = new Process();
}
public void start(ActionEvent event) {
process.start();
}
public void stop(ActionEvent event) {
process.stop();
}
}
处理 class。启动线程。
public class Process {
private Task task = new Task();
public void start(){
task.start();
}
public void stop(){
task.kill();
}
}
任务class。执行任务的线程class
public class Task extends Thread {
private boolean isActive = true;
@Override
public void run() {
while (isActive) {
try {
// Simulate heavy processing stuff
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Add a new number to the linechart
// Remove first number of linechart
}
}
public void kill(){
isActive = false;
}
}
主要class
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.SampleController">
<children>
<Button fx:id="btnStart" mnemonicParsing="false" onAction="#start" text="Start" />
<LineChart fx:id="myChart">
<xAxis>
<CategoryAxis side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis side="LEFT" />
</yAxis>
</LineChart>
<Button fx:id="btnStop" mnemonicParsing="false" onAction="#stop"
text="Stop" />
</children>
</VBox>
您需要插入要在 UI 线程的折线图中显示的值。因此你可以简单地使用这样的东西:
public class Task extends Thread {
private boolean isActive = true;
private LineChart<String, Number> chart;
private Series<String, Number> series = new Series<>();
public Task(LineChart<CategoryAxis, NumberAxis> chart) {
this.chart.getData().add(series);
}
@Override
public void run() {
while (isActive) {
try {
// Simulate heavy processing stuff
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Platform.runLater(() -> {
// Add a new number to the linechart
this.series.getData().add(new Data<>("",0));
// Remove first number of linechart
this.series.getData().remove(0);
});
}
}
public void kill(){
isActive = false;
}
}
或者如果您想在添加和删除值后执行某些操作,请使用类似以下内容:
public class Task extends Thread {
private boolean isActive = true;
private LineChart<String, Number> chart;
private Series<String, Number> series = new Series<>();
public Task(LineChart<CategoryAxis, NumberAxis> chart) {
this.chart.getData().add(series);
}
@Override
public void run() {
while (isActive) {
try {
// Simulate heavy processing stuff
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
FutureTask<Object> task = new FutureTask<Object>(new Callable<Object>() {
@Override
public Object call() throws Exception {
// Add a new number to the linechart
series.getData().add(new Data<>("",0));
// Remove first number of linechart
series.getData().remove(0);
return true;
}
});
Platform.runLater(task);
try {
System.out.println(task.get());
//TODO after insertion
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
public void kill(){
isActive = false;
}
}
在我的 JavaFX 应用程序中,我想显示来自后台线程的实时数据。有谁知道如何从后台线程更新折线图?谢谢你。下面是一些示例代码。
TM
Preview image
示例控制器
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.chart.LineChart;
import javafx.scene.control.Button;
public class SampleController {
@FXML
Button btnStart;
@FXML
Button btnStop;
@FXML
LineChart myChart;
Process process;
@FXML
public void initialize() {
process = new Process();
}
public void start(ActionEvent event) {
process.start();
}
public void stop(ActionEvent event) {
process.stop();
}
}
处理 class。启动线程。
public class Process {
private Task task = new Task();
public void start(){
task.start();
}
public void stop(){
task.kill();
}
}
任务class。执行任务的线程class
public class Task extends Thread {
private boolean isActive = true;
@Override
public void run() {
while (isActive) {
try {
// Simulate heavy processing stuff
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Add a new number to the linechart
// Remove first number of linechart
}
}
public void kill(){
isActive = false;
}
}
主要class
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.SampleController">
<children>
<Button fx:id="btnStart" mnemonicParsing="false" onAction="#start" text="Start" />
<LineChart fx:id="myChart">
<xAxis>
<CategoryAxis side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis side="LEFT" />
</yAxis>
</LineChart>
<Button fx:id="btnStop" mnemonicParsing="false" onAction="#stop"
text="Stop" />
</children>
</VBox>
您需要插入要在 UI 线程的折线图中显示的值。因此你可以简单地使用这样的东西:
public class Task extends Thread {
private boolean isActive = true;
private LineChart<String, Number> chart;
private Series<String, Number> series = new Series<>();
public Task(LineChart<CategoryAxis, NumberAxis> chart) {
this.chart.getData().add(series);
}
@Override
public void run() {
while (isActive) {
try {
// Simulate heavy processing stuff
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Platform.runLater(() -> {
// Add a new number to the linechart
this.series.getData().add(new Data<>("",0));
// Remove first number of linechart
this.series.getData().remove(0);
});
}
}
public void kill(){
isActive = false;
}
}
或者如果您想在添加和删除值后执行某些操作,请使用类似以下内容:
public class Task extends Thread {
private boolean isActive = true;
private LineChart<String, Number> chart;
private Series<String, Number> series = new Series<>();
public Task(LineChart<CategoryAxis, NumberAxis> chart) {
this.chart.getData().add(series);
}
@Override
public void run() {
while (isActive) {
try {
// Simulate heavy processing stuff
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
FutureTask<Object> task = new FutureTask<Object>(new Callable<Object>() {
@Override
public Object call() throws Exception {
// Add a new number to the linechart
series.getData().add(new Data<>("",0));
// Remove first number of linechart
series.getData().remove(0);
return true;
}
});
Platform.runLater(task);
try {
System.out.println(task.get());
//TODO after insertion
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
public void kill(){
isActive = false;
}
}