Как получить координаты точки при щелчке мышью с помощью JFreeChart? - PullRequest
7 голосов
/ 13 марта 2012

Я пытаюсь получить координаты точки, нажатой мышью на графике рассеянного графика.

При нажатии на точку «Щелкните событие!»и координаты напечатаны на консоли.При нажатии кнопки «Тест» на консоли выводятся «Тест» и координаты.

Проблема: Координаты, напечатанные после нажатия кнопки, являются актуальными.Координаты, напечатанные после нажатия на точку, совпадают с ранее выбранной точкой .

Как это исправить (поэтому, когда я нажимаю на точку, координаты новой выбранной точкиотображаются)?

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);
            }
        });
    }
}

Ответы [ 4 ]

6 голосов
/ 13 марта 2012

Я предполагаю, что ваш слушатель мыши вызывается до (внутреннего) слушателя JFreeCharts, поэтому точка перекрестия еще не обновляется, когда ваш код выполняется (все еще указывает на предыдущий выбор).Помещение вашего кода chartMouseClicked в invokeLater должно исправить это.

1 голос
/ 13 марта 2012

Проблема заключается в том, что перерисовка диаграммы также инициируется событием мыши, и поэтому нет уверенности, что это завершится в момент запуска прослушивателя событий.

Вы должны послушать другой пункт, который гарантирует, что перерисовка закончена. Вы можете использовать chartProgressListener и отфильтровывать, когда перерисовка завершена. Адаптированный код не очень элегантен, и вам может потребоваться еще несколько проверок, но, похоже, он выполняет свою работу:

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);
        }
    });
    }
}
0 голосов
/ 18 июля 2013

e.getTrigger (). GetX ()

у меня сработало!

System.out.println(e.getTrigger().getX() + " " + e.getTrigger().getY() );
0 голосов
/ 13 марта 2012

Попробуйте извлечь из ChartMouseEvent e:

e.x
e.y
...