2012-09-27 34 views
5

Tôi muốn đặt dấu chấm trong ứng dụng của mình bằng cách nhấp chuột. Tôi sử dụng JFreeChart và sử dụng trong trình nghe chuột ChartPanel. Đây là giống như thế này:Biến đổi tọa độ trình nghe chuột thành tọa độ biểu đồ

panel.addChartMouseListener(new ThisMouseListener()); 

và nghe con chuột của tôi ThisMouseListener() (nó không phải là kết thúc):

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 

    } 

} 

nhưng nghe con chuột này trả về cho tôi tọa bảng điều khiển của tôi và tôi muốn để có được tọa độ từ biểu đồ của tôi. Có thể tôi phải sử dụng người nghe với đối tượng khác không? hoặc tôi có thể biến đổi tọa độ với một số phương pháp?

+0

Bạn có muốn _add_ điểm mới hoặc _select_ hiện tại? Vui lòng chỉnh sửa câu hỏi của bạn để bao gồm [sscce] (http://sscce.org/) cho thấy cách tiếp cận hiện tại của bạn. – trashgod

Trả lời

3

Bạn đã thêm người nghe vào bảng điều khiển. Do đó, khi bạn nhấp chuột, bạn sẽ nhận được tọa độ tương ứng với bảng điều khiển - đó là nguồn của sự kiện. Bạn cần phải thêm người nghe này vào biểu đồ để thay thế.

Khả năng khác là lấy toạ độ của biểu đồ liên quan đến bảng điều khiển và trừ chúng khỏi x và 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 

Nếu bảng điều khiển là vùng chứa thành phần biểu đồ, giải pháp của bạn có thể trông giống như hình trên. Lưu ý rằng các tọa độ này sẽ được tọa độ theo góc trên cùng bên trái của biểu đồ.

+1

Sẽ không dễ chút nào? Có vẻ như bạn phải làm việc bên trong trình kết xuất đồ họa để có được hình học đáng tin cậy. – trashgod

+0

bạn có ý nghĩa gì bởi giòn? Bạn có nghĩ rằng nó có thể sụp đổ tại một số điểm? Bởi renderer bạn có nghĩa là các chartMouseClicked() chức năng trong người nghe (tôi nghĩ rằng bạn có nghĩa là điều này-http: //docs.oracle.com/javaee/5/api/javax/faces/render/Renderer.html)? Tôi bỏ qua các tuyên bố của x và y không phải vì tôi đề nghị để bao gồm nó bên trong chức năng nhấp chuột, nhưng để lưu ý nguồn gốc của các biến đó. – user1581900

+0

Tôi có nghĩa là giòn theo nghĩa là các tọa độ tương đối biểu đồ có thể thay đổi, trong khi trình kết xuất có thể sử dụng trục để chuyển đổi giữa các tọa độ màn hình và mô hình. – trashgod

2

Lấy x, y tọa độ trong không gian đồ thị của bạn qua

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

Một vấn đề lớn: Tôi thấy rằng JFreeChart không cập nhật các giá trị cho đến khi sau handler ChartMouseEvent tôi được gọi là; mỗi lần thông qua tôi nhận được các giá trị trước đó. Bạn có thể xem XYPlot.handleClick (x, y, thông tin) để biết chi tiết để có được các giá trị hiện tại trong trình xử lý của bạn.

1

Bạn phải lấy tham chiếu đến ChartPanel, rredraw nó và chỉ sau đó bạn có thể nhận được một X, Y chính xác tọa độ từ Lô. Để làm như vậy, bạn phải đặt tọa độ thu hồi trên hàng đợi và không gọi nó trực tiếp. Dưới đây là ví dụ phù hợp với tôi (chỉ dành cho X tọa độ)

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