2012-03-13 50 views
6

散布図グラフ上でマウスでクリックした点の座標を取得しようとしています。JFreeChartでマウスクリック時のポイントの座標を取得する方法は?

ポイントをクリックすると、「イベントをクリックしてください!」というメッセージが表示されます。座標はコンソールに表示されます。 「テスト」ボタンをクリックすると、「テスト」となり、座標がコンソールに表示されます。

問題:ボタンをクリックした後に印刷される座標は最新のものです。点をクリックした後に印刷される座標は、の前に選択された点のいずれかです。

どのように修正できますか(ポイントをクリックすると、選択した新しいポイントの座標が表示されます)。

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

答えて

5

私の推測では、(内部)JFreeChartsリスナーがあるので、ときにコード十字ポイントがまだ更新されていない前に、あなたのマウスリスナーが呼び出されるということです実行する(前の選択をまだ指す)。 chartMouseClickedコードをinvokeLaterに置くと、それが修正されます。

0

ChartMouseEventのeから抽出してみてください。

e.x 
e.y 
+0

私は 'e.getChart()。getXYPlot()。getDomainCrosshairValue()'を試しました。同じ問題 –

1

グラフの再描画もマウスイベントによってトリガされるため、イベントリスナがトリガされた時点でこれが完了しているとは限りません。

再描画が完了したことを保証する別のポイントを聴く必要があります。 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

e.getTrigger()のgetX()

は私のために働きました。!

関連する問題