2012-09-27 8 views
5

Chcę ustawić kropki w mojej aplikacji za pomocą kliknięcia myszą. Używam JFreeChart i używam myszki słuchającej ChartPanel. Jest to wyglądać tak:Przekształć koordynatory myszy na współrzędne wykresu

panel.addChartMouseListener(new ThisMouseListener()); 

i moje myszy słuchacza ThisMouseListener() (nie jest gotowe):

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 

    } 

} 

ale słuchacz mysz zwraca mi moje współrzędne panel i chcę uzyskać współrzędne z mój wykres. Czy mogę używać słuchacza z innym obiektem? lub mogę przekształcić współrzędne za pomocą jakiejś metody?

+0

Czy chcesz _add_ nowe punkty lub _select_ istniejące? Edytuj swoje pytanie, dołączając [sscce] (http://sscce.org/), które pokazuje twoje obecne podejście. – trashgod

Odpowiedz

3

Dodałeś słuchacza do panelu. Dlatego po kliknięciu myszą otrzymujesz współrzędne względem panelu - który jest źródłem zdarzenia. Zamiast tego musisz dodać tego słuchacza do wykresu.

Inną możliwością jest uzyskanie współrzędnych wykresu względem panelu i odjęcie ich od x i 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 

Jeśli panel jest kontenerem komponentu wykresu, rozwiązanie może wyglądać podobnie do powyższego. Zauważ, że te współrzędne będą współrzędnymi względem lewego górnego rogu wykresu.

+1

Czy nie byłoby to trochę kruche? Wygląda na to, że musisz pracować wewnątrz renderera, aby uzyskać wiarygodną geometrię. – trashgod

+0

co masz na myśli przez kruche? Czy myślisz, że w pewnym momencie może się zawiesić? Czy przez renderer masz na myśli funkcję chartMouseClicked() w odbiorniku (myślę, że masz na myśli: http: //docs.oracle.com/javaee/5/api/javax/faces/render/Renderer.html)? Pominąłem deklarację xiy, nie dlatego, że proponuję zawrzeć ją w funkcji kliknięcia myszą, ale zwrócić uwagę na źródło tych zmiennych. – user1581900

+0

Miałem na myśli kruchość w tym sensie, że współrzędne na wykresie mogą się zmieniać, podczas gdy renderer może używać osi do konwersji między ekranem a współrzędnymi modelu. – trashgod

2

Pobierz współrzędne x, y w przestrzeni wykresu poprzez

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

jeden poważny problem: Uważam, że JFreeChart nie aktualizuje te wartości aż po moja obsługi ChartMouseEvent nazywa; za każdym razem otrzymuję poprzednie wartości. Możesz przejrzeć XYPlot.handleClick (x, y, info), aby uzyskać szczegółowe informacje o aktualnych wartościach w twoim programie obsługi.

1

Musisz uzyskać odniesienie do ChartPanel, rredraw go i dopiero wtedy możesz uzyskać prawidłowe współrzędne X, Y z Plotu. Aby to zrobić, musisz umieścić współrzędne w kolejce awt i nie wywoływać go bezpośrednio. Poniżej znajduje się przykład, który zadziałał dla mnie (tylko dla współrzędnych 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); 
      } 
     }); 
    } 
} 
Powiązane problemy