Я делаю приложение, в котором мне нужно показать на графике реальное время захвата определенных данных И он «работает», за исключением того, что он не поспевает за реальным временем, он продолжает считать, как будто время прошло! Я знаю, что он, возможно, связан с этим набором данных.advanceTime(), но без него график становится статичным и больше не продвигается, даже если проходит реальное время
package com.mycompany.moveplus;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.Date;
import java.util.TimeZone;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.DynamicTimeSeriesCollection;
import org.jfree.data.time.Second;
import org.jfree.data.xy.XYDataset;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;
public class Atol extends JInternalFrame {
private static final float MINMAX = 100;
private static final int COUNT = 2 * 60;
private Timer timer;
public Atol() {
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
Date date = new Date();
final DynamicTimeSeriesCollection dataset
= new DynamicTimeSeriesCollection(1, 60, new Second());
dataset.setTimeBase(new Second(date));
dataset.addSeries(gaussianData(), 0, "Uso de CPU");
JFreeChart chart = createChart(dataset);
this.add(new ChartPanel(chart), BorderLayout.CENTER);
JPanel btnPanel = new JPanel(new FlowLayout());
SystemInfo si = new SystemInfo(); //Criando uma nova classe de infos do Sistem
HardwareAbstractionLayer hal = si.getHardware(); //Infos de Hardware do sistema
CentralProcessor cpu = hal.getProcessor(); //E as informações da cpu
long[] oldTricks = cpu.getSystemCpuLoadTicks();
timer = new Timer(100, new ActionListener() {
float cpu() {
Double stats = cpu.getSystemCpuLoadBetweenTicks(oldTricks);
//Convertendo o valor de uso da CPU
stats = stats * 100d;
double teste = Math.round(stats * 100.0) / 100.0;
double d = teste;
float f = (float) d;
System.out.println(f);
return f;
}
float[] newData = new float[1];
@Override
public void actionPerformed(ActionEvent e) {
newData[0] = cpu();
// dataset.advanceTime();
dataset.appendData(newData);
}
});
timer.start();
}
private float[] gaussianData() {
float[] a = new float[COUNT];
for (int i = 0; i < a.length; i++) {
a[i] = 2;
}
return a;
}
private JFreeChart createChart(final XYDataset dataset) {
final JFreeChart result = ChartFactory.createTimeSeriesChart(
"", "hh:mm:ss", "CPU%", dataset, true, true, false);
final XYPlot plot = result.getXYPlot();
// DateAxis axis = (DateAxis) plot.getDomainAxis();
plot.setRangeGridlinePaint(Color.decode("#e8e8e8"));
plot.setBackgroundPaint(Color.white);
plot.setOutlinePaint(null);
plot.setOutlinePaint(null);
XYItemRenderer renderer = plot.getRenderer();
renderer.setSeriesPaint(0, Color.decode("#1b6ca8"));
ValueAxis domain = plot.getDomainAxis();
domain.setAutoRange(true);
ValueAxis range = plot.getRangeAxis();
range.setRange(0, MINMAX);
return result;
}
public void start() {
timer.start();
}
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Atol demo = new Atol();
demo.pack();
demo.setVisible(true);
demo.start();
}
});
}
}
как мне заставить его прогрессировать ТОЛЬКО тогда, когда время действительно проходит?
Я повторно использую этот код
Как было предложено здесь , javax.swing.Timer
хорошо работает при непрерывном синхронном сборе данных. Напротив, непрерывный асинхронный сбор данных может заблокировать поток GUI. Переключение на SwingWorker
, как показано здесь , дает возможность publish()
только при необходимости. В идеале выбранная вами библиотека может предложить подходящий обратный вызов, или вы можете просто дождаться поступления новых данных.
В любом случае в данных будут временные промежутки. Точные детали того, как вы справляетесь с этим, будут зависеть от вашего варианта использования, но я видел некоторые общие стратегии:
Используйте доступные функции для навигации по всему набору данных на диаграмме сигналов, как показано здесь , здесь и здесь ; используйте значения null
, как предложено здесь , чтобы прервать отображение, если это необходимо; пример проиллюстрирован здесь.
Разделите пакеты данных на отдельные наборы данных и добавьте элементы управления навигацией, как показано здесь и здесь.