これは私の最初の投稿StackOverFlowですので、私の投稿の間違いをお許しください。 トピックには、特定のX座標とY座標をプロットするプログラムがあります。 私は現在、XYチャートにJFREECHARTを使用しています。 高速アップデートの要件を満たすために、私は2シリーズを持っています。 Series1は1000のデータポイントを蓄積し、それを表示するためにチャートに追加されます。このシリーズ2は1000データポイントを蓄積し、一度確定されるとシリーズ1000をクリアし(新しい1000データポイントの準備をします)、シリーズ2をチャートに追加します)...そしてこのサイクルは続く。 問題はXYSeries.clearおよびXYSeries.add関数にあります。どうやら彼らは自分のスレッドを作成し、実行が完了する前に、私のアプリケーションが非常に高速であるので、すでに新しいスレッドを生成しています。これは私が考えているindexoutoboundsエラーです。私はこれを推測することができました: http://www.jfree.org/phpBB2/viewtopic.php?p=68111 類似したエラー。 解決策は次のようになります。 Swing Thread Safe ProgrammingJfreechart indexoutofbounds例外
解決策は、SwingUtilities.invokeLaterを使用することです。しかし、私は自分のアプリケーションでこれを使う方法を理解していません。 私のコードは:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static java.lang.Thread.sleep;
import org.jfree.chart.axis.ValueAxis;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
public class dataPlotter {
private static int x = 0;
private static boolean thread_start = false;
private static final double PI = 3.1428571;
private static boolean thread_run = true;
private static double voltage = 0;
private static boolean useSeries1 = true;
public static void main(String[] args) {
//create and configure window
JFrame window = new JFrame();
window.setTitle("Data Plotter GUI");
window.setSize(600, 400);
window.setLayout(new BorderLayout());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create a drop down box and connect button, then place that at the top of the window
JButton connectButton = new JButton("Start");
JPanel topPanel = new JPanel();
topPanel.add(connectButton);
window.add(topPanel, BorderLayout.NORTH);
//create the line graph
XYSeries series1 = new XYSeries("Voltage Characteristics");
XYSeries series2 = new XYSeries("Voltage Characteristics");
XYSeriesCollection dataset = new XYSeriesCollection(series1);
JFreeChart chart = ChartFactory.createXYLineChart("Sine Wave", "Time", "Voltage", dataset);
window.add(new ChartPanel(chart), BorderLayout.CENTER);
//set range of x axis and range of series
XYPlot xyPlot = chart.getXYPlot();
ValueAxis domainAxis = xyPlot.getDomainAxis();
ValueAxis rangeAxis = xyPlot.getRangeAxis();
rangeAxis.setRange(-1.5, 1.5);
domainAxis.setRange(0, 1000);
//Declaring thread
Thread thread;
thread = new Thread() {
@Override
public void run() {
thread_start = true;
int count_y = 0;
thread_run = true;
int count = 0;
while (thread_run) {
//create "Y" datapoint i.e. voltage
if (count_y < 800) {
count_y++;
} else {
count_y = 0;
}
voltage = Math.sin(2 * PI * count_y/800);
//add datapoint to CHART
try {
//use series 1 to accumulate 1000 datapoints
if(useSeries1){
synchronized (series1) {
if (series1.getItemCount() > 1000) {
domainAxis.setRange(x - 1001, x);
}
series1.add(x++, voltage);
sleep(1);
}
synchronized (series1) {
window.repaint();
}
synchronized (series1) {
if (series1.getItemCount() ==1001) {
dataset.removeAllSeries();
series2.clear();
domainAxis.setRange(0, 1000);
dataset.addSeries(series1);
useSeries1 = false;
sleep(5);
x = 0;
window.repaint();
}
}
} else{
synchronized (series2) {
if (series2.getItemCount() > 1000) {
domainAxis.setRange(x - 1001, x);
}
series2.add(x++, voltage);
sleep(1);
}
synchronized (series2) {
window.repaint();
}
synchronized (series2) {
if (series2.getItemCount() == 1001) {
dataset.removeAllSeries();
series1.clear();
domainAxis.setRange(0, 1000);
dataset.addSeries(series2);
useSeries1 = true;
sleep(5);
x = 0;
window.repaint();
}
}
}
} catch (Exception er) { }
}
thread_start = false;
}
};
//configure the connect button and use another thread to listen for data
connectButton.addActionListener(new ActionListener() {
@Override
@SuppressWarnings("empty-statement")
public void actionPerformed(ActionEvent e) {
if (connectButton.getText().equals("Start")) {
connectButton.setText("Stop");
thread.start();
} else {
//disconnect from the serial port
thread_run = false;
//while (thread_start);
connectButton.setText("Start");
//synchronized (series) {
//series.clear();
//}
//x = 0;
}
}
});
//Display winow
window.setVisible(true);
}
}
です。通常、リアルタイムGUIグラフ作成を試みる前に、オブジェクト指向とスレッディングの概念を学ぶのが最善です。少しバックアップを取っておこうと思っているかもしれませんし、先に進める前にこれらの基礎を徹底的に勉強して、あなたが深刻な不満のためにいるかもしれないことを恐れています。 –
ただ一つのシリーズでも、私は要素を追加し、要素を削除してindexoutofboundエラーを出します。大きなスリープ間隔でエラーが表示されません。 私は、2つのスレッド を作成することを考えています.1つはデータ蓄積用、もう1つはGUI更新用ですが、ADDメソッドとREMOVEメソッドを1つずつ呼び出して呼び出すと、主な問題が作成されます。 – EgLeO
JFreeChartの小さなサブセットを読んだ後では、synchronizedをまったく使用しないので、あなたは役に立たない... – Aubin