2012-03-13 19 views
6

Sto cercando di ottenere le coordinate del punto cliccato con il mouse su un grafico di grafico a dispersione.Come ottenere le coordinate di un punto al clic del mouse con JFreeChart?

Quando si fa clic su un punto, "Fare clic su evento!" e le coordinate sono stampate sulla console. Quando si fa clic sul pulsante "Test", "Test" e le coordinate vengono stampate sulla console.

Problema: Le coordinate stampate dopo aver cliccato sul pulsante sono aggiornate. Le coordinate stampate dopo aver cliccato su un punto sono quelle di il punto selezionato in precedenza.

Come posso risolvere il problema (quindi quando clicco su un punto, vengono visualizzate le coordinate del nuovo punto selezionato)?

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

risposta

5

La mia ipotesi è che il listener del mouse viene chiamato prima della JFreeCharts (interni) ascoltatore è, in modo che il punto croce non è ancora aggiornato quando il codice esegue (puntare ancora alla selezione precedente). Mettere il tuo chartMouse Il codice cifrato in un invokeLater dovrebbe correggerlo.

0

Prova estrarre dal ChartMouseEvent e:

e.x 
e.y 
+0

Ho provato 'e.getChart(). GetXYPlot(). GetDomainCrosshairValue()'. Stesso problema –

1

Il problema è che il ridisegno del grafico viene attivato anche dall'evento del mouse e quindi non è garantito che questo sia terminato nel momento in cui viene attivato il listener di eventi.

È necessario ascoltare un altro punto che garantisce il completamento del ridisegno. È possibile utilizzare chartProgressListener e filtrare al termine del ridisegno. Il codice adattato non è molto elegante e potrebbe essere necessario qualche più controlli, ma sembra di fare il lavoro:.

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

e.getTrigger() GetX()

lavorato per me!

System.out.println(e.getTrigger().getX() + " " + e.getTrigger().getY()); 
Problemi correlati