Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
409 views
in Technique[技术] by (71.8m points)

charts - Java - how to receive point coordinates after mouse button release (JFreeChart)

I wrote a simple parabola plot using JFreeChart. I get graphic point coordinates, when mouse button pressed and i also want to get graphic point coordinates, when mouse button released. But chartMouseMoved don't work while mouse button pressing. How can I solve my problem and get graphic coordinates after mouse button releasing?

This is my code:

package parabolademo;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

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.entity.ChartEntity;
import org.jfree.chart.entity.XYItemEntity;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.function.Function2D;
import org.jfree.data.function.PolynomialFunction2D;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;


public class ParabolaDemo extends ApplicationFrame {

    /*
     * @param title  the frame title.
     */
    int flag = 0;
    double delta = 0;
    double px = 0.0, py = 0.0, prx = 0.0, pry = 0.0, chartpx = 0.0, chartpy = 0.0, 
            chartX = 0.0, chartY = 0.0;
    int windowheight = 270;
    public ParabolaDemo(final String title) {

        super(title);
        double[] a = {0.0, 0.0, 1.0};
        Function2D p = new PolynomialFunction2D(a);
        double lrange = -20.0;
        double rrange = 20.0;
        XYDataset dataset = DatasetUtilities.sampleFunction2D(p, lrange, rrange, 1000, "y = f(x)");
        double max = 0.0;

        if (a[2] < 0) {
            max = p.getValue(-a[1] / 2*a[2]);
        }
        else {
            if (p.getValue(lrange) > p.getValue(rrange))
                max = p.getValue(lrange);
            else
                max = p.getValue(rrange);
        }
        System.out.println("max = " + max);
        delta = max / 16.4;

        final JFreeChart chart = ChartFactory.createXYLineChart(
            "Parabola",
            "X", 
            "Y", 
            dataset,
            PlotOrientation.VERTICAL,
            true,
            true,
            false
        );

        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.addMouseListener(new CustomListener());
        chartPanel.addChartMouseListener(new ChartMouseListener() {

            @Override
            public void chartMouseClicked(ChartMouseEvent cme) {

            }

            @Override
            public void chartMouseMoved(ChartMouseEvent cme) {
                ChartEntity ce = cme.getEntity();
                if (ce instanceof XYItemEntity) {
                    XYItemEntity e = (XYItemEntity) ce;
                    XYDataset d = ((XYItemEntity) ce).getDataset();
                    int i = ((XYItemEntity) ce).getItem();
                    chartpx = d.getXValue(0, i);
                    chartpy = d.getYValue(0, i);
                    //System.out.println("X:" + chartpx + ", Y:" + chartpy);
                }
                Point2D po = chartPanel.translateScreenToJava2D(cme.getTrigger().getPoint());
                Rectangle2D plotArea = chartPanel.getScreenDataArea();
                XYPlot plot = (XYPlot) chart.getPlot(); // your plot
                chartX = plot.getDomainAxis().java2DToValue(po.getX(), plotArea, plot.getDomainAxisEdge());
                chartY = plot.getRangeAxis().java2DToValue(po.getY(), plotArea, plot.getRangeAxisEdge());
                System.out.println("X:" + chartX + ", Y:" + chartY);
            }
        });
        chartPanel.setPreferredSize(new java.awt.Dimension(500, windowheight));
        chartPanel.setDomainZoomable(false);
        chartPanel.setRangeZoomable(false);
        setContentPane(chartPanel);
    }

    public static void main(final String[] args) {

        final ParabolaDemo demo = new ParabolaDemo("Parabola Plot Demo");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }


    public class CustomListener implements MouseListener {

          public void mouseClicked(MouseEvent e) {

          }

          public void mouseEntered(MouseEvent e) {

          }

          public void mouseExited(MouseEvent e) {

          }

          public void mousePressed(MouseEvent e) {
              flag = 1;
              px = chartpx;
              py = chartpy;
              System.out.println("Mouse Pressed! xpos = " + px + "; py = " + py);
          }

          public void mouseReleased(MouseEvent e) {
              flag = 1;
              prx = chartX;
              pry = chartY;
              System.out.println("Mouse Released! xpos = " + prx + "; py = " + pry);
          }
     }
}

Thanks in advance!

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As shown here, ChartPanel uses the click-drag-release gesture to handle zooming; setMouseZoomable(false) doesn't change that.

Working from the suggestion shown here, the complete example below prints the coordinates of any clicked point. I've enlarged the series shape to make it easier to see the effect. In addition, Swing GUI objects should be constructed and manipulated only on the event dispatch thread.

image

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Rectangle;
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.entity.ChartEntity;
import org.jfree.chart.entity.XYItemEntity;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.function.Function2D;
import org.jfree.data.function.PolynomialFunction2D;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.util.ShapeUtilities;

public class ParabolaDemo extends ApplicationFrame {

    /*
     * @see https://stackoverflow.com/a/20107935/230513
     * @see https://stackoverflow.com/q/20081801/230513
     */
    public ParabolaDemo(final String title) {

        super(title);
        double[] a = {0.0, 0.0, 3.0};
        Function2D p = new PolynomialFunction2D(a);
        XYDataset dataset = DatasetUtilities.sampleFunction2D(
            p, -20.0, 20.0, 20, "y = 3x2 {-20…20}");
        final JFreeChart chart = ChartFactory.createXYLineChart("Parabola",
            "X", "Y", dataset, PlotOrientation.VERTICAL, true, true, false);
        final XYPlot plot = (XYPlot) chart.getPlot();
        XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) plot.getRenderer();
        r.setBaseShapesVisible(true);
        r.setSeriesShape(0, ShapeUtilities.createTranslatedShape(
            new Rectangle(12, 12), -6, -6));
        final ChartPanel chartPanel = new ChartPanel(chart) {

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(640, 480);
            }
        };
        chartPanel.addChartMouseListener(new ChartMouseListener() {

            @Override
            public void chartMouseClicked(ChartMouseEvent cme) {
                report(cme);
            }

            @Override
            public void chartMouseMoved(ChartMouseEvent cme) {
                //report(cme);
            }

            private void report(ChartMouseEvent cme) {
                ChartEntity ce = cme.getEntity();
                if (ce instanceof XYItemEntity) {
                    XYItemEntity e = (XYItemEntity) ce;
                    XYDataset d = e.getDataset();
                    int s = e.getSeriesIndex();
                    int i = e.getItem();
                    System.out.println("X:" + d.getX(s, i) + ", Y:" + d.getY(s, i));
                }
            }
        });
        setContentPane(chartPanel);
    }

    public static void main(final String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                final ParabolaDemo demo = new ParabolaDemo("Parabola Demo");
                demo.pack();
                RefineryUtilities.centerFrameOnScreen(demo);
                demo.setVisible(true);
            }
        });
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...