2012-09-27 99 views
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 

    } 

} 

但這款鼠標監聽器返回我我的面板座標,我想從座標我的圖表。可能我必須使用其他對象的偵聽器嗎?或者我可以用某種方法轉換座標?

+0

是否要添加新的點或選擇現有的點?請編輯您的問題以包含顯示您當前方法的[sscce](http://sscce.org/)。 – trashgod

回答

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

+0

你什麼意思是脆?你認爲它會在某個時候崩潰嗎?通過渲染器,你的意思是監聽器中的chartMouseClicked()函數(我認爲你的意思是這個 - http://docs.oracle.com/javaee/5/api/javax/faces/render/Renderer.html)?我省略了x和y的聲明,並不是因爲我建議將它包含在鼠標單擊的函數中,而是要注意這些變量的來源。 – user1581900

+0

我的意思是說圖表相對座標可能會發生變化,而渲染器可以使用軸在屏幕和模型座標之間進行轉換。 – trashgod

2

獲取X,Y通過

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

的一個主要問題座標在圖形中的空間:我發現的JFreeChart不更新這些值,直到後我ChartMouseEvent處理程序被調用;每次通過我得到以前的值。您可以查看XYPlot.handleClick(x,y,info)以獲取詳細信息以獲取處理程序中的當前值。

1

您必須獲取對ChartPanel的引用,然後才能繪製它,並且只有在此之後,才能從Plot中獲取正確的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); 
      } 
     }); 
    } 
}