快速绘制多个图形的时序问题 [英] Timing issue with plotting multiple graphs fast
问题描述
在下面的代码中,我正在进行一个实验,我需要绘制几乎10个图形每秒(时间间隔100),共50个。但是,当我减少时间间隔 TIME INTERVAL 线120向下到底部)从200毫秒到100毫秒,代码引起异常如下。
我累了invokeLater等,但我不能解决这个问题。我在这里粘贴生成下面的图表的整个代码。请看看,让我知道该怎么办。提前感谢
线程中的异常AWT-EventQueue-0java.lang.IllegalArgumentException:系列索引超出范围
at org.jfree.data.xy.XYSeriesCollection.getSeries(XYSeriesCollection.java:261)
at org.jfree.data.xy.XYSeriesCollection.getSeriesKey(XYSeriesCollection.java:303)
在org .jfree.chart.labels.AbstractXYItemLabelGenerator.createItemArray(AbstractXYItemLabelGenerator.java:268)
at org.jfree.chart.labels.AbstractXYItemLabelGenerator.generateLabelString(AbstractXYItemLabelGenerator.java:238)
at org.jfree.chart .labels.StandardXYToolTipGenerator.generateToolTip(StandardXYToolTipGenerator.java:165)
at org.jfree.chart.renderer.xy.AbstractXYItemRenderer.addEntity(AbstractXYItemRenderer.java:1747)
at org.jfree.chart.renderer .xy.XYLineAndShapeRenderer.drawSecondaryPass(XYLineAndShapeRenderer.java:1196)
at org.jfree.chart.renderer.xy.XYLineAndShapeRenderer.drawItem(XYLineAndShapeRenderer.java:918)
at org.jfree.chart.plot .XYPlot.render(XYPlot.java:3776)
at org.jfree.chart.plot.XYPlot.draw(XYPlot.java:3337)
at org.jfree.chart.JFreeChart.draw(JFreeChart .java:1226)
at org.jfree.chart.ChartPanel.paintComponent(ChartPanel.java:1612)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
在javax.swing.RepaintManager $ PaintManager.paintDoubleBuffered(RepaintManager.java:1508)
在javax.swing.RepaintManager $ PaintManager.paint( RepaintManager.java:1439)
在javax.swing.RepaintManager.paint(RepaintManager.java:1236)
在javax.swing.JComponent._paintImmediately(JComponent.java:5169)
在javax .swing.JComponent.paintImmediately(JComponent.java:4980)
在javax.swing.RepaintManager $ 3.run(RepaintManager.java:796)
在javax.swing.RepaintManager $ 3.run(RepaintManager.java :784)
在java.security.AccessController.doPrivileged(本地方法)
在java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76)
在javax.swing.RepaintManager。 paintDirtyRegions(RepaintManager.java:784)
在javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:757)
在javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:706)
在javax.swing.RepaintManager.access $ 1000(RepaintManager.java:62)
在javax.swing.RepaintManager $ ProcessingRunnable.run(RepaintManager.java:1647)
在java.awt.event.InvocationEvent。 dispatch(InvocationEvent.java:251)
在java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
在java.awt.EventQueue.access $ 200(EventQueue.java:103)
在java.awt.EventQueue $ 3.run(EventQueue.java:694)
在java.awt.EventQueue $ 3.run(EventQueue.java:692)
在java.security.AccessController.doPrivileged Native方法)
在java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76)
在java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
在java.awt .EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
在java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
在java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
在java.awt.EventDispatchThread.run EventDispatchThread.java:91)
import java.awt.BorderLayout;
import java.awt.color;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart。*;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
public class FastChart extends JFrame {
private XYSeries [] xySeries;
private XYPlot xyPlot;
private XYSeriesCollection xySeriesCollection;
private String title;
private ChartPanel chartPanel;
public FastChart(String s){
super(s);
init(s);
}
private void init(String s){
title = s;
xySeries = new XYSeries [12];
for(int i = 0; i xySeries [i] = new XYSeries(Plot+ i);
}
xySeriesCollection = new XYSeriesCollection();
JFreeChart chart = ChartFactory.createScatterPlot(
title,X,Y,xySeriesCollection,
PlotOrientation.VERTICAL,true,true,false);
xyPlot = chart.getXYPlot();
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
chartPanel = createChartPanel(chart);
add(chartPanel,BorderLayout.CENTER);
JPanel control = new JPanel();
add(control,BorderLayout.SOUTH);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private ChartPanel createChartPanel(JFreeChart chart){
XYItemRenderer renderer = xyPlot.getRenderer();
renderer.setSeriesPaint(0,Color.magenta);
renderer.setSeriesPaint(1,Color.green);
renderer.setSeriesPaint(2,Color.blue);
renderer.setSeriesPaint(4,Color.black);
renderer.setSeriesPaint(3,Color.yellow);
Shape cross = ShapeUtilities.createDiagonalCross(3,0);
Shape plus = ShapeUtilities.createRegularCross(4,0);
for(int i = 0; i <= 3; i ++){
renderer.setSeriesShape(0 + i,new Rectangle(-1,-1,2,2)) ;
renderer.setSeriesShape(4 + i,new Ellipse2D.Float(-2F,-2F,5F,5F));
renderer.setSeriesShape(8 + i,cross);
}
// X轴
NumberAxis domain =(NumberAxis)xyPlot.getDomainAxis();
domain.setVerticalTickLabels(true);
// Y轴
return new ChartPanel(chart);
}
public void plot2d(final int iSeriesN,final double [] dX,final double [] dY,final String sT){
if(dY.length!= dX.length){
throw new IllegalArgumentException(Error!inputs x and y have to be same size。
}
chartPanel.getChart()。removeChangeListener((ChartChangeListener)chartPanel);
xySeries [iSeriesN] .clear();
xySeriesCollection.removeAllSeries();
xySeries [iSeriesN] = addXY(iSeriesN,dX,dY);
xySeries [iSeriesN] .setKey(sT);
for(int i = 0; i xySeriesCollection.addSeries(xySeries [i]);
}
chartPanel.getChart()。addChangeListener((ChartChangeListener)chartPanel);
xyPlot.setDataset(xySeriesCollection);
}
public XYSeries addXY(final int iSeriesN,final double [] dX,final double [] dY){
XYSeries series = new XYSeries(Plot);
for(int i = 0; i series.add(dX [i],dY [i]);
}
return series;
}
public void animatePlot(){
线程线程= null;
thread = new Thread(){
public void run(){
final double [] x = new double [1000];
final double [] y = new double [1000];
try {
for(int k = 1; k <50; k ++){
try {
Thread.sleep(200) // ****时间间隔*****
} catch(InterruptedException e){
e.printStackTrace();
}
for(int i = 0; i x [i] = i;
y [i] = i * i * k;
}
plot2d(k%12,x,y,plot#+ k);
}
} catch(Exception e){
System.out.println();
}
}
};
thread.start();
}
public static void main(String args []){
FastChart demo = new FastChart(X Y Plot);
demo.animatePlot();
}
}
'从线程线程
更新模型。要更新EDT,请使用 javax.swing.Timer
,如此处所示或 SwingWorker
,如此处所示。 / p>
补充:为了验证假设,我将 javax.swing.Timer
添加到
Timer t = new Timer(200,new ActionListener(){
int k = 0;
@Override
public void actionPerformed(ActionEvent e){
if(k ++< 19){
final double [] x = new double [1000];
final double [] y = new double [1000];
for(int i = 0; i x [i ] = i;
y [i] = i * i * k;
}
plot2d(k%12,x,y,plot#+ k);
}
}
});
t.start();
我也使用 invokeLater()
code> main()。
EventQueue.invokeLater(new Runnable b
$ b @Override
public void run(){
FastChart demo = new FastChart(XY Plot);
}
}
In the code below I am conducting an experiment for which I need to plot almost 10 graphs per second ( time interval 100) for total of 50. However when I decrease the time interval TIME INTERVAL ( line 120 down to the bottom) from 200 msec to 100 msec the code raises exception below.
I have tired invokeLater etc, yet I am not able to fix this. I pasted here the entire code which generates the graph below. Kindly take a look and let me know what to do. Thanks in advance
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Series index out of bounds
at org.jfree.data.xy.XYSeriesCollection.getSeries(XYSeriesCollection.java:261)
at org.jfree.data.xy.XYSeriesCollection.getSeriesKey(XYSeriesCollection.java:303)
at org.jfree.chart.labels.AbstractXYItemLabelGenerator.createItemArray(AbstractXYItemLabelGenerator.java:268)
at org.jfree.chart.labels.AbstractXYItemLabelGenerator.generateLabelString(AbstractXYItemLabelGenerator.java:238)
at org.jfree.chart.labels.StandardXYToolTipGenerator.generateToolTip(StandardXYToolTipGenerator.java:165)
at org.jfree.chart.renderer.xy.AbstractXYItemRenderer.addEntity(AbstractXYItemRenderer.java:1747)
at org.jfree.chart.renderer.xy.XYLineAndShapeRenderer.drawSecondaryPass(XYLineAndShapeRenderer.java:1196)
at org.jfree.chart.renderer.xy.XYLineAndShapeRenderer.drawItem(XYLineAndShapeRenderer.java:918)
at org.jfree.chart.plot.XYPlot.render(XYPlot.java:3776)
at org.jfree.chart.plot.XYPlot.draw(XYPlot.java:3337)
at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1226)
at org.jfree.chart.ChartPanel.paintComponent(ChartPanel.java:1612)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1508)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1439)
at javax.swing.RepaintManager.paint(RepaintManager.java:1236)
at javax.swing.JComponent._paintImmediately(JComponent.java:5169)
at javax.swing.JComponent.paintImmediately(JComponent.java:4980)
at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
at javax.swing.RepaintManager$3.run(RepaintManager.java:784)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:784)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:757)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:706)
at javax.swing.RepaintManager.access$1000(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1647)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.*;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;
public class FastChart extends JFrame {
private XYSeries [] xySeries ;
private XYPlot xyPlot;
private XYSeriesCollection xySeriesCollection;
private String title;
private ChartPanel chartPanel;
public FastChart(String s) {
super(s);
init(s);
}
private void init(String s){
title = s;
xySeries = new XYSeries[12];
for (int i = 0; i < xySeries.length; i++) {
xySeries[i] = new XYSeries("Plot "+i);
}
xySeriesCollection = new XYSeriesCollection();
JFreeChart chart = ChartFactory.createScatterPlot(
title, "X", "Y", xySeriesCollection,
PlotOrientation.VERTICAL, true, true, false);
xyPlot = chart.getXYPlot();
xyPlot.setDomainCrosshairVisible(true);
xyPlot.setRangeCrosshairVisible(true);
chartPanel = createChartPanel(chart);
add(chartPanel, BorderLayout.CENTER);
JPanel control = new JPanel();
add(control, BorderLayout.SOUTH);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private ChartPanel createChartPanel(JFreeChart chart) {
XYItemRenderer renderer = xyPlot.getRenderer();
renderer.setSeriesPaint(0, Color.magenta);
renderer.setSeriesPaint(1, Color.green);
renderer.setSeriesPaint(2, Color.blue);
renderer.setSeriesPaint(4, Color.black);
renderer.setSeriesPaint(3, Color.yellow);
Shape cross = ShapeUtilities.createDiagonalCross(3, 0);
Shape plus = ShapeUtilities.createRegularCross(4,0);
for (int i = 0; i <=3; i++) {
renderer.setSeriesShape(0+i, new Rectangle(-1, -1, 2, 2));
renderer.setSeriesShape(4+i, new Ellipse2D.Float(-2F, -2F, 5F, 5F));
renderer.setSeriesShape(8+i, cross);
}
// X axis
NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis();
domain.setVerticalTickLabels(true);
// Y axis
return new ChartPanel(chart);
}
public void plot2d( final int iSeriesN, final double [] dX, final double [] dY, final String sT){
if (dY.length != dX.length){
throw new IllegalArgumentException("Error! inputs x and y have to be of same size.");
}
chartPanel.getChart().removeChangeListener((ChartChangeListener) chartPanel);
xySeries[iSeriesN].clear();
xySeriesCollection.removeAllSeries();
xySeries[iSeriesN]= addXY(iSeriesN, dX, dY);
xySeries[iSeriesN].setKey(sT);
for (int i = 0; i < xySeries.length; i++) {
xySeriesCollection.addSeries(xySeries[i]);
}
chartPanel.getChart().addChangeListener((ChartChangeListener) chartPanel);
xyPlot.setDataset(xySeriesCollection);
}
public XYSeries addXY(final int iSeriesN, final double [] dX, final double [] dY){
XYSeries series = new XYSeries("Plot ");
for (int i = 0; i < dX.length; i++) {
series.add(dX[i], dY[i]);
}
return series;
}
public void animatePlot(){
Thread thread = null;
thread = new Thread (){
public void run() {
final double [] x = new double[1000];
final double [] y = new double[1000];
try{
for (int k = 1; k < 50; k++) {
try {
Thread.sleep(200); //**** TIME INTERVAL *****
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < y.length; i++) {
x[i] = i;
y[i] = i*i*k;
}
plot2d(k % 12, x, y,"plot#"+k);
}
} catch (Exception e){
System.out.println();
}
}
};
thread.start();
}
public static void main(String args[]) {
FastChart demo = new FastChart("X Y Plot");
demo.animatePlot();
}
}
You're updating the model from Thread thread
. To update on the EDT, use a javax.swing.Timer
, as shown here, or SwingWorker
, as shown here.
Addendum: To verify the hypothesis, I added the following javax.swing.Timer
to init()
.
Timer t = new Timer(200, new ActionListener() {
int k = 0;
@Override
public void actionPerformed(ActionEvent e) {
if (k++ < 19) {
final double[] x = new double[1000];
final double[] y = new double[1000];
for (int i = 0; i < y.length; i++) {
x[i] = i;
y[i] = i * i * k;
}
plot2d(k % 12, x, y, "plot#" + k);
}
}
});
t.start();
I also used invokeLater()
in main()
.
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
FastChart demo = new FastChart("X Y Plot");
}
});
这篇关于快速绘制多个图形的时序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!