How to get click point coordinates using JFreeChart?

I am trying to get the coordinates of a point clicked on a scatter plot graph.

When you click on a point, "Click event!" and the coordinates are printed on the console. When you click the Test button, Test and the coordinates are printed on the console.

Problem: The coordinates printed after the button is pressed are current. The coordinates printed after clicking on a point are the characters of the previously selected point .

How can I fix this (so when I click on a point, the coordinates of the newly selected point are displayed)?

package graph; import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.util.Random; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import org.jfree.chart.ChartFactory; 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.axis.NumberTickUnit; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; /** * @see http://stackoverflow.com/questions/7231824 * @see http://stackoverflow.com/questions/7205742 * @see http://stackoverflow.com/questions/7208657 * @see http://stackoverflow.com/questions/7071057 */ public class GraphFrameOld extends JFrame { private static final int N = 32; private static final String title = "Scatter Plot Pannel"; private static final Random rand = new Random(); private final XYSeries added = new XYSeries("Added"); private static XYPlot xyPlot; public GraphFrameOld(String s) { super(s); final ChartPanel chartPanel = createGraphPanel(); this.add(chartPanel, BorderLayout.CENTER); JPanel control = new JPanel(); control.add(new JButton(new AbstractAction("Add") { @Override public void actionPerformed(ActionEvent e) { for (int i = 0; i < N; i++) { added.add(rand.nextDouble(), rand.nextDouble()); } } })); control.add(new JButton(new AbstractAction("Test") { @Override public void actionPerformed(ActionEvent e) { System.out.println("Test"); System.out.println(xyPlot.getDomainCrosshairValue() + " " + xyPlot.getRangeCrosshairValue()); } })); // add click event chartPanel.addChartMouseListener(new ChartMouseListener() { @Override public void chartMouseClicked(ChartMouseEvent e) { System.out.println("Click event!"); XYPlot xyPlot2 = chartPanel.getChart().getXYPlot(); // Problem: the coordinates displayed are the one of the previously selected point ! System.out.println(xyPlot2.getDomainCrosshairValue() + " " + xyPlot2.getRangeCrosshairValue()); } @Override public void chartMouseMoved(ChartMouseEvent arg0) { } }); this.add(control, BorderLayout.SOUTH); } private ChartPanel createGraphPanel() { JFreeChart jfreechart = ChartFactory .createScatterPlot(title, "X", "Y", createSampleData(), PlotOrientation.VERTICAL, true, true, false); xyPlot = (XYPlot) jfreechart.getPlot(); xyPlot.setDomainCrosshairVisible(true); xyPlot.setRangeCrosshairVisible(true); XYItemRenderer renderer = xyPlot.getRenderer(); renderer.setSeriesPaint(0, Color.blue); NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis(); domain.setRange(0.00, 1.00); domain.setTickUnit(new NumberTickUnit(0.1)); domain.setVerticalTickLabels(true); NumberAxis range = (NumberAxis) xyPlot.getRangeAxis(); range.setRange(0.0, 1.0); range.setTickUnit(new NumberTickUnit(0.1)); return new ChartPanel(jfreechart); } private XYDataset createSampleData() { XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); XYSeries series = new XYSeries("Random"); for (int i = 0; i < N * N; i++) { double x = rand.nextDouble(); double y = rand.nextDouble(); series.add(x, y); } xySeriesCollection.addSeries(series); xySeriesCollection.addSeries(added); return xySeriesCollection; } public static void main(String args[]) { EventQueue.invokeLater(new Runnable() { @Override public void run() { GraphFrameOld demo = new GraphFrameOld(title); demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); demo.pack(); demo.setLocationRelativeTo(null); demo.setVisible(true); } }); } } 
+6
source share
4 answers

My assumption is that your mouse listener is called in front of the (internal) JFreeCharts listener, so the hair intersection point is not yet updated when your code executes (point to the previous selection). Paste your chartMouseClicked code into invokeLater to fix this.

+5
source

The problem is that chart redrawing is also triggered by a mouse event, and therefore it is not guaranteed that it ended when your event listener starts.

You must listen to another point, which ensures that the redraw is finished. You can use chartProgressListener and filter out when the redraw is complete. The adapted code is not very elegant, and you may need a few more checks, but it seems to do the job:

 package graph; import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.util.Random; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import org.jfree.chart.ChartFactory; 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.axis.NumberTickUnit; import org.jfree.chart.entity.ChartEntity; import org.jfree.chart.event.*; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; /** * @see http://stackoverflow.com/questions/7231824 * @see http://stackoverflow.com/questions/7205742 * @see http://stackoverflow.com/questions/7208657 * @see http://stackoverflow.com/questions/7071057 */ public class GraphFrameOld extends JFrame { private static final int N = 32; private static final String title = "Scatter Plot Pannel"; private static final Random rand = new Random(); private final XYSeries added = new XYSeries("Added"); private static XYPlot xyPlot; public GraphFrameOld(String s) { super(s); final ChartPanel chartPanel = createGraphPanel(); this.add(chartPanel, BorderLayout.CENTER); JPanel control = new JPanel(); control.add(new JButton(new AbstractAction("Add") { @Override public void actionPerformed(ActionEvent e) { for (int i = 0; i < N; i++) { added.add(rand.nextDouble(), rand.nextDouble()); } } })); control.add(new JButton(new AbstractAction("Test") { @Override public void actionPerformed(ActionEvent e) { System.out.println("Test"); System.out.println(xyPlot.getDomainCrosshairValue() + " " + xyPlot.getRangeCrosshairValue()); } })); this.add(control, BorderLayout.SOUTH); } private ChartPanel createGraphPanel() { JFreeChart jfreechart = ChartFactory .createScatterPlot(title, "X", "Y", createSampleData(), PlotOrientation.VERTICAL, true, true, false); xyPlot = (XYPlot) jfreechart.getPlot(); xyPlot.setDomainCrosshairVisible(true); xyPlot.setRangeCrosshairVisible(true); XYItemRenderer renderer = xyPlot.getRenderer(); renderer.setSeriesPaint(0, Color.red); NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis(); domain.setRange(0.00, 1.00); domain.setTickUnit(new NumberTickUnit(0.1)); domain.setVerticalTickLabels(true); NumberAxis range = (NumberAxis) xyPlot.getRangeAxis(); range.setRange(0.0, 1.0); range.setTickUnit(new NumberTickUnit(0.1)); final ChartPanel result = new ChartPanel(jfreechart); jfreechart.addProgressListener(new ChartProgressListener() { @Override public void chartProgress(ChartProgressEvent cpe) { if(cpe.getType()==ChartProgressEvent.DRAWING_FINISHED){ System.out.println("Click event!"); XYPlot xyPlot2 = result.getChart().getXYPlot(); System.out.println(xyPlot2.getDomainCrosshairValue() + " " + xyPlot2.getRangeCrosshairValue()); } } }); return result; } private XYDataset createSampleData() { XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); XYSeries series = new XYSeries("Random"); for (int i = 0; i < N * N; i++) { double x = rand.nextDouble(); double y = rand.nextDouble(); series.add(x, y); } xySeriesCollection.addSeries(series); xySeriesCollection.addSeries(added); return xySeriesCollection; } public static void main(String args[]) { EventQueue.invokeLater(new Runnable() { @Override public void run() { GraphFrameOld demo = new GraphFrameOld(title); demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); demo.pack(); demo.setLocationRelativeTo(null); demo.setVisible(true); } }); } } 
+1
source

Try extracting from ChartMouseEvent e:

 ex ey 
0
source

e.getTrigger (). Getx ()

worked for me!

 System.out.println(e.getTrigger().getX() + " " + e.getTrigger().getY() ); 
0
source

Source: https://habr.com/ru/post/910605/


All Articles