gpt4 book ai didi

java - 实时面积图应用

转载 作者:太空宇宙 更新时间:2023-11-04 13:59:13 25 4
gpt4 key购买 nike

我从 stackoverflow 中获取了以下代码,当应用程序开始运行时,动态面积图正在更新,几秒钟后应用程序挂起(即窗口的最小化、最大化、关闭按钮在增加窗口大小后不起作用)。但面积图正在更新。

package areachartsample;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.AnimationTimer;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.stage.Stage;


public class AreaChartSample extends Application {
private static final int MAX_DATA_POINTS = 50;

private Series series;
private int xSeriesData = 0;
private ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<Number>();
private ExecutorService executor;
private AddToQueue addToQueue;
private Timeline timeline2;
private NumberAxis xAxis;

private void init(Stage primaryStage) {
xAxis = new NumberAxis(0,MAX_DATA_POINTS,MAX_DATA_POINTS/10);
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(false);

NumberAxis yAxis = new NumberAxis();
yAxis.setAutoRanging(true);

//-- Chart
final AreaChart<Number, Number> sc = new AreaChart<Number, Number>(xAxis, yAxis) {
// Override to remove symbols on each data point
@Override protected void dataItemAdded(Series<Number, Number> series, int itemIndex, Data<Number, Number> item) {}
};
sc.setAnimated(false);
sc.setId("liveAreaChart");
sc.setTitle("Animated Area Chart");

//-- Chart Series
series = new AreaChart.Series<Number, Number>();
series.setName("Area Chart Series");
sc.getData().add(series);

primaryStage.setScene(new Scene(sc));
}

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

//-- Prepare Executor Services
executor = Executors.newCachedThreadPool(new ThreadFactory() {
@Override public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
addToQueue = new AddToQueue();
executor.execute(addToQueue);
//-- Prepare Timeline
prepareTimeline();
}

public static void main(String[] args) {
launch(args);
}

private class AddToQueue implements Runnable {
public void run() {
try {
// add a item of random data to queue
dataQ.add(Math.random());
Thread.sleep(50);
executor.execute(this);
} catch (InterruptedException ex) {
Logger.getLogger(AreaChartSample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

//-- Timeline gets called in the JavaFX Main thread
private void prepareTimeline() {
// Every frame to take any data from queue and add to chart
new AnimationTimer() {
@Override public void handle(long now) {
addDataToSeries();
}
}.start();
}

private void addDataToSeries() {
for (int i = 0; i < 20; i++) { //-- add 20 numbers to the plot+
if (dataQ.isEmpty()) break;
series.getData().add(new AreaChart.Data(xSeriesData++, dataQ.remove()));
}
// remove points to keep us at no more than MAX_DATA_POINTS
if (series.getData().size() > MAX_DATA_POINTS) {
series.getData().remove(0, series.getData().size() - MAX_DATA_POINTS);
}
// update
xAxis.setLowerBound(xSeriesData-MAX_DATA_POINTS);
xAxis.setUpperBound(xSeriesData-1);
}
}

最佳答案

我为您创建了一个示例。它使用时间线进行图表更新。

import java.util.List;
import java.util.Random;

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.SequentialTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.stage.Stage;
import javafx.util.Duration;

public class LiveAreaChartApp extends Application {

private static int MAX_DATA_POINTS = 10;
private static int Y_DATA_RANGE = 100;
private static int TICK_UNIT = 10;

private static int UPDATE_INTERVAL_MS = 100;

private AreaChart.Series<Number, Number> series1;
private AreaChart.Series<Number, Number> series2;
private AreaChart<Number, Number> areaChart;
private NumberAxis xAxis = new NumberAxis();
private NumberAxis yAxis = new NumberAxis();

private SequentialTransition animation;

private double nextX = 0;

Random rnd = new Random();

public LiveAreaChartApp() {

Timeline timeline = new Timeline();
timeline.getKeyFrames().add(new KeyFrame(Duration.millis( UPDATE_INTERVAL_MS), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {

// update chart data
// note that we add one data point and remove one data point in this simple example.
// in a production environment you'd have to add multiple and remove multiple data points

// add new points
series1.getData().add(new XYChart.Data<Number, Number>(nextX, Math.sin(Math.toRadians(nextX)) * Y_DATA_RANGE));
series2.getData().add(new XYChart.Data<Number, Number>(nextX, Math.cos(Math.toRadians(nextX)) * Y_DATA_RANGE));

// remove points that shouldn't be visible anymore
if (series1.getData().size() > MAX_DATA_POINTS) {
series1.getData().remove(0);
}
if (series2.getData().size() > MAX_DATA_POINTS) {
series2.getData().remove(0);
}

nextX += 10;

// update using series 1 as reference
// series 2 contains same amount of data; if it doesn't for your case,
// you need to adapt this here and calculate the proper range
List<Data<Number, Number>> data = series1.getData();
xAxis.setLowerBound(data.get(0).getXValue().doubleValue());
xAxis.setUpperBound(data.get(data.size() - 1).getXValue().doubleValue());

}
}));
timeline.setCycleCount(Animation.INDEFINITE);

animation = new SequentialTransition();
animation.getChildren().addAll(timeline);
}

public Parent createContent() {
xAxis = new NumberAxis();
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(false);
xAxis.setTickLabelsVisible(false);
xAxis.setTickMarkVisible(false);
xAxis.setMinorTickVisible(false);

yAxis = new NumberAxis(-Y_DATA_RANGE, Y_DATA_RANGE, TICK_UNIT);
yAxis.setAutoRanging(false);

areaChart = new AreaChart<>(xAxis, yAxis);
areaChart.setAnimated(false);
areaChart.setLegendVisible(false);

series1 = new AreaChart.Series<>();
series1.getData().add(new AreaChart.Data<Number, Number>(0d, 0d));
areaChart.getData().add(series1);

series2 = new AreaChart.Series<>();
series2.getData().add(new AreaChart.Data<Number, Number>(0d, 0d));
areaChart.getData().add(series2);

return areaChart;
}

public void play() {
animation.play();
}

@Override
public void stop() {
animation.pause();
}

@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(createContent()));
primaryStage.show();
play();
}

public static void main(String[] args) {
launch(args);
}
}

关于java - 实时面积图应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29484803/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com