I got a problem regarding the crosshairs in a CombinedRangeXYPlot when using SWT. With Swing everything works fine. I boiled it down to a minimal example that shows the problem.
There are two source codes below. The first one uses Swing, the second one SWT. Apart from that they do the exact same thing.
There is a CombinedRangeXYPlot with two subplots. When the user clicks on the chart, the range crosshair of the second plot is set to the range crosshair value of the first plot:
Code: Select all
plot2.setRangeCrosshairValue(plot1.getRangeCrosshairValue());
Problem with the SWT version:
The updating of the crosshair in plot2 is always delayed by one click. So it shows the value of the last but one click in plot1. Looks like the chart is not directly updated after the crosshair has been changed.
Any ideas how to fix this?
Swing:
Code: Select all
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.event.ChartProgressEvent;
import org.jfree.chart.event.ChartProgressListener;
import org.jfree.chart.plot.CombinedRangeXYPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.DefaultXYDataset;
import javax.swing.JFrame;
public class CombinedPlotCrosshairDemo {
static XYPlot plot1;
static XYPlot plot2;
public static void main(String[] args) {
DefaultXYDataset data = new DefaultXYDataset();
data.addSeries(0, createData());
plot1 = new XYPlot();
plot1.setDomainAxis(new NumberAxis());
plot1.setRenderer(0, new XYLineAndShapeRenderer());
plot1.setDataset(0, data);
plot1.setRangeCrosshairVisible(true);
plot2 = new XYPlot();
plot2.setDomainAxis(new NumberAxis());
plot2.setRenderer(0, new XYLineAndShapeRenderer());
plot2.setDataset(0, data);
plot2.setRangeCrosshairVisible(true);
CombinedRangeXYPlot combPlot = new CombinedRangeXYPlot();
combPlot.setRangeAxis(new NumberAxis());
combPlot.add(plot1);
combPlot.add(plot2);
JFreeChart chart = new JFreeChart(combPlot);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new java.awt.Dimension(800, 600));
JFrame frame = new JFrame();
frame.setContentPane(chartPanel);
frame.pack();
frame.setVisible(true);
CrosshairUpdater crosshairUpdater = new CrosshairUpdater();
chart.addProgressListener(crosshairUpdater);
chartPanel.addChartMouseListener(crosshairUpdater);
}
private static class CrosshairUpdater
implements ChartMouseListener, ChartProgressListener {
private ChartMouseEvent mouseEvent;
@Override
public void chartMouseClicked(ChartMouseEvent event) {
mouseEvent = event;
}
@Override
public void chartMouseMoved(ChartMouseEvent chartMouseEvent) {
}
@Override
public void chartProgress(ChartProgressEvent event) {
if (event.getType() == ChartProgressEvent.DRAWING_FINISHED
&& mouseEvent != null) {
plot2.setRangeCrosshairValue(plot1.getRangeCrosshairValue());
mouseEvent = null;
}
}
}
private static double[][] createData() {
double[][] data = new double[2][5];
data[0][0] = 1;
data[0][1] = 2;
data[0][2] = 3;
data[0][3] = 4;
data[0][4] = 5;
data[1][0] = 4;
data[1][1] = 7;
data[1][2] = 2;
data[1][3] = 6;
data[1][4] = 4;
return data;
}
}
Code: Select all
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.event.ChartProgressEvent;
import org.jfree.chart.event.ChartProgressListener;
import org.jfree.chart.plot.CombinedRangeXYPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.DefaultXYDataset;
import org.jfree.experimental.chart.swt.ChartComposite;
public class CombinedPlotCrosshairDemoSWT {
static XYPlot plot1;
static XYPlot plot2;
public static void main(String[] args) {
DefaultXYDataset data = new DefaultXYDataset();
data.addSeries(0, createData());
plot1 = new XYPlot();
plot1.setDomainAxis(new NumberAxis());
plot1.setRenderer(0, new XYLineAndShapeRenderer());
plot1.setDataset(0, data);
plot1.setRangeCrosshairVisible(true);
plot2 = new XYPlot();
plot2.setDomainAxis(new NumberAxis());
plot2.setRenderer(0, new XYLineAndShapeRenderer());
plot2.setDataset(0, data);
plot2.setRangeCrosshairVisible(true);
CombinedRangeXYPlot combPlot = new CombinedRangeXYPlot();
combPlot.setRangeAxis(new NumberAxis());
combPlot.add(plot1);
combPlot.add(plot2);
JFreeChart chart = new JFreeChart(combPlot);
Display display = new Display();
Shell parent = new Shell(display);
ChartComposite composite =
new ChartComposite(parent, SWT.NONE, chart, true);
CrosshairUpdater crosshairUpdater = new CrosshairUpdater();
composite.addChartMouseListener(crosshairUpdater);
chart.addProgressListener(crosshairUpdater);
parent.setLayout(new FillLayout());
parent.pack();
parent.open();
while (!parent.isDisposed()) {
if (!display.readAndDispatch ()) {
display.sleep();
}
}
display.dispose();
}
private static class CrosshairUpdater
implements ChartMouseListener, ChartProgressListener {
private ChartMouseEvent mouseEvent;
@Override
public void chartMouseClicked(ChartMouseEvent event) {
mouseEvent = event;
}
@Override
public void chartMouseMoved(ChartMouseEvent chartMouseEvent) {
}
@Override
public void chartProgress(ChartProgressEvent event) {
if (event.getType() == ChartProgressEvent.DRAWING_FINISHED
&& mouseEvent != null) {
plot2.setRangeCrosshairValue(plot1.getRangeCrosshairValue());
mouseEvent = null;
}
}
}
private static double[][] createData() {
double[][] data = new double[2][5];
data[0][0] = 1;
data[0][1] = 2;
data[0][2] = 3;
data[0][3] = 4;
data[0][4] = 5;
data[1][0] = 4;
data[1][1] = 7;
data[1][2] = 2;
data[1][3] = 6;
data[1][4] = 4;
return data;
}
}