2012-09-27 14 views
5

Voglio impostare i punti nella mia app con un clic del mouse. Io uso JFreeChart e uso nel listener del mouse ChartPanel. Questo è simile a questa:Trasforma le coordinate del listener del mouse in coordinate del grafico

panel.addChartMouseListener(new ThisMouseListener()); 

e il mio mouse ascoltatore ThisMouseListener() (non è finita):

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 

    } 

} 

ma questo listener del mouse mi torna mie coordinate del pannello e voglio ottenere le coordinate da il mio grafico. Potrebbe essere necessario utilizzare l'ascoltatore con un altro oggetto? o posso trasformare le coordinate con qualche metodo?

+0

Vuoi _add_ nuovi punti o _seleziona quelli esistenti? Modifica la tua domanda per includere [sscce] (http://sscce.org/) che mostra il tuo approccio attuale. – trashgod

risposta

3

È stato aggiunto l'ascoltatore al pannello. Pertanto quando fai clic con il mouse ricevi le coordinate relative al pannello - che è la fonte dell'evento. Devi invece aggiungere questo listener al grafico.

Un'altra possibilità è ottenere le coordinate del grafico rispetto al riquadro e sottrarle da xe 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 

Se il pannello è il contenitore del componente grafico, la soluzione potrebbe essere simile a quella precedente. Nota che queste coordinate saranno coordinate rispetto all'angolo in alto a sinistra del grafico.

+1

Non sarebbe un po 'fragile? Sembra che tu debba lavorare all'interno del renderer per ottenere una geometria affidabile. – trashgod

+0

cosa intendi per fragile? Pensi che potrebbe crollare ad un certo punto? Con il renderer intendi la funzione chartMouseClicked() nel listener (penso che tu intenda questo-http: //docs.oracle.com/javaee/5/api/javax/faces/render/Renderer.html)? Ho omesso la dichiarazione di x e y non perché suggerisco di includerla all'interno della funzione cliccata del mouse, ma di notare la fonte di quelle variabili. – user1581900

+0

Intendevo fragile nel senso che le coordinate relative al grafico possono cambiare, mentre il renderer può usare l'asse per convertire tra coordinate dello schermo e del modello. – trashgod

2

Prendi il x, y coordinate nel tuo spazio grafico tramite

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

Un grave problema: Trovo che JFreeChart non aggiorna questi valori fino dopo è chiamato mio gestore ChartMouseEvent; ogni volta attraverso ottengo i valori precedenti. Puoi dare un'occhiata a XYPlot.handleClick (x, y, info) per i dettagli per ottenere i valori correnti nel tuo gestore.

1

È necessario ottenere un riferimento al ChartPanel, rredraw e solo dopo è possibile ottenere le coordinate X, Y corrette dal grafico. Per fare ciò, è necessario posizionare il recupero delle coordinate sulla coda awt e non chiamarlo direttamente. Di seguito è riportato un esempio che ha funzionato per me (solo per coordinate 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); 
      } 
     }); 
    } 
}