Java – 如何在鼠标按键释放后接收点坐标(JFreeChart)

我用JFreeChart写了一个简单的抛物线图。 我得到graphics点坐标,当按下鼠标button时,我也想获得graphics点坐标,当鼠标button释放。 但是,鼠标按下时, chartMouseMoved不工作。 如何解决我的问题,获得鼠标button释放后的graphics坐标?

这是我的代码:

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

提前致谢!

如此处所示, ChartPanel使用点击 – 拖放手势来处理缩放; setMouseZoomable(false)不会改变这一点。

根据此处显示的build议进行操作,下面的完整示例将打印任何点击的坐标。 我已经扩大了系列形状,以便更容易看到效果。 另外,Swing GUI对象只能在事件派发线程上构造和操作。

图片

 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 = 3x² {-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); } }); } }