Java - 如何在鼠标按钮释放后接收点坐标(JFreeChart) [英] Java - how to receive point coordinates after mouse button release (JFreeChart)
问题描述
我使用JFreeChart写了一个简单的抛物线图。我得到图形点坐标,当鼠标按钮按下,我也想获得图形点坐标,当鼠标按钮释放。
但是 chartMouseMoved 在鼠标按钮按下时不起作用。如何解决我的问题,鼠标释放后获得图形坐标?
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?
这是我的代码:
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);
}
}
}
p>
推荐答案
如图所示此处, ChartPanel
使用释放手势以处理缩放; setMouseZoomable(false)
不会改变。
As shown here, ChartPanel
uses the click-drag-release gesture to handle zooming; setMouseZoomable(false)
doesn't change that.
从显示的建议工作在这里,下面的完整示例打印任何点击的点的坐标。我已经放大了系列形状,使其更容易看到效果。此外,Swing GUI对象应该在上构造和操作< nofollow noreferrer> event dispatch thread 。
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.
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 http://stackoverflow.com/a/20107935/230513
* @see http://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);
}
});
}
}
这篇关于Java - 如何在鼠标按钮释放后接收点坐标(JFreeChart)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!