当前位置: 首页 > 知识库问答 >
问题:

JavaFX-实时lineChart从线程更新

施琦
2023-03-14

在我的JavaFX应用程序中,我想显示来自后台线程的实时数据。有人知道如何从后台线程更新linechart吗?谢谢你。下面是一些示例代码。

TM的

预览图像

采样控制器

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();
    }

}

处理类。启动线程。

public class Process {

    private Task task = new Task();

    public void start(){
        task.start();
    }

    public void stop(){
        task.kill();
    }

}

任务类。执行任务的线程类

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;
    }

}

主类

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);
    }
}

样品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>

共有1个答案

宇文飞翮
2023-03-14

您需要从UI线程插入要在LineChart中显示的值。因此,你可以简单地使用这样的东西:

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和线程,并且遇到了这个问题,我制作了一个按钮,然后单击该按钮(使用事件处理程序)时,我做了一个for循环,将按钮更改为1,2,3,4 ,5,然后在每个中间延迟一秒钟。像倒计时! 但是发生的事情是延迟了5秒钟,并将按钮的文本更改为5。 问题是我希望看到它在1到5之间变化,但我看到的只是在5秒延迟结束时为5。我认为它会更改按钮文本,但看不到。我可能与类中的方法有关。

  • 我同时使用Javafx和线程,我经常遇到这个问题,我制作了一个按钮,然后当单击按钮时(使用事件处理程序),我制作了一个for循环,将按钮更改为1、2、3、4、5,然后在每个按钮中间延迟一秒钟。就像倒计时一样! 但实际情况是,它会延迟5秒钟,并将按钮的文本更改为5。 问题是我想看到它在1到5之间变化,但我看到的只是5秒延迟结束时的5。我假设它会更改按钮文本,但我看不到它。我可能不得不处理<代码>。在

  • 所以我要做的是,我要编写一个GUI来在LineChart上显示实时数据。到目前为止,我可以让linechart工作,但不能进入GUI。 使用scenebuilder,我制作了一个带有linechart对象的视图,以便将其链接到我生成的图表。但由于某些原因,这似乎不能与我的MainApp中的代码一起工作。 这只显示了带有空线程的视图。我知道图表应该知道然而,因为我可以使用它来创建一个场景,并显示到G

  • 问题内容: 我有一个javafx应用程序和一个工作线程,通过来实现,它执行一个漫长的过程,即压缩并上传一组文件。 我已通过将任务进度连接到进度条。 除此之外,我想将有关正在处理的项目的详细状态报告到ui中。 也就是说,正在处理的文件的名称及其大小以及单个文件处理可能引起的任何错误。 用这些信息更新UI不能从工作线程中完成,最多我可以将其添加到同步集合中。 但是然后我需要一些事件来通知UI新数据可用

  • 我有一个javafx应用程序和一个通过实现的工作线程,它执行一个很长的过程,即压缩和上载一组文件。 我已通过将任务进度连接到进度条。 除此之外,我还希望将正在处理的项的详细状态报告到UI中。即正在处理的文件的名称及其大小和单个文件进程可能产生的任何错误。 不能从辅助线程中使用这些信息更新UI,最多只能将其添加到同步集合中。 但我需要一些事件来通知UI新数据可用。 javafx是否对此问题有特定的支

  • 所以我在这个问题上有点卡住了。我有一个非常基本的游戏,你用箭头键在网格周围移动一艘船。 我添加了另一个线程与一些怪物,应该自动漫游网格。我可以从打印语句中看到线程正在运行怪物正在移动,但是,图像位置没有更新。 我发现了一些类似的问题,有很多建议可以使用。但我不确定它是否符合我的具体情况,如果符合,如何实施。 下面是怪物类正在做的事情,每秒将怪物向右移动一个空间。就像我提到的,每次调用时,我都会记录