Java 使用JFreeChart的动态图表
我有一个100000个样本的数组,都是双类型的。我想显示或打印此数组,以便获得一个移动的图表/打印(动态),而不是立即显示它。有人能帮我吗。在图中,ee[]和y[]是经过一些处理后获得的Java 使用JFreeChart的动态图表,java,jfreechart,Java,Jfreechart,我有一个100000个样本的数组,都是双类型的。我想显示或打印此数组,以便获得一个移动的图表/打印(动态),而不是立即显示它。有人能帮我吗。在图中,ee[]和y[]是经过一些处理后获得的 private byte[] FileR(String filename) { byte[] data = null; AudioInputStream ais; try { File fileIn = new File(filename); if (fi
private byte[] FileR(String filename) {
byte[] data = null;
AudioInputStream ais;
try {
File fileIn = new File(filename);
if (fileIn.exists()) {
ais = AudioSystem.getAudioInputStream(fileIn);
data = new byte[ais.available()];
ais.read(data);
}
} catch (UnsupportedAudioFileException | IOException e) {
System.out.println(e.getMessage());
throw new RuntimeException("Could not read " + filename);
}
return data;
}
private byte[] Capture(double t) throws LineUnavailableException {
AudioFormat format = new AudioFormat(48000, 16, 2, true, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.open();
int size = (int) (line.getBufferSize() * t);
byte[] b = new byte[size];
line.start();
line.read(b, 0, size);
return b;
}
private void plot(double[] ee, double[] y) {
XYSeries see = new XYSeries("Filtered");
for (int i = 0; i < ee.length; i++) {
see.add(i, ee[i]);
}
XYSeriesCollection cee = new XYSeriesCollection();
cee.addSeries(see);
XYItemRenderer ree = new StandardXYItemRenderer();
NumberAxis rangeAxisee = new NumberAxis("Filtered");
XYPlot subplot1 = new XYPlot(cee, null, rangeAxisee, ree);
subplot1.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
XYSeries sy = new XYSeries("Noisy");
for (int i = 0; i < y.length; i++) {
sy.add(i, y[i]);
}
XYSeriesCollection cy = new XYSeriesCollection();
cy.addSeries(sy);
XYItemRenderer ry = new StandardXYItemRenderer();
NumberAxis rangeAxisy = new NumberAxis("Noisy");
XYPlot subplot2 = new XYPlot(cy, null, rangeAxisy, ry);
subplot2.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Domain"));
plot.setGap(10.0);
plot.add(subplot1);
plot.add(subplot2);
plot.setOrientation(PlotOrientation.VERTICAL);
JFreeChart chart = new JFreeChart("Adaptive Filter", JFreeChart.DEFAULT_TITLE_FONT, plot, true);
panel = new ChartPanel(chart, true, true, true, false, true);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(750, 500);
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
}
private byte[]文件管理器(字符串文件名){
字节[]数据=null;
音频输入流;
试一试{
File fileIn=新文件(文件名);
if(fileIn.exists()){
ais=AudioSystem.getAudioInputStream(fileIn);
数据=新字节[ais.available()];
ais.read(数据);
}
}捕获(不支持的数据文件异常| IOE异常){
System.out.println(e.getMessage());
抛出新的RuntimeException(“无法读取”+文件名);
}
返回数据;
}
私有字节[]捕获(双t)引发LineUnavailableException{
AudioFormat格式=新的AudioFormat(48000,16,2,真,假);
DataLine.Info=newdataline.Info(TargetDataLine.class,格式);
line=(TargetDataLine)AudioSystem.getLine(info);
行。打开(格式);
line.open();
int size=(int)(line.getBufferSize()*t);
字节[]b=新字节[大小];
line.start();
行。读取(b,0,大小);
返回b;
}
私有无效地块(双[]ee,双[]y){
XYSeries见=新XYSeries(“过滤”);
for(int i=0;i
您需要有一个线程,所有这些数据都来自该线程。例如,从您的后端。然后,每次有一组新的图表数据时,您都需要通过事件调度线程更新图表。如果你的图表数据是以固定的时间间隔出现的,这是相当容易的(例如拉动),但是如果是推式的(例如,数据更随机),可能会变得有点棘手
从plot方法中删除所有GUI创建:
JFreeChart chart = new JFreeChart("Adaptive Filter", JFreeChart.DEFAULT_TITLE_FONT, plot, true);
panel = new ChartPanel(chart, true, true, true, false, true);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(750, 500);
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
这只需要调用一次。每次出现新数据时,都会调用plot方法
以下是一个简单的方法:
public void startCharting() {
final MySoundCard card = new MySoundCard();
final MyJFreeChart chart = new MyJFreeChart();
Runnable r = new Runnable() {
@Override
public void run() {
while(true) {
int[] i = card.FileR();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
chart.plot();
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t = new Thread(r);
t.start();
}
线程每秒调用一次数据源,然后更新图表。更新是在事件调度线程中调用的。这是什么意思?你是说它在运行时会改变?动画?也许你正在寻找其中一种方法。奥利弗·沃特金斯,也许你已经知道我的问题了。“你能帮我个忙吗。@除非你使用
@
符号,否则奥利弗瓦特金斯可能看不到你的回答。”。在此期间,请编辑您的问题,以澄清它与此的区别。从音频文件接收或从声卡捕获的数据(样本阵列)。现在,我想以一种移动的方式(动态的,而不是时间序列)来显示它,而不是一次性显示。如果可能,请举例说明。首先,您的数据是如何进入您的应用程序的。你在调用一个方法吗?或者数据是在应用程序中以某种方式捕获的?@AbdulBaseerBuriro我添加了一些代码,这应该会让您有所了解。数据是通过方法调用获取的。一种方法是从文件中获取数据,另一种方法是从卡中获取数据。这取决于用户的选择。@AbdulBaseerBuriro您应该在问题中粘贴一些代码。真的帮不了你更多。