将鼠标监听器的坐标转换为图表坐标

5

我想在我的应用程序中通过鼠标单击来设置点。我使用JFreeChart并在ChartPanel中使用鼠标监听器。代码如下:

panel.addChartMouseListener(new ThisMouseListener());

并且我的鼠标监听器ThisMouseListener()(它还没有完成):

class ThisMouseListener implements ChartMouseListener{

    @Override
    public void chartMouseClicked(ChartMouseEvent event) {
        int x = event.getTrigger().getX();
        int y = event.getTrigger().getY();

        System.out.println("X :" + x + " Y : " + y);

        ChartEntity entity = event.getEntity();
        if(entity != null && (entity instanceof XYItemEntity)){
            XYItemEntity item = (XYItemEntity)entity;
        }
        new JOptionPane().showMessageDialog(null, "Hello", "Mouse Clicked event", JOptionPane.OK_OPTION);
    }

    @Override
    public void chartMouseMoved(ChartMouseEvent arg0) {
        // TODO Auto-generated method stub

    }

} 

但是这个鼠标监听器返回的是我的面板坐标,我想要从我的图表中获取坐标。也许我必须使用其他对象的监听器?或者我可以通过一些方法转换坐标?

你想要“添加”新的点还是“选择”现有的点?请编辑您的问题,包括一个 sscce 来展示您当前的方法。 - trashgod
3个回答

3

您将监听器添加到了面板上。因此,当您单击鼠标时,您会收到相对于面板的坐标 - 这是事件源。您需要将此监听器添加到图表中。

另一种可能性是获取图表相对于面板的坐标,并从x和y中减去它们。

Point p = chart.getLocation();     
int px = p.getX();
int py = p.getY();

x = x-px; // x from event
y = y-py; // y from event
// x and y are now coordinates in respect to the chart

if(x<0 || y<0 || x>chart.getWidth() || y>chart.getHeight()) // the click was outside of the chart
else // the click happened within boundaries of the chart and 

如果面板是图表组件的容器,您的解决方案可能类似于上面的解决方案。请注意,这些坐标将是相对于图表左上角的坐标。

1
这不会有点脆弱吗?似乎你必须在渲染器内部工作才能获得可靠的几何形状。 - trashgod
你所说的“brittle”是什么意思?你认为它会在某个时候崩溃吗?你所说的渲染器是指监听器中的chartMouseClicked()函数吗(我想你是指这个-http://docs.oracle.com/javaee/5/api/javax/faces/render/Renderer.html)?我省略了x和y的声明,不是因为建议将其包含在鼠标点击函数内,而是为了说明这些变量的来源。 - user1581900
我的意思是“脆弱”,即图表相关的坐标可能会发生变化,而渲染器可以使用轴来在屏幕坐标和模型坐标之间进行转换。 - trashgod
JFreeChart 没有 chart.getLocation() 方法。 - Aliaksei Bulhak

2

通过以下方式获取您的图形空间中的x,y坐标

double x = event.getChart().getXYPlot().getDomainCrosshairValue();
double y = event.getChart().getXYPlot().getRangeCrosshairValue();

一个主要的问题是:我发现JFreeChart在我的ChartMouseEvent处理程序被调用之前不会更新这些值;每次执行时我都会得到之前的值。你可以查看XYPlot.handleClick(x,y,info)的详细信息,在你的处理程序中获取当前值。


1
你需要获取ChartPanel的引用,重新绘制它,然后才能从图表中获取正确的X,Y坐标。为此,你必须将坐标检索放置在awt队列中,而不是直接调用它。以下是对我有效的示例(仅适用于X坐标)。
@Override
public void chartMouseClicked(ChartMouseEvent cme) {
    final ChartMouseEvent cmeLocal = cme;
    ChartPanel hostChartPanel = (ChartPanel) cme.getTrigger().getComponent();
    if (null != hostChartPanel) {

        //Crosshair values are not valid until after the chart has been updated
        //that is why call repaint() now and post Crosshair value retrieval on the
        //awt thread queue to get them when repaint() is finished
        hostChartPanel.repaint();

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFreeChart chart = cmeLocal.getChart();
                XYPlot plot = chart.getXYPlot();
                double crossHairX = plot.getDomainCrosshairValue();
                JOptionPane.showMessageDialog(null, Double.toString(crossHairX), "X-Value", JOptionPane.OK_OPTION);
            }
        });
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接